根据我的经验,TestNG是最灵活的测试Java框架。但是,它确实存在一些不一致之处。我遇到的主要问题是缺乏对侦听器和方法选择器中依赖注入的支持。在编写位于TestNG之上的可重用测试工具时,此功能至关重要。我只能提出两个解决方法的想法(第一个是黑客,第二个是痛苦),所以我想知道是否有人能想出更好的方法。
首先,hacky方式
创建表示单身的枚举
package com.example;
//other imports
public enum Injection {
INJECTION
private Injector guiceInjector;
public void setGuiceInjector(final Injector guiceInjector) {
this.guiceInjector = guiceInjector;
}
public void injectInto(final Object obj) {
Objects.requireNonNull(this.guiceInjector).injectMembers(obj);
}
}
按如下方式实施org.testng.IObjectFactory2
package com.example;
import static com.example.Injection.INJECTION;
//other imports
public final class GuiceBootstrap implements IObjectFactory2 {
private final Injector injector;
public GuiceBootstrap() {
this.injector = Guice.createInjector(/*modules*/);
INJECTION.setGuiceInjector(this.injector);
}
@Override
public Object newInstance(final Class<?> kind) {
return injector.getInstance(kind);
}
}
根据需要使用枚举injectInto
,例如:
package com.example;
import static com.example.Injection.INJECTION;
//other imports
public final class SimpleRetryAnalyzer implements IRetryAnalyzer {
@Inject @MaxRetryCount private int maxRetries;
private int retriesSoFar;
public SimpleRetryAnalyzer() {
INJECTION.injectInto(this);
retriesSoFar = 0;
}
public boolean retry(final ITestResult result) {
//implementation
}
}
我总体上鄙视可变状态,所以我并不认为这是一种有效的方法。此外,没有什么可以阻止利用这种方法的测试工具的用户直接访问枚举(即使它的意味着是内部的)。哈克,不洁,涉及可变状态......
第二,痛苦的方式
远离TestNG,并以编程方式使用它:
package com.example;
public CustomTestNgLauncher {
public static void main(String... args) {
final Injector injector = Guice.createInjector(determineGuiceModules(args));
final ITestObjectFactory guiceObjectFactory = createGuiceObjectFactory(injector);
final TestNG testNg = new TestNG();
testNg.setObjectFactory(guiceObjectFactory);
testNg.setOutputDirectory(reportsDirPathOrNull);
testNg.setTestSuites(determineTestNgSuites());
testNg.addListener(injector.getInstance(SomeCustomListener.class));
}
}
在我看来,这是对第一种方法的改进,但是注入方法选择器的问题仍然存在,因为TestNG#addMethodSelector接受String
而不是接受{{3}的实例} ...