TestNG使用教程详解

article/2025/9/21 3:14:13

一、TestNG介绍

TestNG是Java中的一个测试框架, 类似于JUnit 和NUnit, 功能都差不多, 只是功能更加强大,使用也更方便。
详细使用说明请参考官方链接:TestNG - Welcome

WIKI教程:TestNG - 小组测试( Group Test)_学习TestNG|WIKI教程 

二、TestNG安装(基于eclipse+maven)

工程的pom.xml中需要添加如下内容

<dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.10</version><scope>test</scope>
</dependency>

记得Maven install一下
eclipse中的TestNG插件的安装则需要在Help中做,地址为http://beust.com/eclipse

三、TestNG基本使用和运行

1、testng的基本使用

新建一个maven工程,新建一个TestNG的class,可以直接新建一个class来使用,也可以新建一个TestNG的class,如下图所示:

TestNG new

此方法好处在于你在创建class的时候可以直接把注解的各个方法都加进去,同时也可以创建xml,名字路径可以自己定义,注意xml文件的路径是支持相对路径的,出来的class文件如下所示:

package com.demo.test.testng;import org.testng.annotations.Test;public class NewTest {@Testpublic void f() {}
}

 一个简单的用例如下:

package com.demo.test.testng;import org.testng.Assert;
import org.testng.annotations.Test;public class NewTest {@Testpublic void f() {System.out.println("this is new test");Assert.assertTrue(true);}
}

2、xml方式运行

由于我将xml放置在其他文件夹,不和class放在一个文件夹,所以需要修改xml,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false"><test name="Test"><classes><class name="com.demo.test.testng.NewTest"/></classes></test> <!-- Test -->
</suite> <!-- Suite -->

四、注解说明

TestNG支持多种注解,可以进行各种组合,如下进行简单的说明

@BeforeSuite    在该套件的所有测试都运行在注释的方法之前,仅运行一次
@AfterSuite    在该套件的所有测试都运行在注释方法之后,仅运行一次
@BeforeClass    在调用当前类的第一个测试方法之前运行,注释方法仅运行一次
@AfterClass    在调用当前类的第一个测试方法之后运行,注释方法仅运行一次
@BeforeTest    注释的方法将在属于test标签内的类的所有测试方法运行之前运行
@AfterTest    注释的方法将在属于test标签内的类的所有测试方法运行之后运行
@BeforeGroups    配置方法将在之前运行组列表。 此方法保证在调用属于这些组中的任何一个的第一个测试方法之前不久运行
@AfterGroups    此配置方法将在之后运行组列表。该方法保证在调用属于任何这些组的最后一个测试方法之后不久运行
@BeforeMethod    注释方法将在每个测试方法之前运行
@AfterMethod    注释方法将在每个测试方法之后运行
@DataProvider    标记一种方法来提供测试方法的数据。 注释方法必须返回一个Object [] [],其中每个Object []可以被分配给测试方法的参数列表。 要从该DataProvider接收数据的@Test方法需要使用与此注释名称相等的dataProvider名称
@Factory    将一个方法标记为工厂,返回TestNG将被用作测试类的对象。 该方法必须返回Object []
@Listeners    定义测试类上的侦听器
@Parameters    描述如何将参数传递给@Test方法
@Test    将类或方法标记为测试的一部分,此标记若放在类上,则该类所有公共方法都将被作为测试方法
 

