5.6 TestNg的使用
Java语言编写的WebDriver测试程序通常使用单元测试框架运行。TestNG单元测试框架比JUnit单元测试框架更强大,它提供了更多的扩展功能。目前很大一部分自动化测试工程师已经开始转向使用TestNG单元测试框架来运行更复杂的自动化测试用例。
1.TestNG概述
TestNG是一种单元测试框架,由Cedric Beust创建,它借鉴了JUnit和NUnit框架的优秀设计思想,引入更易用和更强大的功能。TestNG是一种开源自动化测试框架,NG就是下一代的意思(Next Generation)。TestNG的使用和JUnit有些类似,但是它的设计实现比JUnit框架更好,提供了更灵活和更强大的功能。TestNG消除了一些老式框架的限制,让程序员通过注解、分组、序列和参数化等多种方式组织和执行自动化测试脚本。
TestNG具有以下优点:
(1)漂亮的HTML格式测试报告。
(2)支持并发测试。
(3)参数化测试更简单。
(4)支持输出日志。
(5)支持更多的功能的注解。
编写TestNG测试用例的步骤如下。
(1)使用Eclipse生成TestNG的测试程序框架。
(2)在生成的程序框架中编写测试代码逻辑。
(3)根据测试代码逻辑,插入TestNG注解标签。
(4)配置Testng.xml文件,设定测试类、测试方法、测试分组的执行信息。
(5)执行TestNG的测试程序。
2.安装TestNG
- Eclipse中点击Help->Install new software
- 点击Add,在name中输入testNg,在Location中输入http://beust.com/eclipse
- 选中Testng版本,点击Next,按照提示安装,安装的过程中会有一次警告,直接点是即可,安装完之后重启Eclipse
3.在TestNG中运行第一个WebDriver测试用例
(1)在项目中的src文件夹下,新建一个Package,在其中新建类FirstTestNGDemo。
(2)编写WebDriver的测试逻辑代码,具体测试代码如下:
package TestNG; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.annotations.Test; import org.testng.annotations.BeforeMethod; import org.testng.annotations.AfterMethod; public class FirstTestNGDemo { public WebDriver driver; String baseUrl="http://www.sogou.com/"; //设定访问网站的地址 @Test public void testSearch() { //打开sogou首页 driver.get(baseUrl+"/"); //在搜索框中输入“自动化测试” driver.findElement(By.id("query")).sendKeys("自动化测试"); //单击“搜索”按钮 driver.findElement(By.id("stb")).click(); } @BeforeMethod public void beforeMethod() { //若无法打开Firefox浏览器,可设定Firefox浏览器的安装路径 //System.setProperty("webdriver.firefox.bin", "C:\\Program Files(x86)\\Mozilla Firefox\\firefox.exe"); //打开Firefox浏览器 driver=new FirefoxDriver(); } @AfterMethod public void afterMethod() { //关闭打开的浏览器 driver.quit(); } }
(3)在Eclipse代码编辑区域,单击鼠标右键,在弹出的快捷菜单中选择“Debug As”->“TestNG Test”,开始执行TestNG测试用例。
(4)测试用例执行后,在Console标签栏中显示测试用例的执行结果。
(5)查看Results of running class FirstTestNGDemo标签栏,可以看到测试用例的图形化运行结果。
(6)TestNG也会输出HTML格式的测试报告,访问工程目录下的“test-output”目录,打开目录中的“emailable-report.html”文件。
(7)打开“test-output”目录中的index.html文件,此报告提供更加详细的测试用例执行信息。
4.TestNg常用注解
TestNG的常见测试用例组织结构如下:
- Test Suite由一个或者多个Test组成。
- Test由一个或者多个测试Class组成。
- 一个测试Class由一个或者多个测试方法组成。
在testing.xml中的配置层级结构如下。
<suite> <test> <classes> <method> </method> </classes> </test> </suite>
(1)@Test
表示该方法是一个测试方法。需要引用import org.testng.annotations.Test包。
代码示例如下。
(2)@BeforeMethod & @AfterMethod
@BeforeMethod表示该方法在每个测试方法运行之前,会自动的被调用运行,做初始化等操作。
@AfterMethod表示该方法在每一个测试方法运行之后会自动的被调用运行,做资源回收等操作。
代码示例如下。
(3)@BeforeClass / @AfterClass
这两个注脚的方法,就是在每个类运行之前与之后会自动的被调用。
比如,在自动化脚本运行时,一个类里面的所有测试方法设计的是在同一个浏览器里面运行,那么就是说在这个类对象产生之前,就要把浏览器给启动起来,这时候@BeforeClass可以启动浏览器,@AfterClass就可以关闭浏览器。
(4)@BeforeSuite / @AfterSuite / @BeforeTest / @AfterTest
BeforeSuite:表示此注解的方法会在当前测试集合(Suite)中的任一测试用例开始运行之前执行。
AfterSuite:表示此注解的方法会在当前测试集合(Suite)中的所有测试程序运行结束之后执行。
BeforeTest:表示此注解的方法会在Test中任一测试用例开始运行前执行。
AfterTest:表示此注解的方法会在Test中所有测试用例运行结束后执行。
BeforeGroups:表示此注解的方法会在分组测试用例的任一测试用例开始运行前执行。
AfterGroups:表示此注解的方法会在分组测试用例的所有测试用例运行结束后执行。
举例输入以下测试代码,理解上述注解的用法。
public class BeforeAfter { @Test public void testCase1(){ System.out.println("测试用例1被执行"); } @Test public void testCase2(){ System.out.println("测试用例2被执行"); } @BeforeMethod public void beforeMethod(){ System.out.println("在每个测试方法开始之前执行"); } @AfterMethod public void afterMethod(){ System.out.println("在每个测试方法运行结束后执行"); } @BeforeClass public void beforeClass(){ System.out.println("在当前测试类的第一个测试方法开始调用前执行"); } @AfterClass public void afterClass(){ System.out.println("当前测试类的最后一个测试方法结束运行后执行"); } @BeforeTest public void beforeTest(){ System.out.println("在测试类中的Test开始运行前执行"); } @AfterTest public void afterTest(){ System.out.println("在测试类中的Test运行结束后执行"); } @BeforeSuite public void beforeSuite(){ System.out.println("在当前测试集合(Suite)中的所有测试程序开始运行之前执行"); } @AfterSuite public void afterSuite(){ System.out.println("在当前测试集合(Suite)中的所有测试程序运行结束之后执行"); } }
测试结果如下。
在当前测试集合(Suite)中的所有测试程序开始运行之前执行
在测试类中的Test开始运行前执行
在当前测试类的第一个测试方法开始调用前执行
在每个测试方法开始之前执行
测试用例1被执行
在每个测试方法运行结束后执行
在每个测试方法开始之前执行
测试用例2被执行
在每个测试方法运行结束后执行
当前测试类的最后一个测试方法结束运行后执行
在测试类中的Test运行结束后执行
PASSED: testCase1
PASSED: testCase2
每个含有注解的类方法如果被调用,均会打印出其对应的注解含义,从执行的结果可以分辨出不同的注解方法会在何时被调用,从此实力可以更好地理解注解的执行含义。
5.断言类的使用
(1)测试中断言的作用
断言也就是检查点,重在判断我们通过页面得出来的值与期望值是否相等,如果相等,则代表断言成功,程序会继续往下执行,如果不相等,则代表断言失败,程序就会在断言失败处中止。
TestNG允许在测试执行过程中对测试程序变量的中间状态进行断言(Assert)判断,从而辅助判断测试用例的执行是成功还是失败。
(2)断言的API
- Assert.assertEquals:判断是否相等,Object类型的对象需要实现hashCode及equals方法
- Assert.assertNotEquals(actual1, actual2):判断是否不相等
- Assert.assertFalse(condition):判断是否为false
- Assert.assertTrue(condition):判断是否为true
- Assert.assertNull(object, message):判断是否为null
- Assert.assertNotNull(object):判断是否部位null
- Assert.assertSame(actual, expected):判断引用地址是否相同
- Assert.assertNotSame(actual, expected, message):判断引用地址是否不相同
- Assert.assertEqualsNoOrder:判断忽略顺序是否相等
练习一下:测试百度搜索功能中的正常搜索,打开百度网页,输入关键字“疯狂动物城”,点击搜索,在结果中打开含有疯狂动物城的第一个页面。
6.TestNg的数据驱动
(1)什么是数据驱动
数据驱动测试是自动化测试的主流设计模式之一。
相同的测试脚本使用不同的测试数据来执行,测试数据和测试行为进行了完全的分离,这样的测试脚本设计模式称为数据驱动。例如,测试网站的登录功能,自动化测试工程师想验证不同的用户名和密码在网站登录时的系统影响结果,就可以使用数据驱动模式来进行自动化测试。于是,testng为我们提供了这样一个注脚,让我们只需要提供出数据,就可以控制脚本运行的次数及相应的参数。
(2)TestNg数据驱动的实现
用注解@DataProvider实现,代码如下。
public class DataDrivernTest { @DataProvider public Object[][] loginData(){ return new Object[][]{{"user1","123"},{"user2","123"}}; } @DataProvider(name="logoutData") public Object[][] logoutinfo(){ return new Object[][]{{1},{2},{3}}; } @Test(dataProvider="loginData") public void test1(String name, String password) { System.out.println("Name:"+name+",Password:"+password); } @Test(dataProvider="logoutData") public void test2(int info) { System.out.println(info); } }
@DataProvider注脚的方法的返回值是Object对象的二维数组。
@DataProvider可以指定名称如@DataProvider(name="testData"),这样在测试方法中使用@Test(dataProvider='testData')。如果没有跟name="testData",则测试方法中的dataProvider的值就应该为@DataProvider注脚的方法名。
(3)使用TestNG和CSV文件进行数据驱动
(4)使用TestNG、Apache POI和Excel文件进行数据驱动测试
(5)使用MySQL数据库实现数据驱动测试
7.TestNg用XML运行
在自动化测试的执行过程中,通常会产生批量运行多个测试用例的需求,此需求称为运行测试集合(Test Suite)。TestNG的测试用例可以是相互独立的,也可以按照特定的顺序来执行。
通过TestNG.xml的配置,可实现运行多个测试用例的不同组合。
(1)以class为基本点
(2)以method为基本点
(3)以package为基本点
8.TestNg如何用命令行运行
(1)在Eclipse中的自动build的选项给勾选上,这样就会自动的build
操作提示:在菜单Project中,单击Build Automatically。
(2)在workspace下面找到该工程的bin文件夹,并打开
(3)把bin文件夹下面的内容压缩成zip包(注:不包含bin文件夹),auto.zip
(4)把zip文件改成jar后缀,修改后缀名即可,auto.jar
操作提示:在文件夹窗口中,按下alt键,选择“工具”菜单->“文件夹选项”,点击“查看”选项卡,去掉“隐藏已知文件的扩展名”的勾选。
(5)把selenium-server-standalone-2.25.0.jar,auto.jar,TestBaidu.xml放在同一个文件夹下,如放在C:\automation
(6)编写一个bat文件:
@echo off
set LIB=C:\automation
set CLASSPATH=%LIB%\selenium-server-standalone-2.25.0.jar;%LIB%\auto.jar
java org.testng.TestNG %LIB%\TestBaidu.xml
pause
(7)双击运行bat文件即可。
9.测试报告中的自定义日志
TestNG提供了日志功能,在测试过程中可通过自定义的方式记录测试脚本的运行信息,例如,记录测试程序的执行步骤信息及测试出错时的异常信息等。日志信息一般使用两种模式进行记录,即高层级和低层级。低层级模式日志会记录所有的测试步骤信息,高层级模式日志只记录测试脚本中的主要事件信息。读者可根据测试需求选择日志信息的记录层级。
public class LogRecord { @Test public void OpenBrowser(){ System.out.println("OpenBrowser方法被调用!"); Reporter.log("调用打开浏览器的方法"); } @Test public void SignIn(){ System.out.println("SignIn方法被调用!"); Reporter.log("调用登录方法"); } @Test public void LogOut(){ System.out.println("LogOut方法被调用!"); Reporter.log("调用注销方法"); } }
在TestNG测试报告中,可查看测试运行中的Report Log信息,如下图所示。
10.特定顺序执行测试用例
使用参数priority可实现按照特定顺序执行测试用例。
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 test1(){ System.out.println("test1方法被调用"); } @Test(priority=1) public void test2(){ System.out.println("test2方法被调用"); } }
11.跳过某个测试方法
使用参数enabled=false来跳过某测试方法。
@Test(priority=1,enabled=false) public void test2(){ System.out.println("test2方法被调用"); }