首页 > 解决方案 > 使用 maven-surefire 从 javaagent 访问测试类

问题描述

我正在尝试运行一个分析,在运行 selenium 测试时捕获定位器的值。有大量的项目和版本要测试,我想避免直接修改项目文件,因此,我求助于使用 javaagent(使用 ByteBuddy)。这个想法是对测试类进行检测,这样他们就会得到我需要的信息。因此,在我正在分析的项目的 pom.xml 中,我必须按如下方式设置surefire-plugin

          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M1</version>
            <configuration>
                <argLine>@{argLine} -javaagent:\path\to\my\agent.jar</argLine>
                <forkCount>0</forkCount>
            </configuration>
          </plugin>

argLine 字段允许我将代理附加到surefire 进程,而forkCount 强制surefire 只使用一个JVM,这应该允许我查看所有加载的类(我认为)。

至于代理,我有如下的 premain 方法

public static void premain(final String agentArgs,
                           final Instrumentation inst) {
    System.out.println("Starting to collect metrics");

    new AgentBuilder.Default()
            .with(new AgentBuilder.InitializationStrategy.SelfInjection.Eager())
            .type(ElementMatchers.any())
            .transform(new LocatorReporterTransformer())
            .with(AgentBuilder.TypeStrategy.Default.REDEFINE)
            .installOn(inst);
}

我使用 ElementMatchers.any() 确保能够看到我的代理拦截的所有类。在 LocatorReporterTransormer 类中,我有方法 transform(...) 如下

@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder,
                                        TypeDescription typeDescription,
                                        ClassLoader classLoader,
                                        JavaModule javaModule) {

    System.out.println(typeDescription.getName());
    return builder;
}

我的目标是从我的测试中捕获一些类,但似乎它们从未加载到 JVM 中,这对我来说很奇怪。因此,我的问题是:如何安全地将 javaagent 添加到 surefire 并确保它可以访问所有类?javaagent 有没有办法从目标捕获所有子进程?

标签: instrumentationmaven-surefire-pluginbyte-buddyjavaagents

解决方案


这些类并非全部可见,因为正在执行多个进程。似乎forkCount = 0 d 没有成功。一种解决方案是使用 MAVEN_OPTS 将代理实际附加到 maven 进程上,然后使用fockMode = never。这是在我的情况下有效的实现:

set "MAVEN_OPTS=-javaagent:\path\to\agent.jar"
mvn test -DforkMode=never

推荐阅读