英文:
Writing unit tests for a function instrumented with opentelemetry javaagent
问题
以下是翻译好的部分:
"我已经将opentelemetry的javaagent添加到一个项目中,并使用它来对项目进行仪器化。是否有一种方法可以在单元测试中测试仪器化(例如创建的span)?
假设这是我的整个项目代码:
public class Main {
public static void main(String[] args) {
System.out.println(hello());
}
@WithSpan("hello")
private static String hello() {
return "Hello world!";
}
}
如何测试调用hello()
函数是否创建了一个hello
span?"
英文:
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?
答案1
得分: 3
为了编写单元测试,您可以使用AgentTestingExporterAccess
来访问导出的跨度。您需要导入以下这些包:
<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>
一个简单的单元测试可以像这样:
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(); // 这是一个创建跨度的函数
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");
}
}
请注意,要能够使用AgentTestingExporterAccess
,您需要在运行测试时也使用java代理。如果在运行测试时未附加java代理,将会收到AgentTestingExporterAccess
引发的异常,类似于以下内容:
java.lang.AssertionError: Error accessing fields with reflection.
...
Caused by: java.lang.NullPointerException
...
另一种方法是编写一个模拟服务器来捕获跨度。Opentelemetry在这里有一个示例。
英文:
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
答案2
得分: 1
你可以选择将 OTEL 配置为将跟踪日志记录在有用的地方,比如临时文件。您可以按照这里描述的方式通过系统属性或环境变量进行设置:
https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#logging-otlp-json-exporter
顺便说一下,我在 digma.ai 工作,我们正在开发一个免费的 IntelliJ 插件,具有一个非常酷的功能,可以用于启用/禁用测试的 OTEL,并分析结果。您还可以使用它来验证测试运行中记录的跟踪。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论