【问题标题】:An Easier Way to Control Test Order in TestNG?在 TestNG 中控制测试顺序的更简单方法?
【发布时间】:2013-08-26 15:55:24
【问题描述】:

我看到了一些类似的问题,但没有一个可以直接回答我的问题...... 我正在使用带有 TestNg 和 Java 的 Selenium Webdriver 2.0,我正在寻找一种更好的方法来控制测试运行的顺序。 我真正想要的只是测试用例按照它们在类中编写的顺序运行。 它很直观。这很简单。它的可维护性。我真的很惊讶它不是 testNg 的默认设置。 (当编码器没有明确要求时,为什么要应用一些随机排序?)

无论如何,我知道我可以在我的 testng xml 中添加一个方法列表,但到目前为止我有 130 个测试(还有数百个!),这样的方法列表对于将来的维护来说太多了。 例如,当我添加十个测试方法时,我必须记住将所有这些方法添加到我的 xml 文件中。如果我错过添加一个会发生什么?我永远不会注意到它从未运行过......

所以这个解决方案将是一场维护噩梦:

<test name="BVTQA01">
 <classes>
  <class name="TestPackage.BVT">
   <methods>
    <include name="testLogin"></include>
    <include name="testAddToCart"></include>
    ...
    <include name="test999 etc"></include>
   </methods>
  </class>
 </classes>
</test>

我也尝试过保留顺序:

<test name="BVTQA01" preserve-order="true">
 <classes>
  <class name="TestPackage.TestBVT" />
 </classes>
</test>

但如果我不添加方法列表和“包含名称”列表的维护噩梦,它显然会被忽略......

所以目前我只是在 xml 文件中列出我的测试类(如上所述 - TestBVT,它有 20 个方法等),并使用测试本身的“取决于”注释来控制测试运行顺序。 然而,这并不理想,因为我正在创建对每个方法的依赖项。我想删除它们不是真正必要的依赖项。 我只想在存在真正依赖时使用“依赖”。

我还搜索了从我的 @Test 注释方法自动创建 xml。但是发布的解决方案并不清楚如何实际实施。

任何关于如何让 testNg 从上到下依次运行我的测试类的反馈,没有任何随机排序或维护繁重的列表生成,这将是美妙的。 提前致谢,

JR

