TestNG安装与使用

来源:互联网 发布:银联数据硕士待遇 编辑:程序博客网 时间:2024/09/21 13:17

 

TestNG介绍

TestNGJava中的一个测试框架, 类似于JUnitNUnit,   功能都差不多, 只是功能更加强大,使用也更方便


Eclipse安装TestNG插件

1)在线安装

eclipse中,Help-> Install NewSoftwareAdd "http://beust.com/eclipse" 


2)离线安装

1. 将解压后的文件..\eclipse-testng离线包\features\org.testng.eclipse_6.9.9.201510270734   文件夹 放到      eclipse--》features目录下

2. 将解压后的文件..\eclipse-testng离线包\plugins\org.testng.eclipse_6.9.8.201510130443  文件夹  放到                 eclipse--》plugins目录下

3. 重启eclipse

4. 验证是否安装成功,file-->new-->other-->TestNg

编写简单的测试

步骤
1)编写测试的业务逻辑,在代码中插入TestNG注解
2)创建testng.xml文件,在其中添加测试信息
3)运行TestNG

创建mployeeDetails类,用来get/set员工姓名/月薪/年龄


<strong><span lang="EN-US" style="font-size: 10.5pt; font-family: 宋体;">publicclass EmployeeDetails {</span></strong>
 private String name;   private double monthlySalary;   private int age;      /**   * @return the name   */   public String getName() {      return name;   }   /**   * @param name the name to set   */   public void setName(String name) {      this.name = name;   }   /**   * @return the monthlySalary   */   public double getMonthlySalary() {      return monthlySalary;   }   /**   * @param monthlySalary the monthlySalary to set   */   public void setMonthlySalary(double monthlySalary) {      this.monthlySalary = monthlySalary;   }   /**   * @return the age   */   public int getAge() {      return age;   }   /**   * @param age the age to set   */   public void setAge(int age) {   this.age = age;   }}


创建 EmpBusinessLogic类,用于计算员工年薪

