TestNG中测试的执行顺序

Posted

技术标签:

【中文标题】TestNG中测试的执行顺序【英文标题】:Order of execution of tests in TestNG 【发布时间】:2011-02-09 19:20:45 【问题描述】:

如何自定义?

例如:

public class Test1 
  @Test
  public void test1() 
      System.out.println("test1");
  

  @Test
  public void test2() 
      System.out.println("test2");
  

  @Test
  public void test3() 
      System.out.println("test3");
  

在上述套件中,测试的执行顺序是任意的。对于一次执行,输出可能是:

test1
test3
test2

如何按照编写顺序执行测试?

【问题讨论】:

【参考方案1】:

一个带有重要解释的答案:

TestNG”的两个参数应该决定测试的执行顺序:

@Test(dependsOnGroups= "someGroup")

还有:

@Test(dependsOnMethods= "someMethod")

在这两种情况下,这些功能都取决于方法或组,

但区别:

在这种情况下:

@Test(dependsOnGroups= "someGroup")

该方法将依赖于整个组,因此不一定在依赖函数执行后立即执行该方法,但它可能会在运行后期甚至在其他测试运行之后发生。

重要的是要注意,在此参数的同一组测试中有多个使用的情况下,这是解决问题的安全方法,因为整个测试集的依赖方法将首先运行,然后只有依赖于它们的方法。

但是,在这种情况下:

@Test(dependsOnMethods= "someMethod")

即使在同一组测试中多次使用该参数,在依赖方法立即执行后,依赖方法仍然会被执行。

希望它清楚并有所帮助。

【讨论】:

【参考方案2】:

使用:preserve-order="true" 启用="true" 这将以您编写的方式运行测试用例。

<suite name="Sanity" verbose="1" parallel="" thread-count="">   
<test name="Automation" preserve-order="true"  enabled="true">
        <listeners>
            <listener class-name="com.yourtest.testNgListner.RetryListener" />
        </listeners>
        <parameter name="BrowserName" value="chrome" />
        <classes>
            <class name="com.yourtest.Suites.InitilizeClass" />
            <class name="com.yourtest.Suites.SurveyTestCases" />
            <methods>
                <include name="valid_Login" />
                <include name="verifyManageSurveyPage" />
                <include name="verifySurveyDesignerPage" />
                <include name="cloneAndDeleteSurvey" />
                <include name="createAndDelete_Responses" />
                <include name="previewSurvey" />
                <include name="verifySurveyLink" />
                <include name="verifySurveyResponses" />
                <include name="verifySurveyReports" />
            </methods>
        </classes>
    </test>
</suite>

【讨论】:

【参考方案3】:

使用这个:

public class TestNG

        @BeforeTest
        public void setUp() 
        
                   /*--Initialize broowsers--*/

        

        @Test(priority=0)
        public void Login() 
        

        

        @Test(priority=2)
        public void Logout() 
        

        

        @AfterTest
        public void tearDown() 
        
                //--Close driver--//

        


通常TestNG会提供一些注解,我们可以使用@BeforeSuite, @BeforeTest, @BeforeClass来初始化浏览器/设置。

如果您在脚本中编写了多个测试用例并希望按照分配的优先级执行,我们可以分配优先级,然后使用: @Test(priority=0)从0,1,2,3....开始

同时我们可以对多个测试用例进行分组,并通过分组来执行。 为此,我们将使用@Test(Groups='Regression')

最后像关闭浏览器我们可以使用@AfterTest, @AfterSuite, @AfterClass注解。

【讨论】:

【参考方案4】:

如果您碰巧使用了dependsOnMethods 之类的其他内容,您可能需要在您的testng.xml 文件中定义整个@Test 流程。 AFAIK,您的套件 XML 文件 (testng.xml) 中定义的顺序将覆盖所有其他排序策略。

【讨论】:

【参考方案5】:

这会奏效。

@Test(priority=1)
public void Test1() 



@Test(priority=2)
public void Test2() 



@Test(priority=3)
public void Test3() 


priority 鼓励执行顺序但不保证之前的优先级已经完成。 test3 可以在 test2 完成之前开始。如果需要保证,则声明一个依赖项。

与声明依赖项的解决方案不同,使用priority 的测试即使一项测试失败也会执行。根据documentation,可以使用@Test(...alwaysRun = true...) 解决这个依赖问题。

【讨论】:

【参考方案6】:

我遇到了同样的问题,可能的原因是由于 testng 的并行执行,解决方案是在 testng.xml 中添加 Priority 选项或简单地更新 preserve-order="true"。

<test name="Firefox Test" preserve-order="true">

【讨论】:

preserve-order="true",是 testng.xml 中的默认值,它仅适用于您在 testng.xml 中定义的顺序,因此解决您的问题只需将优先级添加到 @Tests 【参考方案7】:

如果您不想在 TestNG 中使用 @Test(priority = ) 选项,您可以使用 javaassist 库和 TestNG 的 IMethodInterceptor 根据定义的测试方法的顺序对测试进行优先级排序测试类。这是基于here 提供的解决方案。

将此监听器添加到您的测试类中:

package cs.jacob.listeners;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;