如上列表中的@Factory、@Linsteners这两个是不常用的;
前十个注解看起来不太容易区分,顺序不太容易看明白,以如下范例做简单说明,代码:

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;public class NewTest {@Test(groups="group1")public void test1() {System.out.println("test1 from group1");Assert.assertTrue(true);}@Test(groups="group1")public void test11() {System.out.println("test11 from group1");Assert.assertTrue(true);}@Test(groups="group2")public void test2() {System.out.println("test2 from group2");Assert.assertTrue(true);}@BeforeTestpublic void beforeTest() {System.out.println("beforeTest");}@AfterTestpublic void afterTest() {System.out.println("afterTest");}@BeforeClasspublic void beforeClass() {System.out.println("beforeClass");}@AfterClasspublic void afterClass() {System.out.println("afterClass");}@BeforeSuitepublic void beforeSuite() {System.out.println("beforeSuite");}@AfterSuitepublic void afterSuite() {System.out.println("afterSuite");}//只对group1有效,即test1和test11@BeforeGroups(groups="group1")public void beforeGroups() {System.out.println("beforeGroups");}//只对group1有效,即test1和test11@AfterGroups(groups="group1")public void afterGroups() {System.out.println("afterGroups");}@BeforeMethodpublic void beforeMethod() {System.out.println("beforeMethod");}@AfterMethodpublic void afterMethod() {System.out.println("afterMethod");}
}

运行结果如下:

beforeSuite
beforeTest
beforeClass
beforeGroups
beforeMethod
test1 from group1
afterMethod
beforeMethod
test11 from group1
afterMethod
afterGroups
beforeMethod
test2 from group2
afterMethod
afterClass
afterTest
PASSED: test1
PASSED: test11
PASSED: test2===============================================Default testTests run: 3, Failures: 0, Skips: 0
===============================================afterSuite

五、TestNG断言

TestNG的断言种类很多,包括相等/不相等,true/false、为null/不为null、相同/不相同等。

六、TestNG预期异常测试

预期异常测试通过在@Test注解后加入预期的Exception来进行添加,范例如下所示:

@Test(expectedExceptions = ArithmeticException.class)public void divisionWithException() {int i = 1 / 0;System.out.println("After division the value of i is :"+ i);}

七、TestNG忽略测试

有时候我们写的用例没准备好,或者该次测试不想运行此用例,那么删掉显然不明智,那么就可以通过注解@Test(enabled = false)来将其忽略掉,此用例就不会运行了,如下范例:

