使用TestNG框架測試用例執行順序問題


 

既然是討論執行順序問題,那么用例肯定是批量執行的,批量執行的方法有mvn test、直接運行testng.xml文件,其中直接運行testng.xml文件的效果與pom文件中配置執行testng.xml效果是一樣,所以本次只討論mvn test 批量運行方式

一、用例准備

1、 測試用例

編寫一些測試用例,單純為了測試,內容只進行輸入,沒有任何邏輯。 

public class FirstTest {

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


2、pom文件配置

   要使用mvn test方式批量運行用例,需要在pom文件中配置一下內容

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


二、執行順序梳理

1、mvn test 默認順序

如果pom文件只是進行了上步驟的配置,那么執行mvn test,用例是多線程無序執行的,如果要按順序執行要配置為單線程,在<plugin>標簽內增加如下配置

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

再次執行mvn test,我們會發現用例是單線程,按一定順序執行的。但是是按照字母a-z的順序執行的,其實這個排序對我們來說用處不大,我們寫用例要求的是看名知意,不可能按照這個順序來寫。

2、priority 注解

 testng提供了豐富的注解功能,priority標示用例執行的優先級,默認值為0,值越大優先級越低。比如:

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

該注解對同一個類的多個方法也是適用的,比如:

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優先級執行的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM