This is the 29th day of my participation in the August More Text Challenge

In the above

☕ Java Technical Guide “TestNG Topics” unit testing framework TestNG Use Tutorial guide (part 1), continue with our next article on TestNG technical features.

Grouping test

Group tests use groups, or tags if you’re using XML, or @test (groups=”group2″), as in the example in section 4. And @beforeGroup requires a group name to be properly mounted to the group.

@test (groups = {“mysql”,”database”}) @test (groups = {“mysql”,”database”}); Here’s an example:

A test file, newtest.class:

public class NewTest {
  @Test(groups="group1")
  public void test1(a) {
	  System.out.println("test1 from group1");
	  Assert.assertTrue(true);
  }

  @Test(groups="group1")
  public void test11(a) {
	  System.out.println("test11 from group1");
	  Assert.assertTrue(true);
  }
  
  @Test(groups="group2")
  public void test2(a) 
  {
	  System.out.println("test2 from group2");
	  Assert.assertTrue(true);
  }
  
  @BeforeTest
  public void beforeTest(a) 
  {
	  System.out.println("beforeTest");
  }
  
  @AfterTest
  public void afterTest(a) 
  {
	  System.out.println("afterTest");
  }
  
  @BeforeClass
  public void beforeClass(a) 
  {
	  System.out.println("beforeClass");
  }
  
  @AfterClass
  public void afterClass(a) 
  {
	  System.out.println("afterClass");
  }
  
  @BeforeSuite
  public void beforeSuite(a) 
  {
	  System.out.println("beforeSuite");
  }
  
  @AfterSuite
  public void afterSuite(a) 
  {
	  System.out.println("afterSuite");
  }
  
  @BeforeGroups(groups="group1")
  public void beforeGroups(a) 
  {
	  System.out.println("beforeGroups");
  }
  
  @AfterGroups(groups="group1")
  public void afterGroups(a) 
  {
	  System.out.println("afterGroups");
  }
  
  @BeforeMethod
  public void beforeMethod(a) 
  {
	  System.out.println("beforeMethod");
  }
  
  @AfterMethod
  public void afterMethod(a) 
  {
	  System.out.println("afterMethod"); }}Copy the code
Another TestCase1. Class:
@Test(groups= "group2")
public class TestCase1 {

    @Test(enabled=false)
    public void TestNgLearn1(a) {
        System.out.println("this is TestNG test case1");
    }
    @Test
    public void TestNgLearn2(a) {
        System.out.println("this is TestNG test case2"); }}Copy the code
XML is as follows:
<? xml version="1.0" encoding="UTF-8"? > <suite name="Suite" parallel="false">
  <test name="Test">
    <groups>
      <include name="group1"></incloud>
      <include name="group2"></incloud>
    </groups>
    <classes>
      <class name="com.demo.test.testng.NewTest"/>
      <class name="com.demo.test.testng.TestCase1"/> </classes> </test> <! -- Test --> </suite> <! -- Suite -->Copy the code
The running results are as follows:
beforeSuite beforeTest beforeClass beforeGroups beforeMethod test1 from group1 afterMethod beforeMethod test11 from group1 afterMethod afterGroups beforeMethod test2 from group2 afterMethod afterClass this is TestNG test case2 afterTest  afterSuiteCopy the code

As shown above, two use cases of group1 were run first, then two use cases of group2 were run; Note that in XML group identification, we need to add the groups to be run, and also add the classes that are identified by these groups.

Points test suite

  • A test suite is a collection of test cases that test the behavior or group of behaviors of a software program. In TestNG, we can’t define a suite in the test source code, but it can be represented by an XML file, because a suite is the function that executes. It also allows flexibility in configuring the tests to run.

  • Suites can contain one or more tests and are defined by tags. Is the root tag of testng.xml. It describes a test suite, which in turn consists of several parts.

The following table lists the accepted legal attributes of all definitions.

Relying on the test

You might want to call the methods in your test case in a particular order, or you might want to share some data and state between the methods. TestNG supports this dependency because it supports the declaration of explicit dependencies between test methods.

TestNG allows you to specify dependencies:
  • Use the attribute dependsOnMethods in the @test annotation
  • Use the attribute dependsOnGroups in the @test annotation

Dependencies include hard and soft dependencies:

  • Hard dependency: the default dependency mode, that is, all methods or groups of its dependencies must pass, otherwise the class or method identified as dependent will be skipped and marked as SKIP in the report, as shown in the following example, which is the default dependency mode.
  • Soft dependency: If not all of the dependent methods or groups have passes, the operation of the identified dependent classes or methods will not be affected. If this method is used, there must be no causal relationship between the dependent and the dependent, otherwise the use case will fail.
  • DependsOnMethods = {“TestNgLearn1”}, alwaysRun=true) dependsOnMethods= {“TestNgLearn1”}, alwaysRun=true)