import org.testng.annotations.Test;public class TestCase1 {@Test(enabled=false)public void TestNgLearn1() {System.out.println("this is TestNG test case1");}@Testpublic void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

 八、TestNG超时测试

“超时”表示如果单元测试花费的时间超过指定的毫秒数,那么TestNG将会中止它并将其标记为失败。此项常用于性能测试。如下为一个范例:

import org.testng.annotations.Test;public class TestCase1 {@Test(timeOut = 5000) // time in mullisecondspublic void testThisShouldPass() throws InterruptedException {Thread.sleep(4000);}@Test(timeOut = 1000)public void testThisShouldFail() {while (true){// do nothing}}
}

结果如下:

PASSED: testThisShouldPass
FAILED: testThisShouldFail
org.testng.internal.thread.ThreadTimeoutException: Method com.demo.test.testng.TestCase1.testThisShouldFail() didn't finish within the time-out 1000at com.demo.test.testng.TestCase1.testThisShouldFail(TestCase1.java:37)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)at org.testng.internal.InvokeMethodRunnable.runOne(InvokeMethodRunnable.java:54)at org.testng.internal.InvokeMethodRunnable.run(InvokeMethodRunnable.java:44)at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)at java.util.concurrent.FutureTask.run(FutureTask.java:266)at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)at java.lang.Thread.run(Thread.java:748)

九、分组测试

分组测试即为使用group,如果你使用xml的话就是里边的<groups>标签,如果是直接在class中,是通过@Test(groups="group2")这种方式来分组,如第四节的注解说明中的那个例子,分了两个group,而且@BeforeGroup是需要添加group名称才可以正确挂载到该group下的;
这个group说明可以是在单个的测试方法上,也可以在class上,只要具有同样的group名称都会在同一个group中,同时group名称可以有多个,类似@Test(groups = {"mysql","database"})这种,范例如下:
一个测试文件NewTest.class:

public class NewTest {@Test(groups="group1")public void test1() {System.out.println("test1 from group1");Assert.assertTrue(true);}@Test(groups="group1")public void test11() {System.out.println("test11 from group1");Assert.assertTrue(true);}@Test(groups="group2")public void test2() {System.out.println("test2 from group2");Assert.assertTrue(true);}@BeforeTestpublic void beforeTest() {System.out.println("beforeTest");}@AfterTestpublic void afterTest() {System.out.println("afterTest");}@BeforeClasspublic void beforeClass() {System.out.println("beforeClass");}@AfterClasspublic void afterClass() {System.out.println("afterClass");}@BeforeSuitepublic void beforeSuite() {System.out.println("beforeSuite");}@AfterSuitepublic void afterSuite() {System.out.println("afterSuite");}@BeforeGroups(groups="group1")public void beforeGroups() {System.out.println("beforeGroups");}@AfterGroups(groups="group1")public void afterGroups() {System.out.println("afterGroups");}@BeforeMethodpublic void beforeMethod() {System.out.println("beforeMethod");}@AfterMethodpublic void afterMethod() {System.out.println("afterMethod");}}

另一个TestCase1.class:

@Test(groups= "group2")
public class TestCase1 {@Test(enabled=false)public void TestNgLearn1() {System.out.println("this is TestNG test case1");}@Testpublic void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

 xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false"><test name="Test"><groups><incloud name="group1"></incloud><incloud name="group2"></incloud></groups><classes><class name="com.demo.test.testng.NewTest"/><class name="com.demo.test.testng.TestCase1"/></classes></test> <!-- Test -->
</suite> <!-- Suite -->

 运行结果如下:

beforeSuite
beforeTest
beforeClass
beforeGroups
beforeMethod
test1 from group1
afterMethod
beforeMethod
test11 from group1
afterMethod
afterGroups
beforeMethod
test2 from group2
afterMethod
afterClass
this is TestNG test case2
afterTest
afterSuite

如上所示,先运行了group1的两个用例,再运行group2的两条用例;
注意在xml标识group,需要将要运行的group加进来,同时还要将被标识这些group的class也加进来,不被加进去的不会运行

十、分suite测试

测试套件是用于测试软件程序的行为或一组行为的测试用例的集合。 在TestNG中,我们无法在测试源代码中定义一个套件,但它可以由一个XML文件表示,因为套件是执行的功能。 它还允许灵活配置要运行的测试。 套件可以包含一个或多个测试,并由<suite>标记定义。<suite>是testng.xml的根标记。 它描述了一个测试套件,它又由几个<test>部分组成。
下表列出了<suite>接受的所有定义的合法属性。

属性      描述
name    套件的名称,这是一个强制属性
verbose    运行的级别或详细程度,级别为0-10,其中10最详细
parallel    TestNG是否运行不同的线程来运行这个套件,默认为none,其他级别为methods、tests、classes、instances
thread-count    如果启用并行模式(忽略其他方式),则为使用的线程数
annotations    在测试中使用的注释类型
time-out    在本测试中的所有测试方法上使用的默认超时

十一、依赖测试

有时,我们可能需要以特定顺序调用测试用例中的方法,或者可能希望在方法之间共享一些数据和状态。 TestNG支持这种依赖关系,因为它支持在测试方法之间显式依赖的声明。
TestNG允许指定依赖关系:

在@Test注释中使用属性dependsOnMethods
在@Test注释中使用属性dependsOnGroups
除此之外依赖还分为hard依赖和soft依赖:

hard依赖:默认为此依赖方式,即其所有依赖的methods或者groups必须全部pass,否则被标识依赖的类或者方法将会被略过,在报告中标识为skip,如后面的范例所示,此为默认的依赖方式;
soft依赖:此方式下,其依赖的方法或者组有不是全部pass也不会影响被标识依赖的类或者方法的运行,注意如果使用此方式,则依赖者和被依赖者之间必须不存在成功失败的因果关系,否则会导致用例失败。此方法在注解中需要加入alwaysRun=true即可,如@Test(dependsOnMethods= {"TestNgLearn1"}, alwaysRun=true)


在TestNG中,我们使用dependOnMethods和dependsOnGroups来实现依赖测试。 且这两个都支持正则表达式,如范例三所示,如下为几个使用范例:

范例一,被依赖方法pass:

public class TestCase1 {@Test(enabled=true)public void TestNgLearn1() {System.out.println("this is TestNG test case1");}@Test(dependsOnMethods= {"TestNgLearn1"})public void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

运行结果:

this is TestNG test case1
this is TestNG test case2
PASSED: TestNgLearn1
PASSED: TestNgLearn2

 范例二,被依赖方法fail:

public class TestCase1 {@Test(enabled=true)public void TestNgLearn1() {System.out.println("this is TestNG test case1");Assert.assertFalse(true);}@Test(dependsOnMethods= {"TestNgLearn1"})public void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

 结果:

this is TestNG test case1
FAILED: TestNgLearn1
junit.framework.AssertionFailedErrorat junit.framework.Assert.fail(Assert.java:47)at junit.framework.Assert.assertTrue(Assert.java:20)at junit.framework.Assert.assertFalse(Assert.java:34)at junit.framework.Assert.assertFalse(Assert.java:41)at com.demo.test.testng.TestCase1.TestNgLearn1(TestCase1.java:26)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:104)at org.testng.internal.Invoker.invokeMethod(Invoker.java:645)at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:851)at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1177)at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:129)at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:112)at org.testng.TestRunner.privateRun(TestRunner.java:756)at org.testng.TestRunner.run(TestRunner.java:610)at org.testng.SuiteRunner.runTest(SuiteRunner.java:387)at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:382)at org.testng.SuiteRunner.privateRun(SuiteRunner.java:340)at org.testng.SuiteRunner.run(SuiteRunner.java:289)at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)at org.testng.TestNG.runSuitesSequentially(TestNG.java:1293)at org.testng.TestNG.runSuitesLocally(TestNG.java:1218)at org.testng.TestNG.runSuites(TestNG.java:1133)at org.testng.TestNG.run(TestNG.java:1104)at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:114)at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:251)at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:77)SKIPPED: TestNgLearn2

 范例三、group依赖:

