With TestNG framework test case execution order issue

 

Since the problem is to discuss the implementation of the order, the method of execution batch use case certainly batch execution has mvn test, run directly testng.xml files, which run directly testng.xml file with the effect of pom file is configured to perform testng.xml effect Like, so this will only discuss mvn test batch operation mode

A, prepared by Example

1, the test case

Write some test cases, simply in order to test the content input only, without any logic. 

public class FirstTest {

   @Test
   public void testFirst(){
  
      System.err.println("first test");
   }
}


2, pom configuration file

   To run a batch mode using mvn test use cases, you need to configure the content in the pom file

       <build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.19.1</version>			
			</plugin>
		</plugins>
	</build>


Second, the order of execution carding

1, mvn test the default order

If the file is only performed pom configuration steps, is executed mvn test, use a multi-threaded embodiment of order execution, if you want to be executed sequentially configured as a single-threaded, the increase follows <plugin> tag

                               <configuration> 
					<forkCount> 1 </ forkCount>					 
					<reuseForks> false </ reuseForks> 
				</ configuration>

Execute mvn test again, we will find use cases are single-threaded, performed in a certain order. But the order is executed in accordance with the letters az, in fact, this sort of little use to us, we write the use case requirement is intended to see to know the name, it is impossible to write in that order.

2, priority notes

 testng provides a wealth of annotations, the priority, the default value is 0, the lower the value the greater use of the embodiment performs The priority mark. such as:

public class FirstTest {

   @Test(priority = 2)
   public void testFirst(){
      
      System.err.println("first test");
   }
}
public class SecondTest {

   @Test
   public void testFirst(){
      
      System.err.println("second test");
   }
}
public class ThirdTest {

   @Test(priority = 1)
   public void testFirst() {

      System.err.println("third test");
   }
}


执行结果:
second test
third test
first test

The annotation of multiple methods of the same class are also suitable, such as:

public class FirstTest {

   @Test(priority=2)
	public void testFirst2(){

		System.err.println("first test2");
	}

	@Test(priority=3)
	public void testFirst3(){

		System.err.println("first test3");
	}

	@Test(priority=1)
	public void testFirst(){

		System.err.println("first test");
	}
}

执行结果:
first test
first test2
first test3

那么我们就会想如果每个类中都有多个方法,且优先级是不同的,那么执行顺序又是怎么样的?比如:

public class FirstTest {

   @Test(priority=2)
	public void testFirst2(){

		System.err.println("first test2");
	}

	@Test
	public void testFirst3(){

		System.err.println("first test3");
	}

	@Test(priority=1)
	public void testFirst(){

		System.err.println("first test1");
	}
}
public class SecondTest {

	@Test
	public void testFirst(){

		System.err.println("second test");
	}
}


public class ThirdTest {

	@Test(priority = 1)
	public void testFirst() {

		System.err.println("third test");
	}

	@Test(priority = 2)
	public void testFirst2() {

		System.err.println("third test 2");
	}
}

运行结果:
first test3
second test
first test1
third test
first test2
third test 2

这种情况我们从结果可以看出并没有按照类的顺序执行,而是按照priority设置的等级高低,去执行的类。那么这个问题的原因是什么?有没有办法类按照顺序执行同时类中方法也按照顺序执行?这个问题我们放到后面讨论解决方法。

3、dependsOnGroups

public class FirstTest {
	@Test(dependsOnGroups={"second"})
	public void testFirst(){
	System.err.println("first test");
	}
}

public class SecondTest {

	@Test(groups="second",dependsOnGroups={"third"})
	public void testFirst(){

		System.err.println("second test");
	}	

public class ThirdTest {

	@Test(groups="third")
    public void testFirst() {

		System.err.println("third test");
	}	
}

执行结果:
third test
second test
first test

同样该方法适用于类的方法,比如:

public class FirstTest {

	@Test(dependsOnGroups={"first"},groups="second")
    public void testFirst2(){

		System.err.println("first test2");
	}

	@Test(groups="first")
	public void testFirst3(){

		System.err.println("first test3");
	}

	@Test(dependsOnGroups={"second"})
	public void testFirst(){

		System.err.println("first test1");
	}
}
执行结果:
first test3
first test2
first test1

4、dependsOnMethods

 该方法只适用于同一个类的不同方法间,不能跨类适用。举例如:

public class Third10Test {
   
   @Test(dependsOnMethods = { "testFirst3" })
   public void testFirst1() {

      System.err.println("third10 test1");
   }

