TestNG 和 Cucumber:传入单个特征文件名作为参数
TestNG & Cucumber: Pass in single feature file name as parameter
我想要一个 testNG/Cucumber 运行ner 和一个 testng @Test 允许我将单个特征文件的名称作为 testng 参数传递(使用 @Parameter ) 和 运行 它。我想要一个 运行时间解决方案。
我有一堆使用 TestNG 框架编写的非 Cucumber 测试,我也希望在其中包含 Cucumber 代码。
有没有人想出一些聪明的办法?
弄清楚如何将包含功能文件名的自定义 cucumberoptions 发送给 运行ner class。这将允许黄瓜和非黄瓜测试从 testng.xml.
运行
以下文字基于 "Cucumber for Java" 书中的详细信息...
Cucumber 检查是否为@CucumberOptions 注释提供了任何选项覆盖。从上到下依次检查,查到则停止:
- OS环境变量CUCUMBER_OPTIONS
- Java系统属性cucumber.options
- Java 资源包 cucumber.properties 带有 cucumber.options 属性
覆盖中找到的值将替换除插件参数之外的所有值集。将附加插件参数。未被覆盖的参数不会受到影响。
testng.xml
<suite name="Default suite">
<test name="Cucumber Mix">
<classes>
<class name="cucumtestng.test.RunAbstractSampleTest"></class>
<class name="cucumtestng.test.NormalTest"></class>
</classes>
</test>
</suite>
@CucumberOptions(features="",glue="cucumtestng.test.stepdefs",snippets=SnippetType.CAMELCASE,
plugin={"pretty", "html:report", "json:reports.json"})
public class RunAbstractSampleTest extends AbstractTestNGCucumberTests {
}
public class NormalTest {
@Test
public void f() {
System.out.println("NORMAL TESTNG CLASS");
}
}
您还可以使用 testng cucumber classes,它不扩展 AbstractTestNgCucumberTests 但使用组合...
设置 运行 作为 eclipse 中的配置,如下所示 运行...
这段 "setup" 代码可以解决问题。它为我提供了我感兴趣的黄瓜功能 运行。我也会看看其他提案。
@Parameters({"featurename"})
@BeforeTest(alwaysRun = true)
public void setUpTest(String featureName) throws Exception {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
List<CucumberFeature> featureList = testNGCucumberRunner.getFeatures();
for (CucumberFeature feature : featureList){
if (featureName.equalsIgnoreCase(feature.getPath())){
runFeature = feature;
break;
}
}
}
另一种技术是在实例化运行器之前使用反射实时修改 CucumberOptions 注释(感谢几篇旧帖子的启发):
@Parameters({"featurePath"})
@BeforeTest(alwaysRun = true)
public void setUpTest(@Optional("src/main/java/cucumberFeatureFiles/Testcase.feature") String featurePath) throws Exception {
Class<?> testClass = this.getClass();
changeCucumberAnnotation(testClass, "features", new String [] {featurePath});
testNGCucumberRunner = new WaltersTestngCucumberRunner(testClass);
}
private static void changeCucumberAnnotation(Class<?> clazz, String key, Object newValue) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Annotation options = clazz.getAnnotation(CucumberOptions.class); //get the CucumberOptions annotation
InvocationHandler proxyHandler = Proxy.getInvocationHandler(options); //setup handler so we can update Annotation using reflection. Basically creates a proxy for the Cucumber Options class
Field f = proxyHandler.getClass().getDeclaredField("memberValues"); //the annotaton key/values are stored in the memberValues field
f.setAccessible(true); //suppress any access issues when looking at f
Map<String, Object> memberValues = (Map<String, Object>) f.get(proxyHandler); //get the key-value map for the proxy
memberValues.remove(key); //renove the key entry...don't worry, we'll add it back
memberValues.put(key,newValue); //add the new key-value pair. The annotation is now updated.
}//end method
我想要一个 testNG/Cucumber 运行ner 和一个 testng @Test 允许我将单个特征文件的名称作为 testng 参数传递(使用 @Parameter ) 和 运行 它。我想要一个 运行时间解决方案。
我有一堆使用 TestNG 框架编写的非 Cucumber 测试,我也希望在其中包含 Cucumber 代码。
有没有人想出一些聪明的办法?
弄清楚如何将包含功能文件名的自定义 cucumberoptions 发送给 运行ner class。这将允许黄瓜和非黄瓜测试从 testng.xml.
运行以下文字基于 "Cucumber for Java" 书中的详细信息...
Cucumber 检查是否为@CucumberOptions 注释提供了任何选项覆盖。从上到下依次检查,查到则停止:
- OS环境变量CUCUMBER_OPTIONS
- Java系统属性cucumber.options
- Java 资源包 cucumber.properties 带有 cucumber.options 属性
覆盖中找到的值将替换除插件参数之外的所有值集。将附加插件参数。未被覆盖的参数不会受到影响。
testng.xml
<suite name="Default suite">
<test name="Cucumber Mix">
<classes>
<class name="cucumtestng.test.RunAbstractSampleTest"></class>
<class name="cucumtestng.test.NormalTest"></class>
</classes>
</test>
</suite>
@CucumberOptions(features="",glue="cucumtestng.test.stepdefs",snippets=SnippetType.CAMELCASE,
plugin={"pretty", "html:report", "json:reports.json"})
public class RunAbstractSampleTest extends AbstractTestNGCucumberTests {
}
public class NormalTest {
@Test
public void f() {
System.out.println("NORMAL TESTNG CLASS");
}
}
您还可以使用 testng cucumber classes,它不扩展 AbstractTestNgCucumberTests 但使用组合...
设置 运行 作为 eclipse 中的配置,如下所示 运行...
这段 "setup" 代码可以解决问题。它为我提供了我感兴趣的黄瓜功能 运行。我也会看看其他提案。
@Parameters({"featurename"})
@BeforeTest(alwaysRun = true)
public void setUpTest(String featureName) throws Exception {
testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
List<CucumberFeature> featureList = testNGCucumberRunner.getFeatures();
for (CucumberFeature feature : featureList){
if (featureName.equalsIgnoreCase(feature.getPath())){
runFeature = feature;
break;
}
}
}
另一种技术是在实例化运行器之前使用反射实时修改 CucumberOptions 注释(感谢几篇旧帖子的启发):
@Parameters({"featurePath"})
@BeforeTest(alwaysRun = true)
public void setUpTest(@Optional("src/main/java/cucumberFeatureFiles/Testcase.feature") String featurePath) throws Exception {
Class<?> testClass = this.getClass();
changeCucumberAnnotation(testClass, "features", new String [] {featurePath});
testNGCucumberRunner = new WaltersTestngCucumberRunner(testClass);
}
private static void changeCucumberAnnotation(Class<?> clazz, String key, Object newValue) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
Annotation options = clazz.getAnnotation(CucumberOptions.class); //get the CucumberOptions annotation
InvocationHandler proxyHandler = Proxy.getInvocationHandler(options); //setup handler so we can update Annotation using reflection. Basically creates a proxy for the Cucumber Options class
Field f = proxyHandler.getClass().getDeclaredField("memberValues"); //the annotaton key/values are stored in the memberValues field
f.setAccessible(true); //suppress any access issues when looking at f
Map<String, Object> memberValues = (Map<String, Object>) f.get(proxyHandler); //get the key-value map for the proxy
memberValues.remove(key); //renove the key entry...don't worry, we'll add it back
memberValues.put(key,newValue); //add the new key-value pair. The annotation is now updated.
}//end method