如下所示,method1依赖group名称为init的所有方法:

@Test(groups = { "init" })
public void serverStartedOk() {}@Test(groups = { "init" })
public void initEnvironment() {}@Test(dependsOnGroups = { "init.*" })
public void method1() {}

 这里init这个group中的两个方法的执行顺序如果没有在xml中指明则每次运行的顺序不能保证

十二、参数化测试


TestNG中的另一个有趣的功能是参数化测试。 在大多数情况下,您会遇到业务逻辑需要大量测试的场景。 参数化测试允许开发人员使用不同的值一次又一次地运行相同的测试。
TestNG可以通过两种不同的方式将参数直接传递给测试方法:

使用testng.xml
使用数据提供者
下面分别介绍两种传参方式:


1、使用textng.xml传送参数


范例代码如下:

public class TestCase1 {@Test(enabled=true)@Parameters({"param1", "param2"})public void TestNgLearn1(String param1, int param2) {System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);Assert.assertFalse(false);}@Test(dependsOnMethods= {"TestNgLearn1"})public void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

 xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false"><test name="Test"><parameter name="param1" value="1011111" /><parameter name="param2" value="10" /><classes><class name="com.demo.test.testng.TestCase1"/></classes></test> <!-- Test -->
</suite> <!-- Suite -->

 运行xml,结果如下:

this is TestNG test case1, and param1 is:1011111; param2 is:10
this is TestNG test case2===============================================
Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

2、使用@DataProvider传递参数

此处需要注意,传参的类型必须要一致,且带有@DataProvider注解的函数返回的必然是Object[][],此处需要注意。
代码如下:

