4

I have added opentelemetry javaagent to a project and used it to instrument the project. Is there a way to test the instrumentation(for example created spans) in the unit tests?

Lets say this is my whole project code:

public class Main {
    public static void main(String[] args) {
        System.out.println(hello());
    }

    @WithSpan("hello")
    private static String hello() {
        return "Hello world!";
    }
}

How can I test that calling the hello() function creates a hello span?

2 Answers 2

4

To write unit tests you can access the exported spans with AgentTestingExporterAccess. You need to import these packages:

<dependency>
    <groupId>io.opentelemetry.javaagent</groupId>
    <artifactId>opentelemetry-testing-common</artifactId>
    <version>1.23.0-alpha</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.opentelemetry.javaagent</groupId>
    <artifactId>opentelemetry-agent-for-testing</artifactId>
    <version>1.23.0-alpha</version>
    <scope>test</scope>
</dependency>

A simple unit test can look like this:

import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.javaagent.testing.common.AgentTestingExporterAccess;


import static io.opentelemetry.api.common.AttributeKey.stringKey;


import io.opentelemetry.sdk.trace.data.StatusData;


public class MainTest {
    @Test
    public void testHello() {
        AgentTestingExporterAccess.reset();
        Main.hello(); // This a function that creates a span
        var spans = AgentTestingExporterAccess.getExportedSpans();
        assertEquals(spans.get(0).getName(), "hello");
        assertEquals(spans.get(0).getKind(), SpanKind.INTERNAL);
        assertEquals(spans.get(0).getStatus(), StatusData.unset());
        assertEquals(spans.get(0).getAttributes().get(stringKey("service.name")), "search");
    }
}

Please note that to be able to use AgentTestingExporterAccess, you need to run your tests with the javaagent too. If the java agent is not attached when running the tests, you will get an exception from AgentTestingExporterAccess like this:

java.lang.AssertionError: Error accessing fields with reflection.
...
Caused by: java.lang.NullPointerException
...

Another way of doing this is to write a mock server and capture the spans. Opentelemetry has an example here

Sign up to request clarification or add additional context in comments.

2 Comments

That's a brilliant answer @samad-montazeri There is one thing I want to add to this:
If you want to add tests instrumentation in maven your could update maven-surefire-plugin with <argLine>-javaagent:${io.opentelemetry.javaagent:opentelemetry-agent-for-testing:jar</argLine> Also make sure to adjust maven-dependency-plugin as described here
1

Alternatively, you can also set up OTEL to log the traces somewhere useful, like a temp file. You can set it up via a system property or environment variable as described here: https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#logging-otlp-json-exporter

BTW I work at digma.ai and we are developing a free IntelliJ plugin that has a really cool feature for enabling/disabling OTEL for tests and analyzing the results. You can also use it to validate which traces are being recorded by test runs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.