TestNG
TestNG
优点
漂亮的HTML格式测试报告
支持并发测试
参数化测试更简单
支持输出日志
支持更多功能的注解
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version>
</dependency>
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Created by Administrator on 2017/7/17.
*/
public class FirstTestNGDemo {
public WebDriver driver;
String baseUrl="https://www.baidu.com/";
@Test
public void f(){
driver.get(baseUrl);
}
@BeforeMethod
public void beforeMethod(){
System.setProperty("webdriver.firefox.bin", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
driver = new FirefoxDriver();
}
@AfterMethod
public void afterMethod(){
driver.quit();
}
}
test-output
1、点击工具条中Run,选择Edit Configurations,弹出运行配置对话框;
2、在左侧选择要设置运行的test,在左侧选择Configuration的Listeners项,
3、将Listeners中的use Default reporters前的选择框打上对号,
4、重新运行test,就会生产test-output文件了。
常用注解
1、TestNG的常见测试用例组织结构
*Test Suite由一个或者多个Test组成
*Test由一个或者多个测试Class组成
*一个测试Class由一个或者多个测试方法组成
2testing.xml:文件夹:res->右键file->testing.xml->右键run
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="test12">
<classes>
<class name="FirstTestNGDemo" />
</classes>
</test>
说明: suite定义一个测试套件,可以设置是否使用多线程,可包含多个测试用例或者测试group
parallel = classes 每个测试用例class级别多线程
thread-count =3 线程数为5,可同时执行3个case
preserve-order = true classes和methods按照配置中的顺序执行,false为乱序执行。(If you want the classes and methods listed in this file to be run in an unpredictible order, set the preserve-order attribute to false)
parameter 标签传递参数
3以下详细XML规则
-结-构-树
suite
--tests
----parameters
----groups
------definitions
------runs
----classes
--parameters
比较详细的结构如下:
<test name="xxxx">
<!-- 参数定义的方法 --> <parameter name="first-name" value="Cedric"/> <!-- groups的用法,前提是需要存在classes的组,否则所有方法不被运行 --> <groups> <!-- 定义组中组的方法 --> <define name="groups_name"> <include name="group1"/> <include name="group2"/> </define> <run> <!-- 此处用组名来区别 --> <inclue name="groups_name" /> <exclue name="groups_name" /> </run> </groups> <!-- classes的用法,classes中包含类名,类名底下可以包含方法名或排除方法名 --> <classes> <class name="class1"> <methods> <!-- 此处用方法名来区别 --> <inclue name="method_name" /> <exclue name="method_name" /> </methods> </class> </classes> </test>
4常用注释
注解 | 描述 |
---|---|
@BeforeSuite | 注解的方法将只运行一次,运行所有测试前此套件中。 |
@AfterSuite | 注解的方法将只运行一次此套件中的所有测试都运行之后。 |
@BeforeClass | 注解的方法将只运行一次先行先试在当前类中的方法调用。 |
@AfterClass | 注解的方法将只运行一次后已经运行在当前类中的所有测试方法。 |
@BeforeTest | 注解的方法将被运行之前的任何测试方法属于内部类的 <test>标签的运行。 |
@AfterTest | 注解的方法将被运行后,所有的测试方法,属于内部类的<test>标签的运行。 |
@BeforeGroups | 组的列表,这种配置方法将之前运行。此方法是保证在运行属于任何这些组第一个测试方法,该方法被调用。 |
@AfterGroups | 组的名单,这种配置方法后,将运行。此方法是保证运行后不久,最后的测试方法,该方法属于任何这些组被调用。 |
@BeforeMethod | 注解的方法将每个测试方法之前运行。 |
@AfterMethod | 被注释的方法将被运行后,每个测试方法。 |
@DataProvider |
标志着一个方法,提供数据的一个测试方法。注解的方法必须返回一个Object[] [],其中每个对象[]的测试方法的参数列表中可以分配。
该@Test 方法,希望从这个DataProvider的接收数据,需要使用一个dataProvider名称等于这个注解的名字。 |
@Factory | 作为一个工厂,返回TestNG的测试类的对象将被用于标记的方法。该方法必须返回Object[]。 |
@Listeners | 定义一个测试类的监听器。 |
@Parameters | 介绍如何将参数传递给@Test方法。 |
@Test | 标记一个类或方法作为测试的一部分。 |
alwaysRun | 对于每个bufore方法(beforeSuite, beforeTest, beforeTestClass 和 beforeTestMethod, 但是不包括 beforeGroups): 如果设置为true,被配置的方法将总是运行而不管它属于哪个组。 对于after方法(afterSuite, afterClass, ...): 如果设置为true,被配置的方法甚至在一个或多个先调用的方法失败或被忽略时也将运行。 |
dependsOnGroups | 这个方法依赖的组列表 |
dependsOnMethods | 这个方法依赖的方法列表 |
enabled | 这个类的方法是否激活 |
groups | 这个类或方法所属的分组列表 |
inheritGroups | 如果设置为true,这个方法被属于在类级别被@Test annotation指定的组 |
import org.testng.annotations.*;
/**
* Created by Administrator on 2017/7/18.
*/
public class Annotation {
@Test
public void testCase1(){
System.out.println("测试用例1被执行");
}
@Test
public void testCase2(){
System.out.println("测试用例2被执行");
}
@BeforeMethod
public void beforMethod(){
System.out.println("在每个测试方法开始运行前执行");
}
@AfterMethod
public void afterMethod(){
System.out.println("在每个测试方法开始运行结束后执行");
}
@BeforeClass
public void beforClass(){
System.out.println("当每个测试类的第一个方法开始调用前执行");
}
@AfterClass
public void afterClass(){
System.out.println("当每个测试类的最后一个方法结束运行后执行");
}
@BeforeTest
public void beforTest(){
System.out.println("测试类的test开始调用前执行");
}
@AfterTest
public void afterTest(){
System.out.println("测试类test结束运行后执行");
}
@BeforeSuite
public void beforSuite(){
System.out.println("测试集合suite开始调用前执行");
}
@AfterSuite
public void afterSuite(){
System.out.println("测试集合suite结束运行后执行");
}
}
groups
import org.testng.annotations.*;
/**
* Created by Administrator on 2017/7/19.
*/
public class Grouping {
@Test(groups = {"人"})
public void student(){
System.out.println("学生方法被调用");
}
@Test(groups = {"人"})
public void teacher(){
System.out.println("老师方法被调用");
}
@Test(groups = {"动物"})
public void cat(){
System.out.println("小猫方法被调用");
}
@Test(groups = {"动物"})
public void dog(){
System.out.println("小狗方法被调用");
}
@Test(groups = {"动物","人"})
public void feeder(){
System.out.println("饲养员方法被调用");
}
}
<suite name="Suite" parallel="classes" thread-count="3">
<test verbose="2" preserve-order="true" name="TestDebug">
<groups>
<run>
<include name="物动"/>
</run>
</groups>
全部调用
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="classes" thread-count="3">
<test verbose="2" preserve-order="true" name="TestDebug">
<groups>
<define name="All">
<include name="动物"/>
<include name="人"/>
</define>
<run>
<include name="All"/>
</run>
</groups>
<classes>
<class name="Grouping" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
依赖测试
import org.testng.annotations.Test;
/**
* Created by Administrator on 2017/7/19.
*/
public class DependentTest {
@Test(dependsOnMethods = {"OpenBrowser"})
public void SignIn(){
System.out.println("SignIn方法被调用");
}
@Test
public void OpenBrowser(){
System.out.println("OpenBrowser方法被调用");
}
@Test(dependsOnMethods = {"SignIn"})
public void LogOut(){
System.out.println("LogOut方法被调用");
}
}
特定顺序执行测试用例
public class SequenceTest {
@Test(priority = 2)
public void test3(){
System.out.println("test3方法被调用");
}@Test(priority = 3)
public void test4(){
System.out.println("test4方法被调用");
}@Test(priority = 0)
public void test(){
System.out.println("test1方法被调用");
}@Test(priority = 1)
public void test2(){
System.out.println("test2方法被调用");
}
}
跳过某个测试方法
@Test(priority = 1,enabled = false)
测试报告中的自定义日志
(1)、高层级:只记录测试脚本中的主要事件信息。
(2)、底层级:记录所有的测试步骤信息
import org.testng.Reporter;
import org.testng.annotations.Test;
/**
* Created by Administrator on 2017/7/19.
*/
public class DependentTest {
@Test(dependsOnMethods = {"OpenBrowser"})
public void SignIn(){
System.out.println("SignIn方法被调用");
Reporter.log("登陆");
}
@Test
public void OpenBrowser(){
System.out.println("OpenBrowser方法被调用");
Reporter.log("浏览器");
}
@Test(dependsOnMethods = {"SignIn"})
public void LogOut(){
System.out.println("LogOut方法被调用");
Reporter.log("注销");
}
}
index.html中的
结果skip:进行依赖测试时如果有前置的测试方法未执行成功,后续未执行的依赖测试方法
断言
(1) assertTrue:判断是否为True。
(2) assertFalse:判断是否为false。
(3) assertSame:判断引用地址是否相同。
(4) assertNotSame:判断引用地址是否不相同。
(5) assertNull:判断是否为null。
(6) assertNotNull:判断是否不为null。
(7) assertEquals:判断是否相等,Object类型的对象需要实现haseCode及equals方法。
(8) assertNotEquals:判断是否不相等。
(9) assertEqualsNoOrder:判断忽略顺序是否相等。
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Created by Administrator on 2017/7/19.
*/
public class AssertTest {
public WebDriver driver;
String Url="https://www.baidu.com/";
@Test
public void test1(){
driver.get(Url);
WebElement kw = driver.findElement(By.id("kw"));
Assert.assertTrue(kw.isDisplayed());
kw.sendKeys("sdfjskdjfkls");
driver.findElement(By.id("su")).click();
}
@BeforeMethod
public void beforeMethod(){
System.setProperty("webdriver.firefox.bin", "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe");
driver = new FirefoxDriver();
}
@AfterMethod
public void afterMethod(){
driver.quit();
}
}