我们有一个跨国网站。并非所有功能都随处可用,即。在所有国家/地区(语言)。我在堆栈Java上建立了数百个测试-TestNG-TestNG侦听器-Selenium WebDriver(页面对象模型)-Maven。所有测试都使用Maven和命令行从Jenkins运行。我使用命令行传递所有必要的参数,即。测试组,baseURL,语言等。
某些测试并行运行,有些测试为单线程。因此,我将testng.xml
设置如下:
<suite name="Tests">
<listeners>
<listener class-name="listeners.TestListener"/>
<listener class-name="listeners.TestSuiteListener"/>
<listener class-name="listeners.SkipInCountryMethodInterceptorListener"/>
</listeners>
<test name="Parallel tests" parallel="methods" thread-count="8">
<groups>
<run>
<include name="Parallel" />
<exclude name="SingleThread" />
</run>
</groups>
<packages>
<package name="tests" />
</packages>
</test>
<test name="Single thread tests" parallel="false">
<groups>
<run>
<include name="SingleThread" />
<exclude name="Parallel" />
</run>
</groups>
<packages>
<package name="tests" />
</packages>
</test>
</suite>
所有测试都使用“测试注释”中的组进行了整理。
@Test(testName = "testName", priority = Priority.MEDIUM, groups = {TestGroup.SMOKE, TestGroup.SINGLETHREAD}) public void testName () { }
我正在读取
@BeforeSuite
中的命令行参数,并将其放入ITestContext
的属性中>@BeforeSuite() @Parameters({ "lang" }) public void beforeSuite(final ITestContext testContext, @Optional("en") String lang) { ... testContext.setAttribute("Language", lang); ... }
我尝试了许多方法来根据此参数对
lang
(国家)过滤器进行测试,例如@BeforeMethod(onlyForGroups = {TestGroup.SKIP_IN_EN})
和SkipException
或使用IAnnotationTransformer
和setEnable(false)
。我不知道如何将参数传递给transformer
并将其用于条件。没有ITestContext
,看起来像在transformer
之前调用了@BeforeSuite
,因此在我能够读取comandline属性之前。对我来说部分起作用的是
IMethodInterceptor
。我创建了一个新的测试组SkipIn [Language],例如SkipInHU
,SkipInEN
,……怎么说,应该跳过此测试方法
public class SkipInCountryMethodInterceptorListener implements IMethodInterceptor { @Override public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) { List<IMethodInstance> result = new ArrayList<IMethodInstance>(); for (IMethodInstance method : methods) { Test testMethod = method.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class); Set<String> groups = new HashSet<String>(); for (String group : testMethod.groups()) { groups.add(group); } String language = "en"; Set<String> attrs = context.getAttributeNames(); if (attrs.contains("Language")) { try { language = context.getAttribute("Language").toString(); } catch (Exception ignored) {} } if (groups.contains(TestGroup.SKIP_IN_EN) && language.equals("en")) { Log.info("TestMethod skipped."); } else { result.add(method); } } return result; }
但是此解决方案在并行测试中存在问题。我不知道为什么,也许是不同的线程,但是
@BeforeSuite
无法将属性放入ITestContext
。IMethodInterceptor
中的ITestContext的每次属性都是空的(属性语言为null
,不存在),只有@BeforeClass
可以正常工作(读取maven参数),但这是在IMethodInterceptor
已被调用之后。为国家/地区过滤测试的最佳方法是什么?
我可以说,90%的测试是全球性的,因此,从我的角度来看,为每个国家/地区设立一个测试小组并通过我要运行的一组测试并不是一个好办法。因为在一个测试中,我可能必须有10个不同的组,并且对于每个新的国家,我应该为每个测试添加一个新的测试组。
感谢您的帮助或想法。
我们有一个跨国网站。并非所有功能都随处可用,即。在所有国家/地区(语言)。我在堆栈Java上构建了数百个测试-TestNG-TestNG侦听器-Selenium ...
您可以使用IAnnotationTransformer
。例如,这是我的测试班级:
public class TestSkip {
@Test(testName = "ruTest", groups = {"RU_TESTS"})
public void ruTest(){
System.out.println("Running RU test");
Assert.assertTrue(true);
}
@Test(testName = "enTest", groups = {"EN_TESTS"})
public void enTest(){
System.out.printf("Running EN test");
Assert.assertTrue(true);
}
}