public class TestCase1 {@DataProvider(name = "provideNumbers")public Object[][] provideData() {return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };}@Test(dataProvider = "provideNumbers")public void TestNgLearn1(int param1, int param2) {System.out.println("this is TestNG test case1, and param1 is:"+param1+"; param2 is:"+param2);Assert.assertFalse(false);}@Test(dependsOnMethods= {"TestNgLearn1"})public void TestNgLearn2() {System.out.println("this is TestNG test case2");}
}

 运行此class,结果为:

this is TestNG test case1, and param1 is:10; param2 is:20
this is TestNG test case1, and param1 is:100; param2 is:110
this is TestNG test case1, and param1 is:200; param2 is:210
this is TestNG test case2
PASSED: TestNgLearn1(10, 20)
PASSED: TestNgLearn1(100, 110)
PASSED: TestNgLearn1(200, 210)
PASSED: TestNgLearn2

十三、XML配置文件说明

前面讲的大多都是以测试脚本为基础来运行的,少部分是以xml运行,这里以xml来讲解下

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="SuiteName" verbose="1" > 

如下分别讲解各个标签:

1、suite标签
testNG.xml文件的最外层标签即suite,即测试套件,其下可以有多个<test>和<groups>,其有几个可以添加的属性在第十节的分suite测试中有做说明,这里做下详细说明:

(1)、name属性
此属性属于必须要有的,值可以自行设定,此名字会在testNG的报告中看到

(2)、verbose属性
此属性为指定testNG报告的详细程度,从0开始到10,其中10为最详细,默认生成的xml此属性值为1

(3)、parallel属性
此属性是指代运行方式,默认为none,即串行运行方式;并行执行方法包括如下几种,下面做分别说明

methods:方法层级,若为此值,则该suite下所有的测试方法都将进行多线程,即测试用例级别的多线程。如果用例之间有依赖,则执行顺序会按照设定的依赖来运行

<suite name="My suite" parallel="methods" thread-count="5">

tests:TestNG将在同一线程中运行相同的<Test>标签中的所有方法,每个<test>标签都将处于一个单独的线程中,这允许您将不是线程安全的所有类分组在同一个<test>中,并保证它们都将在同一个线程中运行,同时利用TestNG使用尽可能多的线程运行测试。

<suite name="My suite" parallel="tests" thread-count="5">

classes:类级别并发,即TestNG会将该suite下每个class都将在单独的线程中运行,同一个class下的所有用例都将在同一个线程中运行 

<suite name="My suite" parallel="classes" thread-count="5">

instances:实例级别,即TestNG将在同一线程中运行同一实例中的所有方法,两个不同实例上的两个方法将在不同的线程中运行。 

<suite name="My suite" parallel="instances" thread-count="5">

(4)、thread-count属性
此属性用于指定线程数,按照需要输入,需要parallel参数非none时才可以添加

(5)、annotations属性
此项为注解的级别,为methods级别和class级别,一般不用设置

(6)、time-out属性
此属性用于指定超时时间,该suite下所有的用例的超时时间

(7)、group-by-instances属性
此项用于那些有依赖的方法,且被依赖的对象有多个重载对象,因为如果是依赖方法,且该方法有多个重载方法,则默认是会将所有重载方法都跑完再运行被依赖方法,但有时候我们不想这样,则将此项设置为true即可

(8)、preserve-order属性
值可输入true或者false,如果为true,则用例执行会按照在xml中的顺序执行,否则会乱序执行,不添加此属性的话默认是按顺序执行的

2、test标签


此标签无特别意义,其下可以包括多个标签,如groups、classes等,如下介绍下几种书写方式:

1)选择一个包中的全部测试脚本(包含子包)

<test name = "allTestsInAPackage" ><packages><package name = "whole.path.to.package.* /></packages>
</test>

2)选择一个类中的全部测试脚本 

