欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(二)TestNG 基础概念和执行时机注解

程序员文章站 2024-01-29 23:46:16
...

入门的篇幅会写的比较长,毕竟基础要理解好。在学习TestNG注解前,我们先了解基本的名词,留个印象。

TestNG名词解释:

1.TestNG方法(method):是一个在代码内使用@Test注解标注的方法。下面代码中的isDuckMeal()就是一个测试方法。

  @Test
  public void  isDuckMeal() {
     //do sth
  }

2.TestNG 组(group):TestNG方法可以加上groups="groupid"的属性来为方法划分组,后续可以在xml文件中来决定运行哪些组。下面的isClean方法就属于groupxxx组。

	@Test(groups="groupxxx")
	public void isClean(){
		//do sth
	}

下面的配置在xml中排除了groupxxx组。运行的时候,将不会运行所有属于groupxxx组的方法。

<groups>
	<run>
		<!--排除全部属于groupxxx组的Test Method-->
		<exclude name="groupxxx"/>
	</run>
</groups>

3.TestNG类(class):是包含至少一个TesdNG注解的Java类。可以包含多个测试方法。在xml文件中由<class>标签定义了这个Test所涉及的class。

4.TestNG用例(test):是多个TestNG类的组合。在xml文件中由<test>标签定义。

5.TestNG套件(suite):定义了一组业务级粒度的测试动作,它由一个或多个TestNG用例(Test)组成,在xml文件中由<suite>标签定义。


除了@Test注解外,TestNG还提供了丰富的注解满足各种测试场景需求。我们这里先讲最常见的关于执行时机的注解。一下子塞太多也消化不了。

TestNG执行时机注解:在同一个TestNG默认会按照方法的首字母升序执行TestNG Method。

@BeforeSuite:被注解的方法在所属套件(suite)内会最先运行。
@AfterSuite:被注解的方法在所属套件(suite)内会在最后运行。
@BeforeTest:被注解的方法会在所属的类所属的Test用例下最先运行。
@AfterTest:被注解的方法会在这个方法所属的类所属的Test用例下最后运行。
@BeforeClass:被注解的方法会在这个方法所属的类运行时最先运行。
@AfterClass:被注解的方法会在这个方法所属的类运行时最后运行。
@BeforeGroups:被注解的方法会在这个方法所属的组(group,组只属于某个Test,Test之间的组互不干扰)被调用时最先运行。
@AfterGroups:被注解的方法会在这个方法所属的组(group,组只属于某个Test,Test之间的组互不干扰)被调用时最后运行。
@BeforeMethod:被注解的方法会在该方法所属类内每个测试方法运行前运行。
@AfterMethod:被注解的方法会在该方法所属类内每个测试方法运行后运行。

考试考阅读理解的原因来了,上面这些描述,这么绕是不是很容易就被绕晕了,先回顾下前面的名词解释,然后我们结合实际的例子来理解这些注解。我们先来一个简单的例子。先新建一个TestNG类和TestNG配置xml文件。

package com.testng;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class SimpleExample {
	@Test
	public void simpleTest1(){
		System.out.println("simpleTest1");
	}
	
	@Test
	public void simpleTest2(){
		System.out.println("simpleTest2");
	}
	
	@BeforeSuite
	public void beforeSuiteExample(){
		System.out.println("beforeSuite");
	}
	
	@BeforeTest
	public void beforeTestExample(){
		System.out.println("beforeTest");
	}
}

这个TestNG配置xml内加了注释,注明了部分注解的运行时机,可以看下留个印象

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!-- Before suite -->
<suite name="testSuite">
	<!-- Before test1 -->
	<test name="test1">
		<classes>
			<!-- Before class1 -->
			<class name ="com.testng.SimpleExample" />
			<!-- After class1 -->
		</classes>
	</test>
	<!-- After test1 -->
</suite>
<!-- After suite -->

然后在TestNG配置xml文件上,右键,run as -> TestNG Suite(单个类运行也可以不用xml配置,就像上一篇博文的helloworld例子那样,但是单个类测试的场景不是我们主要的学习目标)。运行后,最先会切到Result of Running suite标签可以看到本次运行的套件的结构。TestNG的执行顺序,就是顺着这个结构,穿插着各种before after自上而下的执行下来。

(二)TestNG 基础概念和执行时机注解

前面说了,@BeforeSuite注解会在这个套件内最先运行,@BeforeTest会在这个Test执行前,最先执行,然后是按方法名首字母字母升序执行类内的TestNG方法。我们看下控制台输出,确实如此。

(二)TestNG 基础概念和执行时机注解

接下来让我们搞包含全部注解的完整例子。新建两个TestNG类和TestNG xml配置。来观察多种注解多个类,跨类group组的执行顺序。