In TestNG, we implement dependency tests using dependOnMethods and dependsOnGroups. And both of these support regular expressions, as shown in Example 3. Here are a few usage examples:

Example 1, the dependent method pass:
public class TestCase1 {
    @Test(enabled=true)
    public void TestNgLearn1(a) {
        System.out.println("this is TestNG test case1");
    }
    @Test(dependsOnMethods= {"TestNgLearn1"})
    public void TestNgLearn2(a) {
        System.out.println("this is TestNG test case2"); }}Copy the code
Running results:
this is TestNG test case1
this is TestNG test case2
PASSED: TestNgLearn1
PASSED: TestNgLearn2
Copy the code
Example 2, the dependent method fail:
public class TestCase1 {
    @Test(enabled=true)
    public void TestNgLearn1(a) {
        System.out.println("this is TestNG test case1");
        Assert.assertFalse(true);
    }
    @Test(dependsOnMethods= {"TestNgLearn1"})
    public void TestNgLearn2(a) {
        System.out.println("this is TestNG test case2"); }}Copy the code
Results:
this is TestNG test case1 FAILED: TestNgLearn1 junit.framework.AssertionFailedError at junit.framework.Assert.fail(Assert.java:47) at junit.framework.Assert.assertTrue(Assert.java:20) at junit.framework.Assert.assertFalse(Assert.java:34) at junit.framework.Assert.assertFalse(Assert.java:41) at com.demo.test.testng.TestCase1.TestNgLearn1(TestCase1.java:26) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104) at org.testng.internal.Invoker.invokeMethod(Invoker.java:645) at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851) at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112) at org.testng.TestRunner.privateRun(TestRunner.java:756) at org.testng.TestRunner.run(TestRunner.java:610) at org.testng.SuiteRunner.runTest(SuiteRunner.java:387) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340) at org.testng.SuiteRunner.run(SuiteRunner.java:289) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)  at org.testng.TestNG.runSuitesLocally(TestNG.java:1218) at org.testng.TestNG.runSuites(TestNG.java:1133) at org.testng.TestNG.run(TestNG.java:1104) at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114) at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251) at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77) SKIPPED: TestNgLearn2Copy the code
Group dependence

Method1 relies on all methods whose group name is init, as shown below:

@Test(groups = { "init" })
public void serverStartedOk(a) {}
 
@Test(groups = { "init" })
public void initEnvironment(a) {}
 
@Test(dependsOnGroups = { "init.*" })
public void method1(a) {}
Copy the code

The order in which the two methods in init group are executed is not guaranteed unless specified in the XML

Parametric test

Another interesting feature in TestNG is parameterized testing. In most cases, you will encounter scenarios where the business logic requires extensive testing. Parameterized testing allows developers to run the same tests again and again with different values.

TestNG can pass parameters directly to test methods in two different ways:

Using testng. XML
Using a data provider

The following describes the two parameter transmission modes:

  1. Textng.xml is used to pass parameters
The sample code is as follows:
public class TestCase1 {
    @Test(enabled=true)
    @Parameters({"param1", "param2"})
    public void TestNgLearn1(String param1, int param2) {
        System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
        Assert.assertFalse(false);
    }
    @Test(dependsOnMethods= {"TestNgLearn1"})
    public void TestNgLearn2(a) {
        System.out.println("this is TestNG test case2"); }}Copy the code
The XML configuration:

      
<suite name="Suite" parallel="false">
  <test name="Test">
    <parameter name="param1" value="1011111" />
    <parameter name="param2" value="10" />
    <classes>
      <class name="com.demo.test.testng.TestCase1"/>
    </classes>
  </test> <! -- Test -->
</suite> <! -- Suite -->
Copy the code
Running the XML results in the following:
this is TestNG test case1, and param1 is:1011111; param2 is:10
this is TestNG test case2

===============================================
Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Copy the code
Pass parameters using @dataProvider

Note that the parameter types must be the same, and the function with @dataProvider annotation must return Object[][]. Note here.

The code is as follows:
public class TestCase1 {
    @DataProvider(name = "provideNumbers")
    public Object[][] provideData() {
        return new Object[][] { { 10.20 }, { 100.110 }, { 200.210}}; }@Test(dataProvider = "provideNumbers")
    public void TestNgLearn1(int param1, int param2) {
        System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);
        Assert.assertFalse(false);
    }
    @Test(dependsOnMethods= {"TestNgLearn1"})
    public void TestNgLearn2(a) {
        System.out.println("this is TestNG test case2"); }}Copy the code