<test name = "allTestsInAClass" ><classes><class name="whole.path.to.package.className /></classes>
</test>

 3)选择一个类中的部分测试脚本

<test name = "aFewTestsFromAClass" ><classes><class name="whole.path.to.package.className ><methods><include name = "firstMethod" /><include name = "secondMethod" /><include name = "thirdMethod" /></methods></class></classes>
</test>

 4)选择一个包中的某些组

<test name = "includedGroupsInAPackage" ><groups><run><include name = "includedGroup" /></run></groups><packages><package name = "whole.path.to.package.* /></packages>
</test>

5)排除一个包中的某些组 

<test name = "excludedGroupsInAPackage" ><groups><run><exclude name = "excludedGroup" /></run></groups><packages><package name = "whole.path.to.package.* /></packages>
</test>

其可以附带的属性有如下几种,下面对各个属性做单独说明:

(1) name属性
此属性属于必须要有的,值可以自行设定,此名字会在testNG的报告中看到

(2) verbose属性
此属性为指定testNG报告的详细程度,从0开始到10,其中10为最详细,默认生成的xml此属性值为1

(3) threadPoolSize属性
该属性指定此test的线程池大小,为数字

@Test(threadPoolSize = 3, invocationCount = 10,  timeOut = 10000)
public void testServer() {
}

(4)、invocationCount属性
该属性指定此test的运行次数,为数字,范例如上面的代码所示

(5)、time-out属性
此属性用于指定超时时间,该suite下所有的用例的超时时间,范例如上面的代码所示

(6)、group-by-instances属性
此项用于那些有依赖的方法,且被依赖的对象有多个重载对象,因为如果是依赖方法,且该方法有多个重载方法,则默认是会将所有重载方法都跑完再运行被依赖方法,但有时候我们不想这样,则将此项设置为true即可

<suite name="Factory" group-by-instances="true">

(7)、preserve-order属性
值可输入true或者false,如果为true,则用例执行会按照在xml中的顺序执行,否则会乱序执行,不添加此属性的话默认是按顺序执行的

3、group标签


此标签必然是在<test>标签下的,用于标识那些组会被用于测试或者被排除在测试之外,其同级必然要包含一个<classes>标签或者<pakages>标签,用于指定groups来自于哪些包或者类;
如下即为包含一个group,排除一个group的例子

<groups><run><include name = "includedGroupName" /><exclude name = "excludedGroupName" /></run>
</groups>

 高级应用:

<test name="Regression1"><groups><define name="functest"><include name="windows"/><include name="linux"/></define><define name="all"><include name="functest"/><include name="checkintest"/></define><run><include name="all"/></run></groups><classes><class name="test.sample.Test1"/></classes>
</test>

4、其他

其他的话就是测试脚本的选择了,有三种方式:

1)选择一个包

<packages><package name = "packageName" />
</packages>

2)选择一个类

<classes><class name = "className" />
</classes>

3)选择一个方法

<classes><class name = "className" /><methods><include name = "methodName" /></methods></class>
</classes>

这里也支持正则表达式,例如: 

<test name="Test1"><classes><class name="example1.Test1"><methods><include name=".*enabledTestMethod.*"/><exclude name=".*brokenTestMethod.*"/></methods></class></classes>
</test>

十四、TestNG报告

默认报告输出位置为当前工程的test-output文件夹下,包括xml格式和html格式。
如果想将报告输出位置换个地方,则修改地方在如下图所示位置:

修改输出位置

 如果想要美化报告,则按照如下步骤:

1、配置:Eclipse --> Window --> Preferences -->testng
2、勾选Disable default listeners
3、在Pre Defined Listeners 输入框中输入org.uncommons.reportng.HTMLReporter


记得在POM上添加如下代码:

<dependency><groupId>org.uncommons</groupId><artifactId>reportng</artifactId><version>1.1.4</version><scope>test</scope><exclusions><exclusion><groupId>org.testng</groupId><artifactId>testng</artifactId></exclusion></exclusions>
</dependency>
<dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>3.0</version><scope>test</scope>
</dependency>

