testng教程
TestNG is a testing framework for Java application that is inspired from JUnit and NUnit.
TestNG是一个受JUnit和NUnit启发的Java应用程序测试框架。
测试NG (TestNG)
TestNG provides many features that makes it easy to write and run test cases:
TestNG提供了许多功能,使编写和运行测试用例变得容易:
- Annotation based 基于注释
- Plugins for major IDEs such as Eclipse and IDEA. 适用于主要IDE(例如Eclipse和IDEA)的插件。
- Automatically creation of test suites 自动创建测试套件
- HTML based report generation 基于HTML的报告生成
- Ability to run single test method using IDE plugins. 能够使用IDE插件运行单一测试方法。
- Data driven testing using
@DataProvider
使用@DataProvider
数据驱动的测试 - No additional dependencies to run and logging 无需其他依赖来运行和记录
- TestNG XML file to run test suites with different configurations TestNG XML文件以运行具有不同配置的测试套件
TestNG Maven依赖 (TestNG Maven Dependency)
TestNG libraries are present on maven repository, you can add below maven dependency to include TestNG in your project.
TestNG库存在于maven存储库中,您可以在maven依赖项下面添加以在您的项目中包含TestNG。
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
TestNG Eclipse插件 (TestNG Eclipse Plugin)
I am using Eclipse for TestNG example project, so let’s first install TestNG Eclipse plugin.
我正在使用Eclipse for TestNG示例项目,因此让我们首先安装TestNG Eclipse插件。
Go to “Eclipse Marketplace” and search for “TestNG”.
转到“ Eclipse Marketplace”并搜索“ TestNG”。
Click on “Install” and go through further screens to install it. You will have to accept its license agreement and restart Eclipse once installation is finished.
单击“安装”,然后通过其他屏幕进行安装。 安装完成后,您将必须接受其许可协议并重新启动Eclipse。
Go to “Window | Show View | Other” and inside “Java” you should see “TestNG”.
转到“窗口| 显示视图 其他”和“ Java”中,您应该看到“ TestNG”。
This means that TestNG for Eclipse is successfully installed and we are ready to create our TestNG test classes.
这意味着TestNG for Eclipse已成功安装,并且我们准备创建TestNG测试类。
创建TestNG类 (Create TestNG Class)
Go to your project in the explorer and click on “New | Other” and select “TestNG Class” and click Next.
在资源管理器中转到您的项目,然后单击“新建| 其他”,然后选择“ TestNG类”,然后单击“下一步”。
In next screen, we have to specify our TestNG class configurations and select annotations to include in the class and click on Finish button.
在下一个屏幕中,我们必须指定我们的TestNG类配置,并选择要包括在类中的注释,然后单击“完成”按钮。
This will generate TestNG skeleton class like below.
这将生成如下的TestNG骨架类。
package com.journaldev.utils;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
public class TestUtils {
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
}
@BeforeMethod
public void beforeMethod() {
}
@AfterMethod
public void afterMethod() {
}
@DataProvider
public Object[][] dp() {
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
};
}
@BeforeClass
public void beforeClass() {
}
@AfterClass
public void afterClass() {
}
@BeforeTest
public void beforeTest() {
}
@AfterTest
public void afterTest() {
}
@BeforeSuite
public void beforeSuite() {
}
@AfterSuite
public void afterSuite() {
}
}
That’s it, we can run our basic TestNG class by going to “Run As | TestNG Test” as shown in below image.
就这样,我们可以通过运行“ Run As | TestNG测试”,如下图所示。
Since our test class has nothing, it should pass all tests. You can check “Console” for the logs generated and “TestNG View” will show you basic details of your test run.
由于我们的测试类没有任何内容,因此它应该通过所有测试。 您可以检查“控制台”中生成的日志,“ TestNG View”将向您显示测试运行的基本详细信息。
TestNG测试套件流程 (TestNG Test Suite Flow)
I have added some console logging in the annotated methods to understand the flow of TestNG test run.
我在带注释的方法中添加了一些控制台日志记录,以了解TestNG测试运行的流程。
package com.journaldev.utils;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterSuite;
public class TestUtils {
@Test(dataProvider = "dp")
public void f(Integer n, String s) {
System.out.println("Inside @Test");
}
@BeforeMethod
public void beforeMethod() {
System.out.println("Inside @BeforeMethod");
}
@AfterMethod
public void afterMethod() {
System.out.println("Inside @AfterMethod");
}
@DataProvider
public Object[][] dp() {
System.out.println("Inside @DataProvider");
return new Object[][] {
new Object[] { 1, "a" },
new Object[] { 2, "b" },
};
}
@BeforeClass
public void beforeClass() {
System.out.println("Inside @BeforeClass");
}
@AfterClass
public void afterClass() {
System.out.println("Inside @AfterClass");
}
@BeforeTest
public void beforeTest() {
System.out.println("Inside @BeforeTest");
}
@AfterTest
public void afterTest() {
System.out.println("Inside @AfterTest");
}
@BeforeSuite
public void beforeSuite() {
System.out.println("Inside @BeforeSuite");
}
@AfterSuite
public void afterSuite() {
System.out.println("Inside @AfterSuite");
}
}
When I run it again, below console logs are generated.
当我再次运行它时,在控制台日志下面生成。
[RemoteTestNG] detected TestNG version 6.14.3
Inside @BeforeSuite
Inside @BeforeTest
Inside @BeforeClass
Inside @DataProvider
Inside @BeforeMethod
Inside @Test
Inside @AfterMethod
Inside @BeforeMethod
Inside @Test
Inside @AfterMethod
Inside @AfterClass
Inside @AfterTest
PASSED: f(1, "a")
PASSED: f(2, "b")
===============================================
Default test
Tests run: 2, Failures: 0, Skips: 0
===============================================
Inside @AfterSuite
===============================================
Default suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
Based on above output, we can deduce the flow of TestNG test as:
根据上面的输出,我们可以推断出TestNG测试的流程为:
BeforeSuite -> BeforeTest -> BeforeClass -> DataProvider ->
{ BeforeMethod -> Test -> AfterMethod } * N
-> AfterClass -> AfterTest -> AfterSuite
N is the number of times our test method is executed and it depends on the number of inputs generated by @DataProvider
method.
N是测试方法执行的次数,它取决于@DataProvider
方法生成的输入数。
We can use @BeforeXXX
methods for some preprocessing and initialize resources that we want to use in the test suite. Similarly, we can use @AfterXXX
methods for post-processing and closing resources.
我们可以使用@BeforeXXX
方法进行一些预处理,并初始化要在测试套件中使用的资源。 同样,我们可以使用@AfterXXX
方法进行后处理和关闭资源。
TestNG教程 (TestNG Tutorial)
Now that we have gone through the basics of TestNG and set it up in Eclipse, let’s create a class with few methods and use TestNG to run some test cases on it.
现在,我们已经了解了TestNG的基础知识并在Eclipse中进行了设置,让我们创建一个几乎没有方法的类,并使用TestNG在其上运行一些测试用例。
package com.journaldev.utils;
public class Utils {
public static String NAME = "";
public int add(int x, int y) {
return x + y;
}
public int subtract(int x, int y) {
return x - y;
}
public static void setName(String s) {
System.out.println("Setting NAME to " + s);
NAME = s;
}
}
I have added few public methods, static and void methods too. Below is my TestNG class to test these methods.
我还添加了一些公共方法,静态方法和无效方法。 下面是我的TestNG类,用于测试这些方法。
package com.journaldev.utils;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestUtils {
@Test(dataProvider = "dp")
public void test_add(Integer x, Integer y) {
Utils u = new Utils();
Assert.assertEquals(u.add(x, y), x + y);
}
@Test(dataProvider = "dp")
public void test_subtract(Integer x, Integer y) {
Utils u = new Utils();
Assert.assertEquals(u.subtract(x, y), x - y);
}
@Test(dataProvider = "dpName")
public void test_setName(String s) {
Utils.setName(s);
Assert.assertEquals(Utils.NAME, s);
}
@DataProvider
public Object[][] dp() {
return new Object[][] { new Object[] { 1, 1 }, new Object[] { 2, 2 }, };
}
@DataProvider
public Object[][] dpName() {
return new Object[][] { new Object[] { "Utils" }, new Object[] { "MyUtils" }, };
}
}
Now when we run above class as TestNG Test, we get following output in console.
现在,当我们在类上方运行TestNG Test时,将在控制台中获得以下输出。
[RemoteTestNG] detected TestNG version 6.14.3
Setting NAME to Utils
Setting NAME to MyUtils
PASSED: test_add(1, 1)
PASSED: test_add(2, 2)
PASSED: test_setName("Utils")
PASSED: test_setName("MyUtils")
PASSED: test_subtract(1, 1)
PASSED: test_subtract(2, 2)
===============================================
Default test
Tests run: 6, Failures: 0, Skips: 0
===============================================
===============================================
Default suite
Total tests run: 6, Failures: 0, Skips: 0
===============================================
Refresh the project and you will see a newly generated directory test-output
.
刷新项目,您将看到一个新生成的目录test-output
。
Open index.html
in any browser and you should see HTML report like below image.
在任何浏览器中打开index.html
,您应该看到如下图所示HTML报告。
TestNG XML套件 (TestNG XML Suite)
One of the best part of TestNG is the auto generation of test suite xml file.
TestNG最好的部分之一是自动生成测试套件xml文件。
We can edit it and add parameters to it, we can use it to run a single test method too. TestNG XML suite provides a lot of options and it’s very useful when you want to run a test case through the command line, such as on server with no Eclipse. We can run the TestNG test suite xml file using below command:
我们可以对其进行编辑并添加参数,也可以使用它来运行单个测试方法。 TestNG XML套件提供了很多选项,当您想通过命令行运行测试用例时(例如在没有Eclipse的服务器上),它非常有用。 我们可以使用以下命令运行TestNG测试套件xml文件:
$java com.journaldev.utils.TestUtils testng.xml
TestNG XML is a very vast topic, if you want to explore more then go through its documentation.
TestNG XML是一个非常广泛的主题,如果您想探索更多内容,请阅读其文档 。
TestNG运行单一测试方法 (TestNG Running Single Test Method)
We can run a single test method too, this is very helpful when our test class has many methods and we are interested in only to test a few of them.
我们也可以运行一个测试方法,当我们的测试类有很多方法并且我们只想测试其中一些方法时,这将非常有用。
TestNG测试失败 (TestNG Testing with Failures)
Let’s see what happens when a bug is introduced in our code, change the Utils
class setName
method as below.
让我们看看在代码中引入错误时会发生什么,如下更改Utils
类的setName
方法。
public static void setName(String s) {
System.out.println("Setting NAME to " + s);
// NAME = s; //introducing bug intentionally
}
Now when we run the test class again, we get following output in console.
现在,当我们再次运行测试类时,将在控制台中获得以下输出。
[RemoteTestNG] detected TestNG version 6.14.3
Setting NAME to Utils
Setting NAME to MyUtils
FAILED: test_setName("Utils")
java.lang.AssertionError: expected [Utils] but found []
at org.testng.Assert.fail(Assert.java:96)
at org.testng.Assert.failNotEquals(Assert.java:776)
at org.testng.Assert.assertEqualsImpl(Assert.java:137)
at org.testng.Assert.assertEquals(Assert.java:118)
at org.testng.Assert.assertEquals(Assert.java:453)
at org.testng.Assert.assertEquals(Assert.java:463)
at com.journaldev.utils.TestUtils.test_setName(TestUtils.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
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)
FAILED: test_setName("MyUtils")
java.lang.AssertionError: expected [MyUtils] but found []
at org.testng.Assert.fail(Assert.java:96)
at org.testng.Assert.failNotEquals(Assert.java:776)
at org.testng.Assert.assertEqualsImpl(Assert.java:137)
at org.testng.Assert.assertEquals(Assert.java:118)
at org.testng.Assert.assertEquals(Assert.java:453)
at org.testng.Assert.assertEquals(Assert.java:463)
at com.journaldev.utils.TestUtils.test_setName(TestUtils.java:23)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
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)
Did you noticed that I am running test only on setName method.:)
您是否注意到我仅在setName方法上运行测试。:)
从命令行运行TestNG测试 (Running TestNG Tests from Command Line)
It’s good that we can run our test cases from Eclipse, but most of the times we want to run all the test cases of the project when building the project. Well, maven automatically runs the test cases for us. Below images show output of mvn clean install
command.
可以从Eclipse运行我们的测试用例是一件好事,但是大多数时候,我们希望在构建项目时运行项目的所有测试用例。 好吧,Maven会自动为我们运行测试用例。 下图显示了mvn clean install
命令的输出。
Success Case
成功案例
Failure Case
失败案例
TestNG测试用例顺序 (TestNG Test Cases Order)
TestNG test cases are run in the order of their method names. So in our case the order of execution would be: test_add -> test_setName -> test_subtract
.
TestNG测试用例按其方法名称的顺序运行。 因此,在本例中,执行顺序为: test_add -> test_setName -> test_subtract
。
We can change the order by setting the priority
of test methods. If we want the order of execution as test_add -> test_subtract -> test_setName
then we can change our @Test annotation like below.
我们可以通过设置测试方法的priority
来更改顺序。 如果我们希望执行顺序为test_add -> test_subtract -> test_setName
则可以如下更改@Test批注。
@Test(dataProvider = "dp", priority=1)
public void test_add(Integer x, Integer y) {
}
@Test(dataProvider = "dp", priority=2)
public void test_subtract(Integer x, Integer y) {
}
@Test(dataProvider = "dpName", priority=3)
public void test_setName(String s) {
}
Notice that lower priority methods are executed first.
请注意,优先级较低的方法会先执行。
摘要 (Summary)
TestNG is a very popular unit testing framework and I really liked that it’s very easy to setup and use in the project. We explored basics of TestNG and looked into most common examples to use it in our project.
TestNG是一个非常流行的单元测试框架,我非常喜欢它在项目中易于设置和使用。 我们探索了TestNG的基础,并研究了最常见的示例以在我们的项目中使用它。
testng教程