   @Test
   public void testFirst2() {

      System.err.println("third10 test2");
   }
   @Test(dependsOnMethods = { "testFirst2" })
   public void testFirst3() {

      System.err.println("third10 test3");
   }
}


执行结果:
third10 test2
third10 test3
third10 test1

5、testng.xml

    pom文件中在maven-surefire-plugin插件增加配置如下:

<configuration>
   <suiteXmlFiles>
      <suiteXmlFile>testng.xml</suiteXmlFile>
   </suiteXmlFiles>
</configuration>

testng.xml作为testng的灵魂,提供了很强大的配置功能,其它使用方式可以自己百度。本问只讨论类型的执行顺序问题。tesng.xml配置如下:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
  
<suite name="Suite1"  >
  <test name="Nopackage">
    <classes>
       <class name="com.appiumforatk.SecondTest" />
       <class name="com.appiumforatk.FirstTest" />
       <class name="com.appiumforatk.ThirdTest" />
    </classes>   
  </test>
</suite>

执行mvn test 结果如下:

Second test

first test

third test

从结果可以看出,默认是按照顺序执行。其实在suite和test标签分别有preserve-order控制各自子标签的执行顺序,该值默认true。

如果我们把该值设置为false,可以看到用例不再按照配置的顺序执行了。如下:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
  
<suite name="Suite1"  >
  <test name="Nopackage" preserve-order="false">
    <classes >
       <class name="com.appiumforatk.SecondTest" />
       <class name="com.appiumforatk.FirstTest" />
       <class name="com.appiumforatk.ThirdTest" />
    </classes>   
  </test>
</suite>

执行mvn test命令,结果如下:

first test

Second test

third test

那么我们开始思考,如果testng.xml中设置了preserve-order= “true”,同时我们也设置了priority,那么执行顺序会怎么样?比如:我们只在SecondTest上加了priority=1,其它保持不变。

public class SecondTest {
   @Test
   public void testFirst(){

      System.err.println("Second test");
   }

   @Test(priority = 1)
   public void testFirst1(){
      
      System.err.println("Second test1");
   }
}
public class ThirdTest {

   @Test
   public void testFirst() {

      System.err.println("third test");
   }
   @Test(priority = 1)
   public void testFirst1() {

      System.err.println("third test1");
   }
}

mvn test执行结果如下:

Second test

first test

third test

Second test1

third test1

从结果可以看出同一priority优先级方法,按照配置的顺序执行。也即priority的优先级>preserve-order.那么我们回到2中的问题,原因是因为priority是在testng开始的时候全部加载进去,如果想实现按顺序执行完一个类的方法后,再执行另外一个类的方法,就要去改变方法的priority值,可以通过监听的方式实现。代码如下:

public class RePrioritizingListener implements IAnnotationTransformer {

   HashMap<Object, Integer> priorityMap = new HashMap<Object, Integer>();
   Integer class_priorityCounter = 10000;
   Integer max_testpriorityLength = 4;

   @Override
   public void transform(ITestAnnotation annotation, Class testClass,
         Constructor testConstructor, Method testMethod) {

      Class<?> declaringClass = testMethod.getDeclaringClass();
      Integer test_priority = annotation.getPriority();
      Integer current_ClassPriority = priorityMap.get(declaringClass);
      // 如果类没有设置过优先级,则进行设置。
      if (current_ClassPriority == null) {
         current_ClassPriority = class_priorityCounter++;
         priorityMap.put(declaringClass, current_ClassPriority);
      }

     //获取类中方法的优先级,如果小于四位数则左侧补充0以达到四位数
      String concatenatedPriority = test_priority.toString();
      while (concatenatedPriority.length() < max_testpriorityLength) {
         concatenatedPriority = "0" + concatenatedPriority;
      }


      //把类的优先级和方法的优先级合并
      concatenatedPriority = current_ClassPriority.toString()
            + concatenatedPriority;

      //重新设置方法的优先级
      annotation.setPriority(Integer.parseInt(concatenatedPriority));
   }
}

testng.xml配置如下:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
  
<suite name="Suite1" >
  <test name="Nopackage" preserve-order="true">
    <classes >
       <class name="com.appiumforatk.SecondTest" />
       <class name="com.appiumforatk.FirstTest" />
       <class name="com.appiumforatk.ThirdTest" />
    </classes>   
  </test>

    <listeners>    //配置监听
        <listener class-name="com.appiumforatk.RePrioritizingListener"/>
    </listeners>
</suite>

mvn test执行命令结果如下:

Second test

Second test1

first test

third test

third test1

这个时候我们看到按照配置的顺序执行class并且class中的方法也是按照priority优先级执行的。

 

Guess you like

Origin www.cnblogs.com/leohou/p/11694807.html