不然无法运行的。
如上图所示,还可以自定义testng.xml的模板,并在上图中指定。


http://chatgpt.dhexx.cn/article/110J3aVX.shtml

相关文章

TestNG单元测试框架详解

目录 前言 ​1. TestNG使用流程 1.1TestNG安装 1.2 创建Maven项目 1.3 Maven配置 1.4 项目TestNG测试类 1.5 运行TestNG 2、TestNG常用注解 3.xml方式运行 3.1 鼠标右击testng.xml运行 3.1 使用maven运行 4. 常用的断言&#xff08;assert&#xff09; 5. TestNG预…

使用ZRender类库画直线、圆弧、曲线以及点在线上的运动

最近在学习Zrender类库&#xff0c;并利用Zrender 让点在直线、圆弧、曲线上运动。大概的写了一些. Zrender是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器. 这里我运用的是Canvas画布去画的.想了解Zrender内的属性&…

js画图插件-zrender

zrender&#xff08;Zlevel Render&#xff09; 是一个轻量级的Canvas类库&#xff0c;MVC封装&#xff0c;数据驱动&#xff0c;提供类Dom事件模型&#xff0c;让canvas绘图大不同&#xff01; MVC核心封装实现图形仓库、视图渲染和交互控制&#xff1a; Stroage(M) : shape数…

ZRender文档研读

ZRender文档研读 (基于4.3.2版本) 不使用最新的5.x.x的版本是因为线上文档和最新版本JS文件不匹配-2022年6月13日 1、文档地址 1、官方文档的地址&#xff1a;https://ecomfe.github.io/zrender-doc/public/api.html#zrenderdisplayable 2、Github地址&#xff1a;https://git…

React Developer Tools 下载

React Developer Tools 下载 方法一&#xff1a;网页扩展工具 搜索 React Developer Tools 下载&#xff08;若浏览器不支持搜索React &#xff0c;行不通&#xff09; 打开chrome 浏览器 (只有 chrome 支持 React Developer Tools&#xff09;点击网页工具栏 右上方 确认添…

zrender TypeError: “x“ is not a constructor

如果有兴趣了解更多相关内容&#xff0c;欢迎来我的个人网站看看&#xff1a;耶瞳空间 我是调用zrender的init方法报错&#xff0c;如下图&#xff1a; 然后经过大佬指点&#xff0c;这种开发环境没问题但生产环境报错的东西&#xff0c;一般是因为打包的时候被tree-shaking…

vue+zrender实现医院体温单

项目背景 医院医护项目需求&#xff0c;需要用H5做一个通用的体温单 项目演示 版本一 版本二 项目代码简介 由vue-cli4脚手架快速搭建生成&#xff0c;主要代码都在thermometer.vue文件里面&#xff0c;后续修改也主要是在这个文件修改。 项目需求难点在中间的网格部分…

ZRender开发

ZRender开发 开发文档&#xff1a;https://ecomfe.github.io/zrender-doc/public/ <!-- eslint-disable no-undef --> <template><div class"config-page"><div class"header"><el-button click"handleAdd">撒…

Echarts 源码解读 一:zrender源码分析1var zr = zrender.init(document.getElementById(‘main‘));

2021SCSDUSC 因为Echarts是基于zrender进行实现的&#xff0c;所以解读echarts源码前&#xff0c;首先要对zrender有基本的了解。 zrender是canvas的一个类库&#xff0c;zrender是基于canvas实现的。 目录 zrender的src文件夹 文件夹&#xff1a; animation动画相关 cont…

高效canvas绘图框架——zrender

一个轻量级的Canvas类库&#xff0c;MVC封装&#xff0c;数据驱动&#xff0c;提供类Dom事件模型&#xff0c;让canvas绘图大不同 Architecture MVC核心封装实现图形仓库、视图渲染和交互控制&#xff1a; Stroage(M) : shape数据CURD管理Painter(V) : canvase元素生命周期管理…