public class PriorityInterceptor implements IMethodInterceptor 
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) 

    Comparator<IMethodInstance> comparator = new Comparator<IMethodInstance>() 
        private int getLineNo(IMethodInstance mi) 
        int result = 0;

        String methodName = mi.getMethod().getConstructorOrMethod().getMethod().getName();
        String className  = mi.getMethod().getConstructorOrMethod().getDeclaringClass().getCanonicalName();
        ClassPool pool    = ClassPool.getDefault();

        try 
            CtClass cc        = pool.get(className);
            CtMethod ctMethod = cc.getDeclaredMethod(methodName);
            result            = ctMethod.getMethodInfo().getLineNumber(0);
         catch (NotFoundException e) 
            e.printStackTrace();
        

        return result;
        

        public int compare(IMethodInstance m1, IMethodInstance m2) 
        return getLineNo(m1) - getLineNo(m2);
        
    ;

    IMethodInstance[] array = methods.toArray(new IMethodInstance[methods.size()]);
    Arrays.sort(array, comparator);
    return Arrays.asList(array);
    

这基本上是找出方法的行号,并按行号的升序对它们进行排序,即它们在类中定义的顺序。

【讨论】:

如果您必须从 junit 迁移数百个测试,这是真正的解决方案 这解决了在代码中没有使用依赖标志的情况下的保留顺序问题。【参考方案8】:

在 TestNG 中,您使用dependOnMethods 和/或dependOnGroups:

@Test(groups = "a")
public void f1() 

@Test(groups = "a")
public void f2() 

@Test(dependsOnGroups = "a")
public void g() 

在这种情况下,g() 只会在 f1() 和 f2() 完成并成功后运行。

您会在文档中找到很多示例:http://testng.org/doc/documentation-main.html#test-groups

【讨论】:

但是,Cedric 的解决方案在使用 TestNG Eclipse 插件版本时存在一些缺陷。 5.9.0.4 在每次运行 TestCase 之前都会显示此插件不支持组的消息。 dependsOnGroups 非常有用,但在我看来,当两者结合在一起时,TestNG 会忽略 priority【参考方案9】:

类文件中方法的顺序是不可预测的,因此您需要使用依赖项或在 XML 中显式包含您的方法。

默认情况下,TestNG 将按照它们在 XML 文件中的顺序运行您的测试。如果您希望此文件中列出的类和方法以不可预测的顺序运行,请将 preserve-order 属性设置为 false

【讨论】:

【参考方案10】:

通过在 testNg.xml 中指定要执行的测试方法,我们可以按所需的顺序执行测试用例

<suite>
<test name="selenium1">
 		<classes>
			<class name="com.test.SeleniumTest" >
			    <methods><include name="methodB"></include>
			        <include name="methodA"></include>
			    </methods>    
			 </class>
		</classes>
 
	</test>
</suite>

【讨论】:

【参考方案11】:

小猪放弃了 user1927494 的回答, 如果你想在所有其他人之前运行一个测试,你可以这样做:

@Test()
public void testOrderDoesntMatter_1() 


@Test(priority=-1)
public void testToRunFirst() 


@Test()
public void testOrderDoesntMatter_2() 

【讨论】:

【参考方案12】:

有多种方法可以按照给定的顺序执行测试。但通常情况下,测试必须是可重复的和独立的,以保证它只测试所需的功能,并且不依赖于被测试代码之外的代码的副作用。

因此,要回答您的问题,您需要提供更多信息,例如为什么按特定顺序运行测试很重要。

【讨论】:

在很多情况下依赖项很有用,尤其是对于集成和功能测试。例如,测试一个网站:你想先测试登录页面,然后是下一页等等......一直从头开始清除和重新创建状态是不切实际的,并且会导致测试非常慢。此外,依赖项为您提供了更好的诊断,例如“1 个测试失败,99 个测试被跳过”,而不是传统的“100 个测试失败”,这无助于意识到所有这些失败实际上是因为一个测试失败。【参考方案13】:

为了解决有问题的特定场景:

@Test
public void Test1() 



@Test (dependsOnMethods="Test1")
public void Test2() 



@Test (dependsOnMethods="Test2")
public void Test3() 


【讨论】:

【参考方案14】:
@Test(dependsOnMethods="someBloodyMethod")

【讨论】:

我可能会指出这不是一个特别有用的答案 - 我建议更详细地扩展您的答案!【参考方案15】:

通过使用@Test 的优先级参数,我们可以控制测试执行的顺序。

【讨论】:

很遗憾不在 TestNG 中。 @MariuszJamro 我不明白为什么? Priority参数2012年还没有?【参考方案16】:

如果我正确理解您的问题,即您希望按指定顺序运行测试,则可以使用 TestNG IMethodInterceptor。查看http://beust.com/weblog2/archives/000479.html 了解如何利用它们。

如果您想运行一些预初始化,请查看 IHookable http://testng.org/javadoc/org/testng/IHookable.html 和相关线程 http://groups.google.com/group/testng-users/browse_thread/thread/42596505990e8484/3923db2f127a9a9c?lnk=gst&q=IHookable#3923db2f127a9a9c

【讨论】:

【参考方案17】:

像单元测试一样的测试?做什么的?测试必须是独立的,否则......你不能单独运行测试。如果他们是独立的,为什么还要干涉?另外 - 如果您在多个内核上的多个线程中运行它们,那么“顺序”是什么?

【讨论】:

实际上完全可以混合依赖和并行,看看这篇文章了解TestNG是如何做到的:beust.com/weblog/2009/11/28/hard-core-multicore-with-testng 除了单元测试之外,人们还使用 JUnit 做很多事情。几乎所有这些额外的用途都有你需要按特定顺序做事的时候。这是开发 TestNG 的主要理由之一,顺便说一句。

以上是关于TestNG中测试的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

TestNG 执行顺序 - 它混合了来自不同类的测试

TestNG执行测试用例的顺序

TestNG基础教程 - TestNG.xml中的测试级别和常用注解执行顺序

TestNG学习-002-annotaton 注解概述及其执行顺序

TestNG+Factory,自定义方法的执行顺序

TestNG