<span style="font-weight: normal;"><span style="font-size:14px;">public class EmpBusinessLogic {   // Calculate the yearly salary of employee   public double calculateYearlySalary(EmployeeDetails employeeDetails){      double yearlySalary=0;      yearlySalary = employeeDetails.getMonthlySalary() * 12;      return yearlySalary;   }   // Calculate the appraisal amount of employee   public double calculateAppraisal(EmployeeDetails employeeDetails){      double appraisal=0;      if(employeeDetails.getMonthlySalary() < 10000){         appraisal = 500;      }else{         appraisal = 1000;      }      return appraisal;   }}</span></span>

在project中添加TestNG库,project -> build path -> configure build path ->library -? add library -> TestNG 


添加成功


创建一个TestNG类名称为,TestEmployeeDetails,file->other->testNG class

也可以之间创建一个Java类,自己import需要的包


<span style="font-weight: normal;"><span style="font-size:14px;">import org.testng.Assert;import org.testng.annotations.Test;public class TestEmployeeDetails {EmpBusinessLogic empBusinessLogic = new EmpBusinessLogic();EmployeeDetails employee = new EmployeeDetails();@Testpublic void testCalculateAppriasal() {employee.setName("Rajeev");employee.setAge(25);employee.setMonthlySalary(8000);double appraisal = empBusinessLogic.calculateAppraisal(employee);Assert.assertEquals(500, appraisal, 0.0, "500");}// test to check yearly salary@Testpublic void testCalculateYearlySalary() {employee.setName("Rajeev");employee.setAge(25);employee.setMonthlySalary(8000);double salary = empBusinessLogic.calculateYearlySalary(employee);Assert.assertEquals(96000, salary, 0.0, "8000");}}</span></span>
textng.xml文件

<span style="font-weight: normal;"><span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">  <test name="test1">    <classes>       <class name="TestEmployeeDetails"/>    </classes>  </test></suite></span></span>
运行testng.xml->右击Run As->TestNg.suite,可以在控制台中看到运行结果



此外,TestNG创建了一个HTML报告,会自动在当前目录下创建一个文件夹名为test-output,打开并加载index.html,可以看到测试结果页面


xml文件

使用实例1

这个文件告诉TestNG执行在ParameterSample类中找到所有方法,并执行ParameterTest类中所有以database开头的方法,排除名为inProgress的方法。

使用示例2

通过<test>标签下的<package>标签指定要导入的包

  • 一个suite(套件)由一个或多个测试组成
  • 一个test(测试)由一个或多个类组成
  • 一个class(类)由一个或多个方法组成

基本注解

注解描述@BeforeSuite注解的方法将只运行一次,运行所有测试前此套件中。@AfterSuite注解的方法将只运行一次此套件中的所有测试都运行之后。@BeforeClass注解的方法将只运行一次先行先试在当前类中的方法调用。@AfterClass注解的方法将只运行一次后已经运行在当前类中的所有测试方法。@BeforeTest注解的方法将被运行之前的任何测试方法属于内部类的 <test>标签的运行。@AfterTest注解的方法将被运行后,所有的测试方法,属于内部类的<test>标签的运行。@BeforeGroups组的列表,这种配置方法将之前运行。此方法是保证在运行属于任何这些组第一个测试方法,该方法被调用。@AfterGroups组的名单,这种配置方法后,将运行。此方法是保证运行后不久,最后的测试方法,该方法属于任何这些组被调用。@BeforeMethod注解的方法将每个测试方法之前运行。@AfterMethod被注释的方法将被运行后,每个测试方法。@DataProvider

标志着一个方法,提供数据的一个测试方法。注解的方法必须返回一个Object[] [],其中每个对象[]的测试方法的参数列表中可以分配。
该@Test 方法,希望从这个DataProvider的接收数据,需要使用一个dataProvider名称等于这个注解的名字。@Factory作为一个工厂,返回TestNG的测试类的对象将被用于标记的方法。该方法必须返回Object[]。@Listeners定义一个测试类的监听器。@Parameters介绍如何将参数传递给@Test方法。@Test标记一个类或方法作为测试的一部分。

套件测试

suite的属性
属性描述name此套件的名称。这是一个强制性的属性。verbose这个运行级别或冗长。parallel由TestNG 运行不同的线程来运行此套件。thread-count使用的线程数,如果启用并行模式(忽略其他方式)。annotations在测试中使用注释的类型。time-out默认的超时时间,将用于本次测试中发现的所有测试方法。当有两个或以上的TestNG测试类时可用

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">  <test name="exampletest1">    <classes>       <class name="Test1" />    </classes>  </test>  <test name="exampletest2">    <classes>       <class name="Test2" />    </classes>  </test></suite> 

组测试


在编写测试的过程中,我们经常遇到只想执行个别或者某一部分/某一部分的测试用例,这时可以用组测试的方法
<div><span style="font-family:Consolas, Courier New, Courier, mono, serif;color:#5c5c5c;"><span style="line-height: 18px;"></span></span><pre name="code" class="java">public class TestngGroups {      @Test(groups = { "functest", "checkintest" })      public void testMethod1() {          System.err.println("groups = { functest, checkintest }");      }        @Test(groups = { "functest", "checkintest" })      public void testMethod2() {          System.err.println("groups = { functest, checkintest }");      }        @Test(groups = { "functest" })      public void testMethod3() {          System.err.println("groups = { functest }");      }        @Test(groups = { "checkintest" })      public void testMethod4() {          System.err.println("groups = { checkintest }");      }    }  


TestNG.xml使用时,<group>,<run>标签用来指定或排除一部分组

<pre name="code" class="html"><?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">  <suite name="framework_testng">      <test name="TestGroups">          <groups>              <run>                  <include name="functest" />                  <exclude name="checkintest" />              </run>          </groups>            <classes>              <class name="com.dragon.testng.annotation.TestngGroups" />          </classes>      </test>  </suite>  


分组测试执行原则,只保留最小集合进行执行。例如以功能点为粒度进行划分,然后以总的testng.xml将各个功能点的配置汇总起来

注意执行测试的默认顺序是按照testng.xml文件里给定的顺序执行的。如果不希望按此顺序执行,使用preserve-order=false属性,例如:<test name="Regression1" preserve-order="false">

参数化 

TestNG改进了传统测试框架无法传递参数的缺点,它提供了两种传递参数的简单方法:

(1)在测试方法上加@Parameters标签,然后在testng.xml给出参数;

(2)指定@Dataproviders

第一种方式的缺点很明显,它只支持java基本类型,并且在构造值时,无法包含计算逻辑得到需要的参数。

第二种方式可以向测试方法传递任何有效的java类型。我们倾向于第二种方法来构造参数。

在使用TestNG进行测试时,经常会使用到一些参数化配置,比如数据库、连接池、线程池数。

@Parameters标签方法

 // @Parameters注解内对应的参数名称和配置文件中的key必须是相同      @Parameters({ "<span style="font-family: Arial, Helvetica, sans-serif;">secondName</span>" })      @Test      public void testSingleString(String secondName) {          System.err.println("Invoked testString " + secondName);          assert "Cedric".equals(secondName);      }        @Parameters({ "count" })      @Test      public void testSingleInteger(Integer count) {          System.err.println("Invoked count " + count);          assert count.intValue() == 8;      }  

<?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">  <!-- data-provider-thread-count="20" 共享线程池配置 -->  <suite name="framework_testng" data-provider-thread-count="20">        <parameter name="secondname" value="Cedric" />      <parameter name="count" value="8" />      <parameter name="datasource" value="com.dbcp.source" />      <parameter name="jdbcDriver" value="com.mysql.jdbc.driver" />      <parameter name="poolSize" value="10" />              <test verbose="2" name="TestGroups">          <classes>              <class name="com.dragon.testng.annotation.TestngParameters" />          </classes>      </test>  </suite>  

@Dataproviders标签方法

@DataProvider(name = "DP1")       public Object[][] createData() {           Object[][] retObjArr = { { "001", "Jack", "London" },                   { "002", "John", "New York" }, { "003", "Mary", "Miami" },                   { "004", "George", "california" } };           return (retObjArr);       }       @Test(dataProvider = "DP1")       public void testEmployeeData(String empid, String empName, String city) {           System.err.println(empid);           System.err.println(empName);           System.err.println(city);          }        @DataProvider(name = "iterator")       public Iterator<Object[]> getData() {           Set<Object[]> set = new HashSet<Object[]>();           set.add(new String[] { "hello" });           Iterator<Object[]> iterator = set.iterator();           return iterator;       }       @Test(dataProvider = "iterator")       public void testIteraorData(String iterator) {           System.err.println("iterator  .. " + iterator);         }  
DP1数组内的每一组数据都会作为一个测试用例执行


注意要点:

1.我们的@DataProvider方法可以通过读取Excel、数据库、properties文件等方式进行获取,这个取决于实际测试用例的设计和项目的需要,

2.其返回值是返回一个二维数组,数组内的二维元素个数必须和调用方法的参数一致,

3.这个一致包括了个数和顺序以及类型,否则如果类型不匹配或无法自动转换时就会抛出类型转换异常,而参数个数不匹配也会抛出参数缺失异常。



测试的依赖与分组

测试方法之间的依赖是一种很常见的需求,您也许认为,测试之间的依赖不是破坏了测试方法之间的隔离性吗?确实是这样的,但是有时为了这种隔离性,在彼此隔离的测试方法当中要付出很大的代价去相互模拟,所以为了方便起见,testng提供了这种依赖的方式。

Testng当中通过@Test的属性dependsOnMethods,dependsOnGroups来实现针对方法和分组的依赖。

依赖还包括软依赖和硬依赖。硬依赖是很强的关联,如果被依赖的测试失败,那么依赖它的测试会跳过。而软依赖则不会跳过。通过给@Test设定alwaysRun=true来实现软依赖。使用依赖时需要注意的是要避免循环依赖

import org.testng.Assert;import org.testng.annotations.Test;public class DependencyTestUsingAnnotation {    String message = "Manisha";    MessageUtil messageUtil = new MessageUtil(message);    @Test    public void testPrintMessage() {System.out.println("Inside testPrintMessage()");message = "Manisha";Assert.assertEquals(message, messageUtil.printMessage());    }    @Test(dependsOnMethods = { "initEnvironmentTest" })    public void testSalutationMessage() {        System.out.println("Inside testSalutationMessage()");message = "Hi!" + "Manisha";Assert.assertEquals(message, messageUtil.salutationMessage());    }    @Test    public void initEnvironmentTest() {System.out.println("This is initEnvironmentTest");    }}


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">    <test name="test1"><classes>    <class name="DependencyTestUsingAnnotation" /></classes>    </test></suite>
验证输出

This is initEnvironmentTestInside testPrintMessage()ManishaInside testSalutationMessage()Hi!Manisha

异常测试

TestNG跟踪异常处理代码提供了一个选项。可以测试是否需要代码抛出异常或不抛出。 @Test注释expectedExceptions 参数一起使用。


import org.testng.Assert;import org.testng.annotations.Test;public class ExpectedExceptionTest {    String message = "Manisha";    MessageUtil messageUtil = new MessageUtil(message);       @Test(expectedExceptions = ArithmeticException.class)    public void testPrintMessage() {        System.out.println("Inside testPrintMessage()");             messageUtil.printMessage();        }   @Test   public void testSalutationMessage() {      System.out.println("Inside testSalutationMessage()");      message = "Hi!" + "Manisha";      Assert.assertEquals(message,messageUtil.salutationMessage());   }}


<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" ><suite name="Suite1">   <test name="test1">       <classes>      <class name="ExpectedExceptionTest" /></classes>   </test></suite>

验证输出。testPrintMessage()测试的情况下会获得通过。

Inside testPrintMessage()ManishaInside testSalutationMessage()Hi!Manisha












0 0