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

如何自定义TestNG中测试的执行顺序?

例如:

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

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

【问题讨论】:

    标签: testing testng order-of-execution


    【解决方案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 的主要理由之一,顺便说一句。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2020-06-04
                        • 1970-01-01
                        • 2019-06-26
                        相关资源
                        最近更新 更多