【问题讨论】:

  • 我个人不明白你为什么想要这个。测试的本质是,在大多数情况下,您希望您的测试是不同的和独立的。您能否向我们提供更多信息,说明您的情况为何需要这样做,我们可以为您提供另一种方法吗?
  • 为什么要按顺序运行 tcs?维护?我认为维护更多的是与您的编码有关,然后是执行顺序..忘记顺序..并行运行
  • 是的,我期待这些问题。我读过的大多数帖子都在寻找一种方法来控制 testNg 中的排序得到这个响应。有时顺序很重要。例如,您需要创建用户并分配权限,并以管理员身份注销,以新用户身份登录并验证他们可以看到报告的场景。是的,这可能是一个测试用例。但实际上它应该更像是五个或十个较小的测试。此外,如果一个字段在用户创建中没有正确接受电话号码,您不希望它停止整个测试。排序很重要,特定的依赖项也很重要。
  • 正是我面临的问题!我在 TestNG 的 github 存储库上发布了一个问题作为功能。到现在都没有回应 :( TestNG 的不灵活正在变成一场噩梦。
  • 是的,完全同意。无法以最直观的方式运行测试来设计和维护(按编写顺序)只是 testNG 的一个明显缺陷。我们真的不应该用所有这些黑客来修补它,让它做它默认应该做的事情。这么聪明的开发者怎么会错过这么明显的要求。

标签: java selenium testng


【解决方案1】:

一种方法是以编程方式运行 TestNG。

package com.shn.test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

import org.testng.TestNG;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
import org.xml.sax.SAXException;

import com.shn.demos.RunDemo;

public class RunSuite{

    public static void main(String[] args)  {

        TestNG testNG = new TestNG();
        List<XmlSuite> suites = new ArrayList<XmlSuite>();

        //pass the name of Suite, Name of the groups to be executed & name of test
        suites.add(createSuite("SuiteDemo", "groupName1", "testName"));

        testNG.setSuiteThreadPoolSize(1);
        testNG.setXmlSuites(suites);

        testNG.run();
    }

    public static XmlSuite createSuite(String suiteName, String groupName, String testName) {
        XmlSuite suite = new XmlSuite();
        suite.setName(suiteName);
        suite.setParallel(XmlSuite.PARALLEL_NONE);

        LinkedHashMap<String, String> suiteParams = new LinkedHashMap<String, String>();
        //Put in the parameters out here which are required @ suite level
        suiteParams.put("SuiteKey1", "SuiteValue1");
        suiteParams.put("SuiteKey2", "SuiteValue2");
        suite.setParameters(suiteParams);

        XmlTest test = new XmlTest(suite);

        test.setName(testName);
        test.addIncludedGroup(groupName);
        //Put in the parametes out here wich are required @ test level
        test.addParameter("testKey1", "testValue1");
        test.addParameter("testKey2", "testValue2");

        List<XmlClass> clazzes = new ArrayList<XmlClass>();

        //This is your class under test
        XmlClass clazz = new XmlClass(Foo.class);
        clazzes.add(clazz);
        test.setClasses(clazzes);
        List<XmlTest> tests = new ArrayList<XmlTest>();
        tests.add(test);
        suite.setTests(tests);
        return suite;
    }
}

我只知道 setPreserveOrder() 还没有真正尝试过。 让我知道它是否适合你

【讨论】:

  • 我正在尝试。您为此使用了哪些内容?我有:导入 org.testng.TestNG;导入 org.testng.xml.XmlSuite;导入 org.testng.xml.XmlTest;导入 java.util.ArrayList;导入 java.util.List;
  • 哎呀按回车...无论如何我有上述包括,并得到'无法解析符号'.setName、.setParallel、.setPreserveOrder 等。
  • 用包含编辑了我的答案。重试并告诉我。
  • 你能解释一下这应该如何工作吗?如何将它与标准 testNG 功能一起使用?您可以在上面看到我如何使用 xml 文件来运行 testNG。我有几个类,可以轻松注释掉哪些类正在运行,或者轻松更改 xml 中的顺序。如何选择在此解决方案中运行的类?如何传递我的 xml 文件中的参数等。另外, foo 代表什么。它是红色的,所以我认为它需要分配给某些东西......请提供更多详细信息。
  • 我又玩了一些。我将您上面提供的代码与我的测试类放在同一个包中。在上面首先发布的这种情况下,我用类名“TestBVT”替换了“foo”,然后用 TestPackage.testSuite 替换了 TestPackage.TestBVT(在 xml 中)。并正常运行 XML。但是我的 IDE (IDEA) 只是说所有测试在实际运行之前都通过了。看起来我没有正确使用您的代码,或者您的代码中的列表没有正确添加指定类的测试方法。任何向前推进的建议都非常感谢。如果它有效,它很有希望。
【解决方案2】:

您可以通过实现和注册 IAnnotationTransformer 自动为每个测试方法生成优先级注解,它使用 javassist 读取方法行号并将其分配为 TestNG 测试优先级。

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import javassist.*

import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;

public class AssignTestPriorityTransformer implements IAnnotationTransformer
{
    static ClassPool s_ClassPool = ClassPool.getDefault(); 

    @Override
    public void transform(ITestAnnotation p_annotation, Class p_testClass, Constructor p_testConstructor, Method p_testMethod)
    {
        p_annotation.setPriority(getMethodLineNumber(p_testMethod));
    }
    private int getMethodLineNumber(Method p_testMethod)
    {
        try
        {
            CtClass cc = s_ClassPool.get(p_testMethod.getDeclaringClass().getCanonicalName());
            CtMethod methodX = cc.getDeclaredMethod(p_testMethod.getName());
            return methodX.getMethodInfo().getLineNumber(0);        
        }
        catch(Exception e)
        {
            throw new RuntimeException("Getting of line number of method "+p_testMethod+" failed", e);
        }
    }
}

并在您的 XML 文件中注册该侦听器

<suite name="Suite" parallel="false">
<listeners>
    <listener class-name="AssignTestPriorityTransformer" />
</listeners>
<test name="All tests">
    <classes>
        <class name="tests.YourTests"/>
    </classes>
</test>
</suite>

AssignTestPriorityTransformer 将确保由@Test 注解标记的方法将按照与在测试类的 java 源代码中定义的顺序相同的顺序进行处理。

【讨论】:

    【解决方案3】:

    您可以使用优先注释,它们不是 TestNG 的标准部分,但也是由框架的作者制作的。当然,现在您必须跟踪所有 130 个测试的优先级,而不是管理 1 个 xml 文件,但是您仍然可以使用优先级进行更精细的控制。此处描述了优先级注释:http://beust.com/weblog/2008/03/29/test-method-priorities-in-testng/

    【讨论】:

    • 不错的建议。不幸的是,对我来说,这将是同样的维护噩梦。如果我在一个班级有 50 个测试并且想在中间添加一个,我必须手动重新编号所有测试。我将考虑制作更多的测试课程,并一次将优先级添加到十个以上的集合中。它确实不理想,但如果没有提供其他解决方案来按照编写的顺序自动运行它们,则可能是一种解决方法。
    • 嗯,刚刚想到...我可以将它们编号为 10、20、30 等。这样,如果需要,我总是可以添加 11、12、13...也许这之后会起作用全部。
    • 使用优先级是维护测试方法顺序的最糟糕的方式!对于实际 UI 测试代码逻辑与 AUT 紧密耦合的 UI 自动化测试,大量时间用于维护核心测试代码本身,测试开发人员不必担心如何解决单元测试的此类问题他用于 UI 自动化的框架。
    • 这是我采用的解决方案,并且运行良好...据说依赖注释会破坏优先级注释,因此您必须非常小心地使用其中一个。混合它们可能会产生意想不到的结果。这仍然是最好的答案-谢谢。
    猜你喜欢
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多