Running this class results in:
this is TestNG test case1, and param1 is:10; param2 is:20
this is TestNG test case1, and param1 is:100; param2 is:110
this is TestNG test case1, and param1 is:200; param2 is:210
this is TestNG test case2
PASSED: TestNgLearn1(10, 20)
PASSED: TestNgLearn1(100, 110)
PASSED: TestNgLearn1(200, 210)
PASSED: TestNgLearn2
Copy the code

XML configuration file description

Most of the above is based on the test script to run, a small part of the XML run, here in XML to explain:

<! DOCTYPEsuite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="SuiteName" verbose="1" > 
Copy the code
Each label is explained as follows:
Suite label

The testng. XML file contains the outermost tag suite, which can have more than one and. Several attributes can be added to the testng. XML file, as described in Section 10 of the suite test.

  1. The name attribute

This attribute is mandatory and can be set to its own value. The name will appear in the testNG report.

  1. Verbose attribute

This attribute specifies the level of detail in the testNG report, ranging from 0 to 10, where 10 is the most detailed. The default value of this attribute is 1 for the generated XML.

  1. The parallel attribute
  • This property refers to the running mode, which defaults to None, serial running; Parallel execution methods include the following:
    • Methods: Method level, if this value, all test methods under the suite will be multithreaded, i.e., multithreaded at the test case level. If there are dependencies between the use cases, the order of execution will run according to the specified dependencies;
    <suite name="My suite" parallel="methods" thread-count="5">
    Copy the code
    • Tests: TestNG will run all methods in the same tag in the same thread, each tag in a separate thread, allowing you to group all classes that are not thread-safe in the same thread and ensure that they all run in the same thread, while using TestNG to run tests on as many threads as possible.
    <suite name="My suite" parallel="tests" thread-count="5">
    Copy the code
    • Classes: class-level concurrency, i.e. TestNG will run each class under the suite in a separate thread, and all use cases under the same class will run in the same thread;
    <suite name="My suite" parallel="classes" thread-count="5">
    Copy the code
    • Instances: Instance level, where TestNG will run all methods in the same instance in the same thread, and two methods on two different instances will run in different threads.
    <suite name="My suite" parallel="instances" thread-count="5">
    Copy the code
  1. Thread – count property

This attribute is used to specify the number of threads. If required, parallel can be added only if the parallel parameter is not None.

  1. Annotations property

This is the annotation level, including methods level and class level.

  1. Time – out attributes

This property is used to specify the timeout for all use cases under the suite;

  1. The group – by – instances attributes

This is used for dependent methods that have multiple overloaded objects, because if it is a dependent method and the method has multiple overloaded methods, the default is to run all overloaded methods before running the dependent method, but sometimes we don’t want to do this, so we just set this to true.

  1. Preserve – order attribute

The value can be true or false. If it is true, use case execution will be in the order in XML, otherwise it will be out of order. If this attribute is not added, use case execution will be in order by default.

2. Test tag

This tag has no special meaning. It can include multiple tags, such as groups and classes, as follows:

Select all test scripts in a package (including subpackages)

<test name = "allTestsInAPackage" >
   <packages>
      <package name = "whole.path.to.package.* />  Copy the code

Select all test scripts in a class

<test name = "allTestsInAClass" >
   <classes>
  <class name="whole.path.to.package.className />  Copy the code

Select part of the test script in a class

<test name = "aFewTestsFromAClass" >
   <classes>
  <class name="whole.path.to.package.className > 
       
      firstMethod" /> secondMethod" /> thirdMethod" />    Copy the code

Select some groups in a package

<test name = "includedGroupsInAPackage" >
   <groups>
      <run>
         <include name = "includedGroup" />
      </run>
   </groups>
   <packages>
      <package name = "whole.path.to.package.* />  Copy the code

Exclude groups from a package

<test name = "excludedGroupsInAPackage" >
   <groups>
      <run>
         <exclude name = "excludedGroup" />
      </run>
   </groups>
   <packages>
      <package name = "whole.path.to.package.* />  Copy the code
The group TAB

This tag must be under the tag to identify which groups will be used for testing or excluded from testing. Its sibling must contain a tag or tag that specifies which packages or classes groups come from. Include a group and exclude a group:

<groups>
  <run>
     <include name = "includedGroupName" />
     <exclude name = "excludedGroupName" />
  </run>
</groups>
Copy the code

Advanced applications:

<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>
Copy the code

other

The other option is to select a test script, which can be done in three ways:

Select a package

<packages>
    <package name = "packageName" />
</packages>
Copy the code

Select a class

<classes>
    <class name = "className" />
</classes>
Copy the code

Choose a method

<classes>
    <class name = "className" />
       <methods>
          <include name = "methodName" />
       </methods>
    </class>
</classes>
Copy the code

Regular expressions are also supported, for example:

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