TestNG

TestNG是一个Java语言的测试框架,也是QA最常用的测试框架之一

TestNG官网文档地址:TestNG 文档 — TestNG Documentation

有时间再依据这个重新学下https://lwmzz.blog.csdn.net/article/details/129173343有代码实践

  • 简介

    • TestNG 是一个测试框架,从单元测试(与其他类隔离的情况下测试一个类)到集成测试(测试由多个类、多个包甚至多个外部框架(如应用服务器)组成的整个系统)

    • 编写测试通常是一个三步过程:

      • 编写您测试的业务逻辑,并在您的代码中插入TestNG注解。
      • 到 testng.xml 文件中或在build.xml中添加有关您的测试信息(例如,类名、您希望运行的组等)
      • 运行TestNG

      可以在欢迎页面找到一个快速示例

    • 文档中主要概念:

      • 套件由一个XML文件表示。可以包含一个或多个测试,并由<suite>标记定义
      • 测试用例由<test>表示,可以包含一个或多个TestNG
      • TestNG类是一个包含至少一个TestNG注解的Java类。它由<class>标记表示,可以包含一个或多个测试方法
      • 测试方法是代码中的@Test注解的Java方法
      • 可以通过@BeforeXXX@AfterXXX注解进行配置,这些注解允许在某个特定点之前和之后执行一些 Java 逻辑,这些点可以是上述列表中的任何一项
    • 其余部分将解释以下内容:

      • 所有注解的列表以及简要说明。这将让您了解TestNG提供的各种功能,但可能需要查阅专用于每个注解的部分以了解详细信息。
      • testng.xml文件的说明,语法以及您可以在其中指定的内容。
      • 各种功能的详细列表以及如何结合注解和testng.xml使用它们
  • 注解

    • 以下TestNG中可用注解及其属性的快速概述

    • 注解:BeforeXXX & AfterXXX

      TestNG类的配置信息:

      • @BeforeSuite:在此套件中的所有测试运行之前,将运行带注解的方法。
      • @AfterSuite:在此套件中的所有测试运行后,将运行带注解的方法。
      • @BeforeTest:在运行属于<test>标记内的类的任何测试方法之前,将运行带注解的方法。
      • @AfterTest:在运行属于<test>标记内的类的所有测试方法之后,将运行带注解的方法。
      • @BeforeGroups:此配置方法之前将运行的组列表。保证在调用属于任何这些组的第一个测试方法之前不久运行此方法。
      • @AfterGroups:此配置方法将在之后运行的组列表。保证在调用属于任何这些组的最后一个测试方法后不久运行此方法。
      • @BeforeClass:在调用当前类中的第一个测试方法之前,将运行带注解的方法。
      • @AfterClass:在运行当前类中的所有测试方法之后,将运行带注解的方法。
      • @BeforeMethod:带注解的方法将在每个测试方法之前运行。
      • @AfterMethod:带注解的方法将在每个测试方法之后运行
    • TestNG类的超类中的注解行为

      • 超类是指被继承的类

      • 超类中的注解行为会被继承到子类中。

      • 执行顺序:

        • @Before 类注解 : 从超类到子类
        • @After 类注解:从子类到超类。

      当放置在TestNG类的超类上时,上述注解也将被兑现(继承)。例如,这对于在公共超类中集中多个测试类的测试设置非常有用

      import org.testng.annotations.BeforeClass;
      import org.testng.annotations.BeforeMethod;
      import org.testng.annotations.AfterClass;
      import org.testng.annotations.AfterMethod;
      
      public class BaseTest {
          @BeforeClass
          public void beforeClass() {
              System.out.println("BaseTest: BeforeClass");
          }
      
          @AfterClass
          public void afterClass() {
              System.out.println("BaseTest: AfterClass");
          }
      
          @BeforeMethod
          public void beforeMethod() {
              System.out.println("BaseTest: BeforeMethod");
          }
      
          @AfterMethod
          public void afterMethod() {
              System.out.println("BaseTest: AfterMethod");
          }
      }
      
      import org.testng.annotations.Test;
      
      public class SubTest extends BaseTest {
          @BeforeClass
          public void subBeforeClass() {
              System.out.println("SubTest: BeforeClass");
          }
      
          @AfterClass
          public void subAfterClass() {
              System.out.println("SubTest: AfterClass");
          }
      
          @Test
          public void testMethod() {
              System.out.println("SubTest: TestMethod");
          }
      }
      
      BaseTest: BeforeClass
      SubTest: BeforeClass
      BaseTest: BeforeMethod
      SubTest: TestMethod
      BaseTest: AfterMethod
      SubTest: AfterClass
      BaseTest: AfterClass
      
    • Before和After注解的参数

      • alwaysRun 对于before方法(beforeSuitebeforeTestbeforeTestClassbeforeTestMethod,但不是beforeGroups):如果设置为true,则无论它属于哪个组,都将运行此配置方法。 对于after方法(afterSuiteafterClass,…):如果设置为true,即使先前调用的一个或多个方法失败或被跳过,也将运行此配置方法。
      • dependsOnGroups 此方法所依赖的组列表。
      • dependsOnMethods 此方法所依赖的方法列表。
      • 启用 是否启用此类/方法上的方法。
      • 组 此类/方法所属的组列表。
      • inheritGroups 如果为true,则此方法将属于类级别的@Test注解中指定的组。
      • onlyForGroups 仅适用于@BeforeMethod和@AfterMethod。如果指定,则仅当相应的测试方法属于列出的组之一时,才会调用此setup / teardown方法。
    • @DataProvider

      将方法标记为测试方法提供数据。带注解的方法必须返回一个Object[][],其中每个Object[]都可以分配测试方法的参数列表。想要从此DataProvider接收数据的@Test方法需要使用dataProvider名称等于此注解的名称。

    • @DataProvider的参数

      • name 此数据提供者的名称。如果未提供,则此data provider的名称将自动设置为其方法的名称。
      • parallel 如果设置为true,则使用此数据提供程序生成的测试将并行运行。默认值为false。
    • @Factory

      将方法标记为工厂,返回将由TestNG用作Test类的对象。该方法必须返回Object[]

    • @Listeners

      在测试类上定义侦听器。

      参数:value 扩展org.testng.ITestNGListener的类数组

    • @Parameters

      描述如何将参数传递给@Test方法。

      参数:value 用于填充此方法参数的变量列表

    • @Test

      将类或方法标记为测试的一部分。

    • @Test的参数

      • alwaysRun 如果设置为true,则即使依赖于失败的方法,也始终会运行此测试方法。
      • dataProvider 此测试方法的数据提供程序的名称。
      • dataProviderClass 查找数据提供程序的类。如果未指定,则将在当前测试方法的类或其基类之一上查找数据提供程序。如果指定了此属性,则数据提供程序方法必须在指定的类上是静态的。
      • dependsOnGroups 此方法所依赖的组列表。
      • dependsOnMethods 此方法所依赖的方法列表。
      • description 此方法的描述。
      • enabled 是否启用此类/方法上的方法。
      • expectedExceptions 预期测试方法抛出的异常列表。如果抛出此列表中没有异常或不同异常,则此测试将标记为失败。
      • groups 此类/方法所属的组列表。
      • invocationCount 应该调用此方法的次数。
      • invocationTimeOut 此测试应对所有调用计数的累计时间应采用的最大毫秒数。如果未指定invocationCount,则将忽略此属性。
      • priority 此测试方法的优先级。将优先安排较低的优先事项。
      • successPercentage 此方法预期的成功百分比
      • singleThreaded 如果设置为true,则此测试类上的所有方法都保证在同一个线程中运行,即使当前正在使用parallel = "methods"运行测试。此属性只能在类级别使用,如果在方法级别使用,它将被忽略。注意:此属性曾被称为sequential(现已弃用)。
      • timeOut 此测试应采用的最大毫秒数。
      • threadPoolSize 此方法的线程池大小。该方法将从invocationCount指定的多个线程调用。注意:如果未指定invocationCount,则忽略此属性
  • TestNG.xml

    • 可以通过几种不同的方式调用TestNG:

      • 使用testng.xml文件
      • ant
      • 从命令行
    • 本节介绍testng.xml的格式

      • 一个示例testng.xml文件:

        <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
        
        <suite name="Suite1" verbose="1" >
          <test name="Nopackage" >
            <classes>
               <class name="NoPackageTest" />
            </classes>
          </test>
        
          <test name="Regression1">
            <classes>
              <class name="test.sample.ParameterSample"/>
              <class name="test.sample.ParameterTest"/>
            </classes>
          </test>
        </suite>
        
      • 可以指定包名而不是类名:

        <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
        
        <suite name="Suite1" verbose="1" >
          <test name="Regression1">
            <packages>
              <package name="test.sample" />
           </packages>
         </test>
        </suite>
        

        在此示例中,TestNG将查看包test.sample中的所有类, 并仅保留具有TestNG注解的类

      • 还可以指定要包含和排除的组和方法:

        <test name="Regression1">
          <groups>
            <run>
              <exclude name="brokenTests"  />
              <include name="checkinTests"  />
            </run>
          </groups>
        
          <classes>
            <class name="test.IndividualMethodsTest">
              <methods>
                <include name="testMethod" />
              </methods>
            </class>
          </classes>
        </test>
        

        可以在testng.xml中定义新组,并在属性中指定其他详细信息,例如是否并行运行测试,使用多少线程,是否运行JUnit测试等等…

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

        <test name="Regression1" preserve-order="false">
          <classes>
        
            <class name="test.Test1">
              <methods>
                <include name="m1" />
                <include name="m2" />
              </methods>
            </class>
        
            <class name="test.Test2" />
        
          </classes>
        </test>
        
  • 运行TestNG 文档 — TestNG Documentation

  • Test methods, Test classes and Test groups

    • 测试方法

      • 测试方法用@Test注解。除非在testng.xml中将allow-return-values设置为true,否则将忽略使用@Test注解恰好返回值的方法:

        <suite allow-return-values="true"> 
        or
        <test allow-return-values="true">
        
    • 测试组

      • TestNG允许执行复杂的测试方法分组。可以声明方法属于组,还可以指定包含其他组的组。然后可以调用TestNG并要求包括一组特定的组(或正则表达式),同时排除另一组。这为您分区测试提供了最大的灵活性

        组在testng.xml文件中指定,可以在或标记下找到。标记中指定的组适用于下面的所有标记。请注意,组在这些标记中是累积的如果在<suite>中指定了组"a",在<test>中指定了组"b",则"a"和"b"都将被包含

        例如,至少有两类测试是很常见的

        • 准入测试。应在提交新代码之前运行这些测试。它们通常应该很快,并确保没有基本功能被破坏。
        • 功能测试。这些测试应涵盖您软件的所有功能,并且每天至少运行一次,尽管理想情况下您希望连续运行它们。

        通常,准入测试是功能测试的子集。TestNG允许您以非常直观的方式使用测试组指定。

      • 例如,您可以通过。您的整个测试类属于“functest”组来构建测试,另外还有一些方法属于“checkintest”组:

        public class Test1 {
          @Test(groups = { "functest", "checkintest" })
          public void testMethod1() {
          }
        
          @Test(groups = {"functest", "checkintest"} )
          public void testMethod2() {
          }
        
          @Test(groups = { "functest" })
          public void testMethod3() {
          }
        }
        

        用以下方式调用TestNG:

        <test name="Test1">
          <groups>
            <run>
              <include name="functest"/>
            </run>
          </groups>
          <classes>
            <class name="example1.Test1"/>
          </classes>
        </test>
        

        将运行该类中的所有测试方法,而使用checkintest调用它将只运行 testMethod1()和testMethod2()

      • 方法组

        <test name="Test1">
          <classes>
            <class name="example1.Test1">
              <methods>
                <include name=".*enabledTestMethod.*"/>
                <exclude name=".*brokenTestMethod.*"/>
              </methods>
             </class>
          </classes>
        </test>
        

        可以派上用来停用单个方法而不必重新编译任何东西,但是我不建议过多地使用这种技术,因为如果你开始重构你的Java代码(正则表达式中使用的正则表达式),它会使你的测试框架崩溃。标签可能不再符合您的方法)

    • 组群

      组还可以包括其他组。这些组称为“MetaGroups”。

      例如,您可能希望定义包含“checkintest”和“functest”的组“all”。“functest”本身将包含“windows”和“linux”组,而“checkintest将只包含”windows“。以下是如何在属性文件中定义它:

      <test name="Regression1">
        <groups>
          <define name="functest">
            <include name="windows"/>
            <include name="linux"/>
          </define>
      
          <define name="all">
            <include name="functest"/>
            <include name="checkintest"/>
          </define>
      
          <run>
            <include name="all"/>
          </run>
        </groups>
      
        <classes>
          <class name="test.sample.Test1"/>
        </classes>
      </test>
      
    • 排除组

      TestNG允许您包含组以及排除它们

      例如,在上面的例子中,我知道testMethod2()现在已经坏了所以我想禁用它:

      @Test(groups = {"checkintest", "broken"} )
      public void testMethod2() {
      }
      
      <test name="Simple example">
        <groups>
          <run>
            <include name="checkintest"/>
            <exclude name="broken"/>
          </run>
        </groups>
      
        <classes>
          <class name="example1.Test1"/>
        </classes>
      </test>
      
    • 部分组