轻量级的Canvas类库zrender使用笔记 :简单自定义图件开发

ECharts&#xff0c;一个纯 Javascript 的图表库&#xff0c;底层依赖轻量级的 Canvas 类库 ZRender&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可高度个性化定制的数据可视化图表。当然我们自己可能有些需求&#xff0c;通过修改ECharts或者highchar…

vue-echarts的ZRender事件

首先贴出 vue-echarts 的官网连接&#xff1a;https://www.npmjs.com/package/vue-echarts 1、vue-echarts 具体在vue中的使用方法&#xff0c;本文中就暂时不多介绍了&#xff1b; 2、如何在vue中使用vue-echarts的鼠标事件&#xff1a; 具体使用方式跟vue中使用echarts一样&a…

ZRender文档研读 (基于4.3.2版本)

ZRender文档研读 &#xff08;基于4.3.2版本&#xff09; 不使用最新的5.x.x的版本是因为线上文档和最新版本JS文件不匹配-2022年6月13日 1、文档地址 1、官方文档的地址&#xff1a;https://ecomfe.github.io/zrender-doc/public/api.html#zrenderdisplayable 2、Github地址…

【ZRender 渲染引擎 - 贰】 | Vue 框架集成与绘制其他图元

theme: cyanosis 持续创作&#xff0c;加速成长&#xff01;这是我参与「掘金日新计划 10 月更文挑战」的第 8 天&#xff0c;点击查看活动详情 1. Vue 中使用 ZRender 上一篇中&#xff0c;我们通过最原始的方式体验了一下 ZRender 的使用。接下来&#xff0c;为了更方便管理…

zrender实现图形缩放功能

zrender实现图形缩放功能 一、绘制一个矩形图 <div id"main-container"></div>#main-container {width: 500px;height: 300px;border: 1px solid #888; }import * as zrender from zrenderconst container document.querySelector(#main-container) c…

ECharts 3.0底层zrender 3.x源码分析1-总体架构

zrender是一个轻量级的Canvas类库&#xff0c;作为百度Echarts 3.0的底层基础。截至目前查看的zrender源码和文档&#xff0c;包括官网文档都还停留在2.x时代&#xff0c;我打算用一个系列介绍下zrender 3.x的使用和源码&#xff0c;一些demo和没有在博客中介绍的源码请进我的g…

ZRender (Canvas)简单使用(拖拽、缩放、旋转、文字、层级)

一、ZRender 是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器&#xff1b; 二、下面是以图片做的简单demo&#xff0c;分为左中右三部分&#xff0c;左边是需要的图片&#xff0c;中间是绘图部分&#xff0c;右边是添加文字…

源码解读之zrender-ZRender 类(3)

00 小结 当我们在 zrender.init(document.getElementById(“canvas”))时&#xff0c;首先实例化了一个 ZRender 实例&#xff0c;在这个实例化过程中&#xff0c;主要实例化了&#xff1a; Storage 类&#xff0c;作用类似于全局状态管理Painter 类&#xff0c;可以理解为画…

【ZRender 渲染引擎 - 壹】 | 基础图形元素绘制

theme: cyanosis 持续创作&#xff0c;加速成长&#xff01;这是我参与「掘金日新计划 10 月更文挑战」的第 7 天&#xff0c;点击查看活动详情 开篇前言 在掘金认识我的都知道&#xff0c;我主要是研究 Flutter 的。其实我一直希望开发出一套好用的 Flutter 的图表库&#xf…

zrender学习

这个是项目总结&#xff0c;不适合学习 <div id"canvas" style"background-image:url(./canvasbg.gif)"></div> 定义zrender初始化对象&#xff0c;背景是一个gif图 样式如下 ↓ 工程里&#xff0c; topo.html <div id "containe…