首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Selenium - TestNG -如何在并行使用中根据Maven命令行传递的参数跳过/禁用某些测试

Selenium - TestNG -如何在并行使用中根据Maven命令行传递的参数跳过/禁用某些测试
EN

Stack Overflow用户
提问于 2020-05-20 19:55:18
回答 1查看 472关注 0票数 0

我们有一个跨国网站。并不是所有的功能都是可用的。在所有国家/地区(语言)。我在堆栈Java - TestNG - TestNG监听器- Selenium WebDriver (页面对象模型)- Maven上构建了数百个测试。所有测试都是使用Maven和命令行从Jenkins运行的。使用命令行,我传递了所有必要的参数。测试组、baseURL、语言等

有些测试是并行运行的,有些测试是单线程的。出于这个原因,我将testng.xml设置如下:

代码语言:javascript
运行
复制
<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>

所有测试都在使用已排序的测试注释中的组。

代码语言:javascript
运行
复制
@Test(testName = "testName", priority = Priority.MEDIUM, groups = {TestGroup.SMOKE, TestGroup.SINGLETHREAD})
public void testName () {

}

我正在读取@BeforeSuite中的命令行参数,并将其放入ITestContext的属性中

代码语言:javascript
运行
复制
@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,或者使用IAnnotationTransformersetEnable(false)。我不知道如何将参数传递给transformer并将其用于条件。这里没有ITestContext,它看起来像是在@BeforeSuite之前调用的transformer,所以在我能够读取命令行属性之前。

对我来说部分起作用的是IMethodInterceptor。我已经创建了一个新的测试组SkipInLanguage,比如SkipInHUSkipInEN,...怎么说,这个测试方法应该被跳过

代码语言:javascript
运行
复制
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,不是exist),并且只有@BeforeClass工作正常(读取maven参数),但这是在已经调用IMethodInterceptor之后。

为国家/地区过滤测试的最佳想法是什么?

我可以说,90%的测试是全球性的,所以从我的角度来看,在每个国家都有一个测试组并通过一组我想运行的测试并不是一个好的方法。因为在一次测试中,我可能要有10个不同的组,并且对于每个新的国家/地区,我应该在每个测试中添加新的测试组。

感谢您的帮助或想法。

EN

回答 1

Stack Overflow用户

发布于 2020-05-21 04:21:49

您可以使用IAnnotationTransformer。例如,下面是我的测试类:

代码语言:javascript
运行
复制
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);
    }

}

这是我的testng.xml

代码语言:javascript
运行
复制
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
    <listeners>
        <listener class-name="click.webelement.testng.TestSkipTransformer"/>
    </listeners>
    <test name="SO-answer">
        <packages>
            <package name="click.webelement.testng" />
        </packages>
    </test>
</suite>

下面是我的注解转换器实现:

代码语言:javascript
运行
复制
public class TestSkipTransformer implements IAnnotationTransformer {

    @Override
    public void transform(ITestAnnotation annotation, Class testClass, Constructor testConstructor, Method testMethod) {
        String language = System.getProperty("lang", "EN");
        if ("EN".equals(language)
                && !Arrays.asList(annotation.getGroups()).contains("EN_TESTS")) {
            annotation.setEnabled(false);
        }
        if ("RU".equals(language)
                && !Arrays.asList(annotation.getGroups()).contains("RU_TESTS")) {
            annotation.setEnabled(false);
        }
    }
}

下面是我的surefire设置,其中我设置了参数(不是为了处理命令行参数)

代码语言:javascript
运行
复制
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M4</version>
    <configuration>
        <suiteXmlFiles>
            <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
        </suiteXmlFiles>
            <systemPropertyVariables>
                <lang>RU</lang>
            </systemPropertyVariables>
    </configuration>
</plugin>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61912489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档