TestNG安装与使用

 


TestNG介绍

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


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();

	@Test
	public 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
	@Test
	public 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 initEnvironmentTest
Inside testPrintMessage()
Manisha
Inside 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()
Manisha
Inside testSalutationMessage()
Hi!Manisha












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值