1. 教程
testng入门教程: http://www.yiibai.com/testng/EasyMock教程 : http://www.yiibai.com/easymock/
junit 入门教程: http://www.yiibai.com/junit/
2. eclipse中testng插件安装配置
(1)安装插件
二中tesgng插件安装方法(在线,离线)
方法一: 离线安装
TestNG Eclipse插件下载地址http://testng.org/doc/download.html。
下载下来以后,放在eclipse的plugins文件夹下,然后启动eclipse,点击Help -> software update -> Installed Software, 查找到TestNG Eclipse插件,点击Install(安装),安装完成后,重启eclipse。
然后去Windows -> show view -> other,java文件夹下,有TestNG,双击图标,在eclipse界面下面便会出现TestNg的窗体
方法二: 在线安装具体步骤如下:
1. 选择菜单:Help->Install New Software,然后在弹出的窗口中的Work with后面的输入框中输入:
http://beust.com/eclipse。
2. 然后点击Add按钮,选中TestNG后一路点击Next下去安装即可,直到Finished之后,重启Eclipse完成安装。
(2)配置使用
配置步骤:
打开 eclipse -> 右键单击项目,然后单击property > Java Build Path > Libraries->Add Library->TestNG (或者 Add External JARS ,添加额外下载的jar包,如testng-6.8.jar )
简单的一个例子:
package testng;
public class testngclass {
private String message;
//Constructor
//@param message to be printed
public testngclass(String message){
this.message = message;
}
// prints the message
public String printMessage(){
System.out.println(message);
return message;
}
}
testng测试类:
package testng;
import org.testng.annotations.Test;
import org.testng.Assert;
public class testngclassTest {
String message = "Hello World";
testngclass messageUtil = new testngclass(message);
@Test
public void testPrintMessage() {
Assert.assertEquals(message,messageUtil.printMessage());
}
}
项目结构:
(3)运行testng
执行TestNg有几种方式:命令行、Eclipse、ant等.
第一种: 直接执行,右键要执行的方法, 点Run As ->TestNG Test
第二种: 通过testng.xml文件来执行. 把要执行的case, 放入testng.xml文件中。 右键点击testng.xml, 点Run As->TestNG Suite
testng.xml内容:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEsuiteSYSTEM"http://testng.org/testng-1.0.dtd">
<suitename="Suite1">
<testname="test1">
<classes>
<classname="testng.testngclassTest"/>
</classes>
</test>
</suite>
(4)运行结果
3. testng 详细使用
注:注释被正式加入到JDK 5中的Java语言和TestNG作出选择使用注释注释测试类。
(1)TestNG的支持列表中的注解
@DataProvider | 为测试方法提供数据 |
---|
注解 | 描述 |
@BeforeMethod | 在每个测试方法 前 执行 |
@AfterMethod | 在每个测试方法 后 执行 |
@BeforeClass | 被注释的方法将在当前类的第一个测试方法调用前运行 |
@AfterClass | 被注释的方法将在当前类的所有测试方法调用后运行 |
@BeforeGroups | 被配置的方法将在列表中的gourp前运行。这个方法保证在第一个属于这些组的测试方法调用前立即执行 |
@BeforeTest | 被注释的方法将在测试运行前运行 |
@AfterTest | 被注释的方法将在测试运行后运行 |
@BeforeSuite | 被注释的方法将在所有测试运行前运行 |
@AfterSuite | 被注释的方法将在所有测试运行后运行 |
alwaysRun | 对于每个bufore方法(beforeSuite, beforeTest, beforeTestClass 和 beforeTestMethod, 但是不包括 beforeGroups): 如果设置为true,被配置的方法将总是运行而不管它属于哪个组。 对于after方法(afterSuite, afterClass, ...): 如果设置为true,被配置的方法甚至在一个或多个先调用的方法失败或被忽略时也将运行。 |
dependsOnGroups | 这个方法依赖的组列表 |
dependsOnMethods | 这个方法依赖的方法列表 |
enabled | 这个类的方法是否激活 |
groups | 这个类或方法所属的分组列表 |
inheritGroups | 如果设置为true,这个方法被属于在类级别被@Test annotation指定的组 |
(2) testng套件测试
目的:为了测试软件程序的行为或一系列行为的情况下,是一个集合。
testng.xml中有<suite>根标签。它描述了一个测试套件,这反过来又是由多个<test>区段组成。
下表列出了所有的<suite>可接受合法属性。
属性 | 描述 |
---|---|
name | 此套件的名称。这是一个强制性的属性。 |
verbose | 这个运行级别或冗长。 |
parallel | 由TestNG 运行不同的线程来运行此套件。 |
thread-count | 使用的线程数,如果启用并行模式(忽略其他方式)。 |
annotations | 在测试中使用注释的类型。 |
time-out | 默认的超时时间,将用于本次测试中发现的所有测试方法。 |
testngclassTest,testngclassTest1
testng1.xml为:
<?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="testng.testngclassTest"/>
</classes>
</test>
<test name="test2">
<classes>
<class name="testng.testngclassTest1"/>
</classes>
</test>
</suite>
运行结果: 分别产生2个测试报告
(2)忽略测试
@Test(enabled = false)有助于禁用此测试案例。
例如:
@Test(enabled = false)
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Manisha";
Assert.assertEquals(message, messageUtil.printMessage());
}
(3)组测试
在TestNG中组测试是一个新的创新功能,它不存在于JUnit框架,它允许调度到适当的部分方法和瓶坯复杂的测试方法分组。
这给了你最大的灵活性,如何分区测试,如果想运行两套不同的测试背靠背,不要求重新编译任何东西。
组指定testng.xml文件使用<groups>标签。
例子:类:
public class MessageUtil {
private String message;
// Constructor
// @param message to be printed
public MessageUtil(String message) {
this.message = message;
}
// prints the message
public String printMessage() {
System.out.println(message);
return message;
}
// add "tutorialspoint" to the message
public String salutationMessage() {
message = "tutorialspoint" + message;
System.out.println(message);
return message;
}
// add "www." to the message
public String exitMessage() {
message = "www." + message;
System.out.println(message);
return message;
}
}
测试类:
<span style="color:#333333;">import org.testng.Assert;
import org.testng.annotations.Test;
public class GroupTestExample {
String message = ".com";
MessageUtil messageUtil = new MessageUtil(message);
</span><span style="color:#ff0000;">@Test(groups = { "functest", "checkintest" })</span><span style="color:#333333;">
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = ".com";
Assert.assertEquals(message, messageUtil.printMessage());
}
@Test(groups = { "checkintest" })
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "tutorialspoint" + ".com";
Assert.assertEquals(message, messageUtil.salutationMessage());
}
</span><span style="color:#ff0000;">@Test(groups = { "functest" })</span><span style="color:#333333;">
public void testingExitMessage() {
System.out.println("Inside testExitMessage()");
message = "www." + "tutorialspoint"+".com";
Assert.assertEquals(message, messageUtil.exitMessage());
}
}</span>
testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="test1">
<groups>
<run>
<include name="functest" />
</run>
</groups>
<classes>
<class name="GroupTestExample" />
</classes>
</test>
</suite>
结果:测试类中的2个被标记为红色的方法被执行
(3)异常测试
@Test(expectedExceptions)例如:
@Test(expectedExceptions = ArithmeticException.class)
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
messageUtil.printMessage();
}
(4)依赖测试
使用属性dependsOnMethods在 @Test 注释OR使用属性dependsOnGroups在@Test注解。
例子1:
<span style="color:#333333;">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());
}
</span><span style="color:#ff0000;">@Test(dependsOnMethods = { "initEnvironmentTest" })</span>
<span style="color:#ff0000;">//只有在执行 initEnvironmentTest() 方法之后,才会运行 testSalutationMessage()</span><span style="color:#333333;">
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");
}
}</span>
例子2:
public class DependencyTestUsingAnnotation {
String message = "Manisha";
MessageUtil messageUtil = new MessageUtil(message);
@Test(groups = { "init" })
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
message = "Manisha";
Assert.assertEquals(message, messageUtil.printMessage());
}
<span style="color:#ff0000;">@Test(dependsOnGroups = { "init.*" })</span>
//testPrintMessage的()和initEnvironmentTest()将始终前testSalutationMessage()被调用
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
message = "Hi!" + "Manisha";
Assert.assertEquals(message, messageUtil.salutationMessage());
}
@Test(groups = { "init" })
public void initEnvironmentTest() {
System.out.println("This is initEnvironmentTest");
}
}
如果一个方法失败,取决于你有一个很难依赖于它(alwaysRun= false,这是默认的),没有标记的方法依赖于它的失败,但作为跳过。
跳过的方法将被报告为例如在最终报告(在HTML中,既不是红也不是绿的颜色),这是很重要的,因为跳过的方法不一定是失败。
(5)参数化测试
(一)使用testng.xml :在testng.xml文件中定义的简单参数,然后在源文件中引用这些参数。
使用testng.xml
下面是支持的类型:
String
int/Integer
boolean/Boolean
byte/Byte
char/Character
double/Double
float/Float
long/Long
short/Short
例子:
<span style="color:#333333;">import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class ParameterizedTest1 {
@Test
</span><span style="color:#ff0000;"> @Parameters("myName")//<span style="font-family: Verdana, Arial, 宋体, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 21px; background-color: rgb(245, 245, 245);">注释 @Parameters("myName") 到此方法。该参数将被传递testng.xml</span></span><span style="color:#333333;">
public void parameterTest(String myName) {
System.out.println("Parameterized value is : " + myName);
}
}</span>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="test1">
<span style="color:#ff0000;"><parameter name="myName" value="manisha"/> </span>
<classes>
<class name="ParameterizedTest1" />
</classes>
</test>
</suite>
数据提供程序
第一个例子是@DataProvider的使用Vector,String或Integer 作为参数,第二个例子是关于@DataProvider 的使用对象作为参数。
例子1:
类:
public class PrimeNumberChecker {
public Boolean validate(final Integer primeNumber) {
for (int i = 2; i < (primeNumber / 2); i++) {
if (primeNumber % i == 0) {
return false;
}
}
return true;
}
}
测试类:
<span style="color:#333333;">import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ParamTestWithDataProvider1 {
private PrimeNumberChecker primeNumberChecker;
@BeforeMethod
public void initialize() {
primeNumberChecker = new PrimeNumberChecker();
}
</span><span style="color:#ff0000;"> @DataProvider(name = "test1")</span><span style="color:#333333;">
public static Object[][] primeNumbers() {
return new Object[][] { { 2, true }, { 6, false }, { 19, true },
{ 22, false }, { 23, true } };
}
// This test will run 4 times since we have 5 parameters defined
</span><span style="color:#ff0000;"> @Test(dataProvider = "test1")//<span style="color: rgb(51, 51, 51); font-family: Verdana, Arial, 宋体, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 21px; background-color: rgb(245, 245, 245);">dataProvider的属性被映射到"test1"</span></span><span style="color:#333333;">
public void testPrimeNumberChecker(Integer inputNumber,
Boolean expectedResult) {
System.out.println(inputNumber + " " + expectedResult);
Assert.assertEquals(expectedResult,
primeNumberChecker.validate(inputNumber));
}
}</span>
例子2:
Java类 Bean:
public class Bean {
private String val;
private int i;
public Bean(String val, int i){
this.val=val;
this.i=i;
}
public String getVal() {
return val;
}
public void setVal(String val) {
this.val = val;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
}
测试类:
<span style="color:#333333;">import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ParamTestWithDataProvider2 {
</span><span style="color:#ff0000;"> @DataProvider(name = "test1")</span><span style="color:#333333;">
public static Object[][] primeNumbers() {
return new Object[][] { { new Bean("hi I am the bean", 111) } };
}
@Test(dataProvider = "test1")
public void testMethod(</span><span style="color:#ff0000;">Bean myBean</span><span style="color:#333333;">) {
System.out.println(myBean.getVal() + " " + myBean.getI());
}
}</span>
(6)运行junit
可以使用TestNG执行现有JUnit测试用例。
TestNG可以自动识别和运行JUnit测试,所以你可以使用TestNG运行所有的测试,并编写新的测试使用TestNG。
import org.junit.Test;
import static org.testng.AssertJUnit.assertEquals;
public class TestJunit {
@Test
public void testAdd() {
String str= "Junit testing using TestNG";
assertEquals("Junit testing using TestNG",str);
}
}
xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Converted JUnit suite" >
<test name="JUnitTests" <span style="color:#ff0000;">junit="true"</span>>
<classes>
<class name="TestJunit" />
</classes>
</test>
</suite>
要执行JUnit测试用例定义属性 junit="true" 如上面的xml文件中. JUnit测试用例类TestJunit定义在类名。
JUnit 4中,TestNG将使用 org.junit.runner.JUnitCore 运行测试。
(7) testng测试结果报告
监听器: 为了实现一个监听类,类有实现theorg.testng。 ITestListener接口。这些类在运行时通知了TestNG测试开始时,结束后,失败,跳过或传递。
记录器: 为了实现一个报表类,实现一个org.testng.IReporter接口。这些类一整套运行结束时调用。调用时,该对象包含整个测试运行的信息传递到这个类。
下表列出了不同的情况报告和记录的例子:
自定义日志 | 这个例子说明如何编写您自己的记录。 |
自定义记录器 | 这个例子说明了如何编写自己的记录器。 |
HTML 和 XML 报告 | 这个例子说明了默认的HTML和XML报告TestNG产生。 |
JUnit 报告 | 这个例子说明了TestNG的报告生成Junit的报告。 |
(一) 自定义日志记录
import org.testng.Assert;
import org.testng.annotations.Test;
public class SampleTest {
@Test
public void testMethodOne(){
Assert.assertTrue(true);
}
@Test
public void testMethodTwo(){
Assert.assertTrue(false);
}
@Test(dependsOnMethods={"testMethodTwo"})//结果将会被跳过
public void testMethodThree(){
Assert.assertTrue(true);
}
}
创建自定义日志记录类:
import org.testng.ITestResult;
import org.testng.TestListenerAdapter;
public class CustomListener <span style="color:#ff0000;">extends TestListenerAdapter</span>{
private int m_count = 0;
@Override
public void onTestFailure(ITestResult tr) {
log(tr.getName()+ "--Test method failed\n");
}
@Override
public void onTestSkipped(ITestResult tr) {
log(tr.getName()+ "--Test method skipped\n");
}
@Override
public void onTestSuccess(ITestResult tr) {
log(tr.getName()+ "--Test method success\n");
}
private void log(String string) {
System.out.print(string);
if (++m_count % 40 == 0) {
System.out.println("");
}
}
}
上述的类扩展TestListenerAdapter,空方法实现ITestListener。因此,不需要重写其他方法从接口。如果你喜欢,可以直接实现这个接口。
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Simple Logger Suite">
<span style="color:#ff0000;"><listeners>
<listener class-name="CustomListener" />
</listeners>
</span>
<test name="Simple Logger test">
<classes>
<class name="SampleTest" />
</classes>
</test>
</suite>
结果:
testMethodOne--Test method success testMethodTwo--Test method failed testMethodThree--Test method skipped =============================================== Simple Logger Suite Total tests run: 3, Failures: 1, Skips: 1 ===============================================
(二)自定义记录器
import org.testng.Assert;
import org.testng.annotations.Test;
public class SampleTest {
@Test
public void testMethodOne(){
Assert.assertTrue(true);
}
@Test
public void testMethodTwo(){
Assert.assertTrue(false);
}
@Test(dependsOnMethods={"testMethodTwo"})
public void testMethodThree(){
Assert.assertTrue(true);
}
}
创建自定义报告类:
import java.util.List;
import java.util.Map;
import org.testng.IReporter;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestContext;
import org.testng.xml.XmlSuite;
public class CustomReporter implements IReporter{
@Override
public void generateReport(List xmlSuites, List suites,
String outputDirectory) {
//Iterating over each suite included in the test
for (ISuite suite : suites) {
//Following code gets the suite name
String suiteName = suite.getName();
//Getting the results for the said suite
Map suiteResults = suite.getResults();
for (ISuiteResult sr : suiteResults.values()) {
ITestContext tc = sr.getTestContext();
System.out.println("Passed tests for suite '" + suiteName +
"' is:" + tc.getPassedTests().getAllResults().size());
System.out.println("Failed tests for suite '" + suiteName +
"' is:" +
tc.getFailedTests().getAllResults().size());
System.out.println("Skipped tests for suite '" + suiteName +
"' is:" +
tc.getSkippedTests().getAllResults().size());
}
}
}
}
它实现了IReporter接口定义的 方法GenerateReport。这个方法有三个参数:
第一个是xmlSuite,这是TestNG的测试XML正在执行中提到的列表套件
第二个是套件,其中包含一套测试执行后信息,该对象包含了所有的信息包,类,测试方法和测试执行结果。
第三的outputDirectory,报告将产生的输出文件夹路径,其中包含的信息。
<span style="color:#333333;"><?xml version="1.0" encoding="UTF-8"?>
<suite name="Simple Reporter Suite">
</span><span style="color:#ff0000;"><listeners>
<listener class-name="CustomReporter" />
</listeners></span><span style="color:#333333;">
<test name="Simple Reporter test">
<classes>
<class name="SampleTest" />
</classes>
</test>
</suite></span>
结果:
=============================================== Simple Reporter Suite Total tests run: 3, Failures: 1, Skips: 1 =============================================== Passed tests for suite 'Simple Reporter Suite' is:1 Failed tests for suite 'Simple Reporter Suite' is:1 Skipped tests for suite 'Simple Reporter Suite' is:1自定义报告器,打印的数量在控制台上对每个套件包含在上述的测试执行失败,通过跳过测试。 报告器主要是用于测试的执行,以生成最终的报告。扩展程序可以被用来生成XML,HTML,CHM,CSV或文本格式的文件,根据报告要求。
(三)testng 的html , xml 报告
import org.testng.Assert;
import org.testng.annotations.Test;
public class SampleTest {
@Test
public void testMethodOne(){
Assert.assertTrue(true);
}
@Test
public void testMethodTwo(){
Assert.assertTrue(false);
}
@Test(dependsOnMethods={"testMethodTwo"})
public void testMethodThree(){
Assert.assertTrue(true);
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Simple HTML-XML Suite">
<test name="Simple HTML-XML test">
<classes>
<class name="SampleTest" />
</classes>
</test>
</suite>
2个重要的报告:
(四)testng junit报告
JUnit是单元框架,最初用于许多Java应用软件作为一个单元测试框架之一。默认情况下,JUnit测试生成一个简单的XML文件测试执行报告。然后这些XML文件可以被用来生成任何自定义报表按测试要求。
我们也可以使用XML文件生成HTML报告(XML---->HTML)。Ant的有这样一个实用的任务,需要这些JUnit的XML文件作为输入,并生成一个HTML报告。
TestNG默认情况下,生成JUnit的XML执行任何测试报告(测试输出文件夹中)。我们可以使用这些XML格式的报告文件作为一个JUnit HTML报告生成的输入(Junit XML---> Junit HTML)。
import org.testng.Assert;
import org.testng.annotations.Test;
public class SampleTest {
@Test
public void testMethodOne(){
Assert.assertTrue(true);
}
@Test
public void testMethodTwo(){
Assert.assertTrue(false);
}
@Test(dependsOnMethods={"testMethodTwo"})
public void testMethodThree(){
Assert.assertTrue(true);
}
}
testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Simple Suite">
<test name="Simple test">
<classes>
<class name="SampleTest" />
</classes>
</test>
</suite>
验证输出。
=============================================== Simple Suite Total tests run: 3, Failures: 1, Skips: 1 ===============================================
现在,我们已经可以从上面执行JUnit的XML报告,让我们创建一个简单的Ant构建配置XML文件来生成一个HTML报告测试执行。
创建一个新的文件名为 build.xml 在目录 TestNG_WORKSPACE 中
<project name="TestNG_WORKSPACE" default="junit-report" basedir=".">
<!-- Sets the property variables to point to respective directories -->
<property name="junit-xml-dir" value="${basedir}/test-output/junitreports"/>
<property name="<span style="color:#ff0000;">report-dir" value="${basedir}/html-report" /></span>
<!-- Ant target to generate html report -->
<target name="junit-report">
<!-- Delete and recreate the html report directories -->
<delete dir="${report-dir}" failοnerrοr="false"/>
<mkdir dir="${report-dir}" />
<mkdir dir="${report-dir}/Junit" />
<!-- Ant task to generate the html report.
todir - Directory to generate the output reports
fileset - Directory to look for the junit xml reports.
report - defines the type of format to be generated.
Here we are using "noframes" which generates a single html report.
-->
<junitreport todir="${report-dir}/Junit">
<fileset dir="${junit-xml-dir}">
<include name="**/*.xml" />
</fileset>
<report format="noframes" todir="${report-dir}/Junit" />
</junitreport>
</target>
</project>
定义了一个简单的Ant build.xml文件,具有特定的Ant目标名为JUnit的报告,执行时产生一个JUnit报告。目标看起来JUnit报告XML文件目录下test-output/junitreports。 Ant配置文件的默认目标执行配置JUnit的报告。
打开命令提示符窗口,然后转到 TestNG_WORKSPACE 目录在命令提示符下运行以下命令:
TestNG_WORKSPACE> ant
一旦执行,一个JUnit HTML报告,将产生配置目录/html-report/Junit。打开文件名为junit-noframes.html即可。