工欲善其事, its prerequisite
The importance of unit testing is self-evident. But without good unit testing tools, it is impossible to arouse the desire of developers.
TestNG is one of the sharp tools. TestNG is a pioneer in the annotation-based testing framework that overcomes some of the shortcomings of JUNIT3 by adding features such as flexible devices, test classifications, parameter testing, and dependency methods. Below I will summarize some important features of testng.
About Testng.xml
Testng.xml is a file that records all tests in XML. It describes the run-time definition of the test suite and is also the largest unit of work for running tests in testng. Although there are no testng.xml files, testing is easy to implement. But as the test code grows, Testng.xml provides a convenient way to store all runtime configurations, such as setting classes, tests, methods, parameters, grouping inclusions and exclusions, and so on. It becomes very important to test the class more and more.
The main structure of Testing.xml
Root tag is <suite>
<suite> tags contain one or more <test> tags
<test> tags contain one or more <classes> tags
<classes> tags contain one or more <method> tags
In general, most files are detailed to the <classes> tag.
Extra tags for testing.xml
<packages> and <package>: As the name implies, they can specify a set of Java packages, which can also include <include> or exclude <exclude> attributes in this tag.
<parameter> defines the parameter names and values, which are used in conjunction with the @parameters comments in the test class, similar in function and @dataprovider, provide external parameters, function less powerful than @dataprovider, have limitations.
<suite-files> and <suite-file>: It is used to introduce other testng.xml files that will be executed together with the current file.
<groups>,<define> and <run>: These three tags are used in conjunction to specify or exclude a subset of the groupings at execution time, as an example is shown:
XML code
- <groups>
- <define name= "All" >
- <include name= "Test1"/>
- <exclude name= "Test2"/>
- </define>
- <run>
- <include name= "All"/>
- </run>
- <groups>
Note The default order for performing tests is performed in the order given in Testng.xml. If you do not want to do this in this order, use the Preserve-order property to specify false. such as <test name= "Regression1" preserve-order= "false" >. For a detailed description of the Testng.xml label, see the official documentation for Testng.xml.
In the actual development, I suggest testng.xml to the granularity of the function points for the division. The configuration of each function point is then aggregated with the total testng.xml.
Parameter passing
TestNG improves the disadvantage of the traditional test framework's inability to pass parameters, and it provides the simplest two ways to test the method of passing parameters:
1, add the @parameters label to the test method, and then give the parameter in Testng.xml.
2, specify @dataproviders.
The disadvantage of the first approach is obvious, it only supports Java primitives, and when constructing values, it is not possible to include the calculation logic to get the required parameters.
The second way to test the method is to pass any valid Java type. We prefer the second method to construct the parameters.
Here we introduce a way to pass parameters: Factory note @factory, which differs from the previous two parameter passes.
Let's review the common TestNG test, which is a parameterless construction method (the default constructor method, which cannot accept parameters). The emergence of @Factory is precisely the remedy for this shortcoming. The @Factory method is first checked and executed at execution time and executed only once. Returns an object array after execution. The content of the object in this array is the instance of the current test method with a constructor function. While using @factory, the test class also has a constructor that corresponds to parameters, and @Factory provides help in the form of parameters that are provided as constructors.
dependencies and grouping of tests
We are describing dependencies with groupings, because they have a strong connection.
Test dependencies
The dependency between test methods is a common requirement, and you might think that the dependencies between tests do not undermine the isolation between test methods? It is true, but sometimes for this isolation, there is a great price to simulate each other in the test method of isolation, so for the sake of convenience, TESTNG provides this way of dependency.
In TestNG, the dependency on methods and groupings is achieved through the @test attribute dependsonmethods,dependsongroups.
Dependencies also include soft dependencies and hard dependencies. A hard dependency is a strong association, and if a dependent test fails, then the tests that depend on it are skipped. Soft dependencies are not skipped. Soft dependencies are achieved by setting alwaysrun=true for @test. When using dependencies, it is important to avoid cyclic dependencies
Test grouping
The group name provided in testing is somewhat similar to the concept in Java, where classes containing similar points are grouped into groups.
The most important goal of grouping is to make a clear separation between the fixed test code and what tests are performed. When you need to specify which groups of tests to perform, specify the group when dynamic execution occurs.
The syntax for grouping is very simple, @Test, @BeforeClass, @AfterClass, @BeforeMethod and so on can belong to a group. The associated syntax is @test (groups= "group1"), and a @test groups can also specify multiple group names, such as @test (groups= "GROUP1,GROUPS2").
A defined group name, in fact, is used for the runtime, that is, in the Testng.xml file can be configured. The use of <groups> is mentioned in the previous Testng.xml description.
Group organizations can be divided according to various dimensions, such as unit testing, integration testing, performance testing. or frame layering to divide such as Action,service,dao. In the configuration file, you can also define groups in groups, which are implemented by define tags, as described earlier.
In a general project, I suggest that group classifications can be defined in terms of schema layering, divided into basic functions, service services, and DAO layers.
Expectedexceptions
There are two advantages to using Expectedexceptions to test for exceptions: first, it eliminates the interference that the Try/catch statement brings to the code. The second is to make the test code express the intention more clearly. As long as you see the expectedexceptions attribute defined in the @test annotation, you know the intent of the test method and divide the use case of exception and the intended business function into different test methods.
The syntax is simple, @Test (expectedexceptions= "Xxxexception.class"), the exception class can have multiple, separated by commas.
Asynchronous and concurrency Testing
Asynchronous and concurrency are often difficult in unit testing.
With regard to asynchronous tests such as JMS, send and receive are decoupled, and if you are testing a method of sending a message, there will be a return value when the response is received. According to this scenario, the test code is usually this:
Java code
- Private volatile Boolean success= "false";
- @Test (groups= "send")
- public void SendMessage () {
- Send Message code
- }
- @Test (timeout=10000,invocationcount=1000,successpercentage=98,dependsongroups={"Send"})
- public void Waitforanser () {
- while (!success) {
- Thread.Sleep (1000);
- }
- }
@Test (TimeOut = 10000, Invocationcount = 1000,successpercentage = 98), is the value set for testing the system's availability and response speed. This tells TestNG to call the method 1000 times, if 98% of the call is successful, it is considered to pass the test. Of course, you should also call the SendMessage method 1000 times before. Timeout is created to prevent deadlocks.
Testing has built-in support for concurrency and can be divided into two
1, concurrency Test
TestNG provides a threadpoolsize,invocationcount and timeout of three properties to complete when doing concurrency testing. ThreadPoolSize can specify multiple thread pools to execute test methods.
2, concurrent execution of tests
Testing can also be set up for concurrent execution through Testng.xml. Testng.xml default is single-threaded execution.
The <suite> tab can set the parallel property. Thread-count the specified number of threads
Parallel= "Methods": each test method executes in its own thread (in method granularity).
Parallel= "tests": all test methods within a <test> tag are executed in its own thread (in <test> granularity).
Unit Test Framework TESTNG Usage Summary