package com.testng;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestNGClass1 {	
	@BeforeSuite
	public void beforeSuite1(){
		System.out.println("beforeSuite1 会在所属Suite被调用前运行 我们同属于一个Suite会按xml的顺序执行");
	}
	@AfterSuite
	public void afterSuite1(){
		System.out.println("afterSuite1 会在所属Suite运行后运行 我们同属于一个Suite会按xml的顺序执行");
	}
	
	@BeforeTest
	public void BeforeTest1(){
		System.out.println("beforeTest1 会在当前所属的Test运行前运行 我们同属于一个Test会按xml的顺序执行");
	}
	
	@AfterTest
	public void afterTest1(){
		System.out.println("afterTest1 会在当前所属的Test运行后运行 我们同属于一个Test会按xml的顺序执行");
	}
	
	@BeforeClass
	public void beforeClass1(){
		System.out.println("beforeClass1 会在当前所属的class1运行前运行");
	}
	
	@AfterClass
	public void afterClass1(){
		System.out.println("afterClass1 会在当前所属的class1运行后运行");
	}
	/*这表示这注解的方法会在id为groupsxxx的组的所有方法运行前最先运行*/
	@BeforeGroups(groups="groupxxx")
	public void beforeGroupsXXX(){
		System.out.println("beforeGroupsXXX 会在这个Test内所属的Group被调用前运行");
	}
	/*这表示这个注解的方法会在id为groupxxx的组的所有方法运行完毕后运行*/
	@AfterGroups(groups="groupxxx")
	public void afterGroupsXXX(){
		System.out.println("afterGroupsXXX 会在这个Test内所属的Group运行后运行");
	}
	
	@BeforeMethod
	public void beforeMethod1(){
		System.out.println("beforeMethod1 会在当前类每个test method被调用前运行");
	}
	
	@AfterMethod
	public void afterMethod1(){
		System.out.println("afterMethod1 会在当前类每个test method运行后运行");
	}
	
	@Test(groups="groupxxx")
	public void test1001GroupXXX(){
		System.out.println("test1001-XXX Test Method");
	}
	
	@Test(groups="groupyyy")
	public void test1002GroupYYY(){
		System.out.println("test1002-YYY Test Method");
	}
}
package com.testng;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestNGClass2 {
	
	@BeforeSuite
	public void beforeSuite2(){
		System.out.println("beforeSuite2 会在所属Suite被调用前运行 我们同属于一个Suite会按xml的顺序执行");
	}
	@AfterSuite
	public void afterSuite2(){
		System.out.println("afterSuite2 会在所属Suite运行后运行 我们同属于一个Suite会按xml的顺序执行");
	}
	
	@BeforeTest
	public void BeforeTest2(){
		System.out.println("beforeTest2 会在当前所属的Test运行前运行 我们同属于一个Test会按xml的顺序执行");
	}
	
	@AfterTest
	public void afterTest2(){
		System.out.println("afterTest2 会在当前所属的Test运行后运行 我们同属于一个Test会按xml的顺序执行");
	}
	
	@BeforeClass
	public void beforeClass2(){
		System.out.println("beforeClass2 会在当前所属的class2运行前运行");
	}
	
	@AfterClass
	public void afterClass2(){
		System.out.println("afterClass2 会在当前所属的class2运行后运行");
	}
	
	@BeforeGroups(groups="groupyyy")
	public void beforeGroupsYYY(){
		System.out.println("beforeGroupsYYY 会在所属的Group被调用前运行");
	}
	
	@AfterGroups(groups="groupyyy")
	public void afterGroupsYYY(){
		System.out.println("afterGroupsYYY 会在所属的Group运行后运行");
	}
	
	@BeforeMethod
	public void beforeMethod2(){
		System.out.println("beforeMethod2 会在每个test method被调用前运行");
	}
	
	@AfterMethod
	public void afterMethod2(){
		System.out.println("afterMethod2 会在每个test method运行后运行");
	}
	
	
	@Test(groups="groupxxx")
	public void test2001GroupXXX(){
		System.out.println("test2001-XXX Test Method");
	}
	
	@Test(groups="groupyyy")
	public void test2002GroupYYY(){
		System.out.println("test2002-YYY Test Method");
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<!-- Before suite -->
<suite name="testSuite">
	<!-- Before test1 -->
	<test name="test1">
		<classes>
			<!-- Before class1 -->
			<class name ="com.testng.TestNGClass1" />
			<!-- After class1 -->
			
			<!-- Before class2 -->
			<class name ="com.testng.TestNGClass2" />
			<!-- After class2 -->
		</classes>
	</test>
	<!-- After test1 -->
</suite>
<!-- After suite -->

TestNG会按照xml配置中的顺序,从上往下的执行test用例。这个例子,执行的顺序说明都已在控制台打印。TestNG会按照xml配置中的顺序,从上往下的执行test用例。动手敲一敲,很快就能搞明白这里的调用顺序优先级。我们看下控制台的输出,重点把group的结果标了出来。

(二)TestNG 基础概念和执行时机注解

下面回顾下,配置xml文件的标签层次,编写TestNG xml文件时就按这个层次来。

|--suite
|--test
  |--groups
  |       |--run 
  |       |--exclide name="groupid"//排除组,支持正则表达式
          |--classes

      |--class name="classname"

到了这一步,你至少已经能看懂TestNG的注解,知道怎么编写简单的TestNG套件,TestNG也就算入门辣!后面我们再讲TestNG的其他注解的用法。

附上TestNG官网,你想查的都在这里:https://testng.org/doc/documentation-main.html#annotations