surefire如何决定测试框架?
How Does surefire decide on the Test framework?
我一直在尝试了解 Surefire 插件如何在内部决定使用哪个测试框架(TestNG、Jupiter、Junit4 等)
它是否使用反射并尝试在类路径中查找每个框架的存在?
(查看依赖项,Surefire 似乎在其传递依赖项中附带了 junit4 - junit:JUnit:jar:4.12)
可以显式传递提供程序(test-framework 类型),设置额外的插件依赖项,例如对于 TestNG:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
</plugin>
如果没有指定
Surefire normally automatically selects which test-framework provider to use based on the version of TestNG/JUnit present in your project's classpath.
来自此文档:
https://maven.apache.org/surefire/maven-surefire-plugin/examples/providers.html
Surefire 插件如何在内部决定使用哪个测试框架
让我们看看它是如何实现的。
有 ProviderInfo
方法接口 boolean isApplicable()
;
我在 class AbstractSurefireMojo.java
中找到了多个实现
用于:
- TestNgProviderInfo
- JUnit3ProviderInfo
- JUnit4ProviderInfo
- JUnitPlatformProviderInfo
- JUnitCoreProviderInfo
- DynamicProviderInfo
还有一个受保护的方法 protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
引用了所有这些实现。
protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
throws MojoExecutionException
{
Artifact junitDepArtifact = getJunitDepArtifact();
return providerDetector.resolve( new DynamicProviderInfo( null ),
new JUnitPlatformProviderInfo( getJUnit5Artifact(), testClasspath ),
new TestNgProviderInfo( getTestNgArtifact() ),
new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit3ProviderInfo() );
}
和 ProviderDetector
class 在 resolve
方法中为每个 providerInfo 调用 isApplicable()
。
看起来第一个适用的已被选中:
private Optional<ProviderInfo> autoDetectOneWellKnownProvider( ProviderInfo... wellKnownProviders )
{
Optional<ProviderInfo> providerInfo = stream( wellKnownProviders )
.filter( ProviderInfo::isApplicable )
.findFirst();
providerInfo.ifPresent( p -> logger.info( "Using auto detected provider " + p.getProviderName() ) );
return providerInfo;
}
我一直在尝试了解 Surefire 插件如何在内部决定使用哪个测试框架(TestNG、Jupiter、Junit4 等)
它是否使用反射并尝试在类路径中查找每个框架的存在?
(查看依赖项,Surefire 似乎在其传递依赖项中附带了 junit4 - junit:JUnit:jar:4.12)
可以显式传递提供程序(test-framework 类型),设置额外的插件依赖项,例如对于 TestNG:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-testng</artifactId>
<version>3.0.0-M5</version>
</dependency>
</dependencies>
</plugin>
如果没有指定
Surefire normally automatically selects which test-framework provider to use based on the version of TestNG/JUnit present in your project's classpath.
来自此文档:
https://maven.apache.org/surefire/maven-surefire-plugin/examples/providers.html
Surefire 插件如何在内部决定使用哪个测试框架
让我们看看它是如何实现的。
有 ProviderInfo
方法接口 boolean isApplicable()
;
我在 class AbstractSurefireMojo.java
用于:
- TestNgProviderInfo
- JUnit3ProviderInfo
- JUnit4ProviderInfo
- JUnitPlatformProviderInfo
- JUnitCoreProviderInfo
- DynamicProviderInfo
还有一个受保护的方法 protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
引用了所有这些实现。
protected List<ProviderInfo> createProviders( TestClassPath testClasspath )
throws MojoExecutionException
{
Artifact junitDepArtifact = getJunitDepArtifact();
return providerDetector.resolve( new DynamicProviderInfo( null ),
new JUnitPlatformProviderInfo( getJUnit5Artifact(), testClasspath ),
new TestNgProviderInfo( getTestNgArtifact() ),
new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
new JUnit3ProviderInfo() );
}
和 ProviderDetector
class 在 resolve
方法中为每个 providerInfo 调用 isApplicable()
。
看起来第一个适用的已被选中:
private Optional<ProviderInfo> autoDetectOneWellKnownProvider( ProviderInfo... wellKnownProviders )
{
Optional<ProviderInfo> providerInfo = stream( wellKnownProviders )
.filter( ProviderInfo::isApplicable )
.findFirst();
providerInfo.ifPresent( p -> logger.info( "Using auto detected provider " + p.getProviderName() ) );
return providerInfo;
}