Java automation test framework - 04 - Test Method of TestNG

Keywords: Java xml MySQL JDK

From: https://www.cnblogs.com/du-hong/p/11718894.html

brief introduction

According to the plan in the previous article, this one will share the test method with the kids.

1, Set parameters

Test methods can have Parameters. Each test method can have any number of Parameters, and you can pass the correct Parameters to the method by using TestNG's @ Parameters.

There are two ways to set it up: use testng.xml or Data Providers.

(1) Setting parameters using testng.xml

This approach allows us to define simple parameters in the testng.xml file and then reference them in the source file.

1. If only relatively simple parameters are used, you can specify them in testng.xml file:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Parameters({ "first-name" })  
@Test  
public void testSingleString(String firstName) {   
  System.out.println("Invoked testString " + firstName);  
  assert "Cedric".equals(firstName);  
}

 

In this code, we let the first name parameter receive a value called the first name parameter in the XML file. This XML parameter is defined in testng.xml:

<suite name="My suite">  
  <parameter name="first-name"  value="Cedric"/>  
  <test name="Simple example">

Similarly, it can also be used on @ Before/After and @ Factory annotations:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Parameters({ "datasource", "jdbcDriver" })  
@BeforeMethod  
public void beforeTest(String ds, String driver) {  
  m_dataSource = ...;                              // Query the value of the data source  
  m_jdbcDriver = driver;  
}

There are two this time Java The parameters ds and driver receive the values specified from the properties datasource and jdbc driver, respectively.

2. Parameters can also be declared through Optional comments:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Parameters("db")  
@Test  
public void testNonExistentParameter(@Optional("mysql") String db) { ... }

If "db" is not found in your testng.xml file, your test method will use the value in @ Optional:“ MySQL".

3.@Parameters can be placed in the following positions:

(1) In any place annotated by @ Test, @Before/After or @ Factory.

(2) In the test class, at most one constructor tag can be placed. In this way, TestNG can instantiate this class with specific parameters in testng.xml when necessary. This feature can be used to initialize values in some classes for later use by other methods in the class.

be careful:

Parameters in XML will be mapped in the order in which Java parameters appear in the annotations, and TestNG will report an error if the number does not match.

Parameters are scoped. In testng.xml, you can declare either under the < suite > tag or under < test >. If both parameters have the same name, the one defined in < test > has priority. This is convenient when you need to override the values of certain parameters in some tests.

(2) Using DataProviders to provide parameters

Specifying parameters in testng.xml may have the following disadvantages:

1. If you don't use testng.xml at all

2. You need to pass complex parameters, or create parameters from Java (complex object, etc read from property file or database...) or specify parameters in testng.xml may not be enough

In this way, you can use the Data Provider to provide parameters for the required tests. The so-called Data Provider is a method that can return an array of objects, and this method is annotated by @ DataProvider annotation:

DataProvider is defined as follows:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@DataProvider(name = "range-provider")  
public Object[][] rangeData() {  
    int lower = 5;  
    int upper = 10;  
    return new Object[][] {  
    { lower-1, lower, upper, false },  
    { lower, lower, upper, true },  
    { lower+1, lower, upper, true },  
    { upper, lower, upper, true},  
    { upper+1, lower, upper, false },  
    };  
}

The DataProvider is called as follows:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Test(dataProvider = "range-provider")  
public void testIsBetween(int n, int lower,int upper, boolean expected){  
    println("Received " + n + " " + lower + "-"+ upper + " expected: " + expected);  
    Assert.assertEquals(expected, isBetween(n, lower, upper));  
}

The method annotated by @ Test indicates its data provider through the dataProvider property. This name must match the name in @ DataProvider(name =... ").

DataProvider returns a two-dimensional array of objects. Each one-dimensional array in the two-dimensional array will be passed to the calling function as a parameter. When running, it will be found that the number of times the test method identified by @ Test has been executed is the same as the number of one-dimensional arrays contained in object [] [], and the number of parameters of the function identified by @ Test is the same as the number of elements in the one-dimensional array within the object.

The output after operation is as follows:

Received 4 5-10expected: false

Received 5 5-10expected: true

Received 6 5-10expected: true

Received 10 5-10expected: true

Received 11 5-10expected: false

 

===============================================

Parameter Suite

Total tests run: 5,Failures: 0, Skips: 0

===============================================

 

(3) DataProviders extension

By default, the data provider looks up the current test class or the base class of the test class. If you want it to be used by other classes, you need to specify it as static and the class to be used through the dataProviderClass property:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automated test framework-03 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
public static class StaticProvider {  
    @DataProvider(name = "create")  
    public static Object[][] createData() {  
        return new Object[][] {  
          new Object[] { new Integer(42) }  
        }  
     }  
}  
public class MyTest {  
    @Test(dataProvider = "create", dataProviderClass = StaticProvider.class)  
    public void test(Integer n) {  
        // ...  
    }  
}

The Data Provider method can return one of the following two types:

1. An array (Object [] []) with multiple objects. The first subscript indicates the number of times the test method is called. The second subscript completely matches the parameter type and number in the test method. The above example has been explained.

2. The other is iterator < object [] >. The difference is that iterators allow you to delay creating your own test data. TestNG will call the iterator, and then the test method will call the value returned by the iterator one by one. When you need to pass many parameter groups to the test group, you don't need to create a bunch of values in advance.

The following is an example of using JDK 5 (note that the example of JDK 1.4 does not apply to generics):

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
public Iterator createData() {  
      return new MyIterator(DATA);  
    )  
@DataProvider(name = "test1")  
public Iterator

If you declare @ DataProvider using java.lang.reflect.Method as the first parameter, TestNG will pass the current test method as a parameter to the first parameter. This is especially useful when you have multiple test methods using the same @ DataProvider, and you want to return different values based on specific test methods.

For example, the following code is the name of the test method in its internal @ DataProvider:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@DataProvider(name = "dp")
public Object[][] createData(Method m) {
  System.out.println(m.getName());  
  return new Object[][] { new Object[] { "Cedric" }};
}

@Test(dataProvider = "dp")
public void test1(String s) {}
@Test(dataProvider = "dp")
public void test2(String s) {}

So it shows:

test1 

test2

 

The Data provider can run in parallel through the property parallel:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@DataProvider(parallel = true)  
//...

The data provider running with the XML file has the same thread pool. The default size is 10. You can change it by modifying the value in the < suite > tag:

<suitename="Suite1" data-provider-thread-count="20" >

...

If you need to run the specified data provider s in different threads, you must run them through different xml files.

(4) Advantages and disadvantages of the two methods

testng.xml

Advantages: the value is specified in testng.xml, which is convenient to modify and does not need to recompile the code;

Disadvantage: you need a testng.xml file, and the value cannot be calculated dynamically

data provider

Advantage: you can pass any valid Java type to the test method. This method is very flexible, and the value can be calculated dynamically through Java code or any storage mechanism

Disadvantage: this method requires some logic to return the correct object

2, Dependency method

Sometimes, you need to call test methods in a specific order.

1. Ensure that a certain number of test methods have been successfully completed before more method tests.

2. When initializing a test, we hope that the initialization method is also a test method (@ Before/After will not appear in the final report).

To do this, you can use the dependsOnMethods or dependsOnGroups property in @ Test.

There are two kinds of dependence:

1.Harddependencies. All dependent methods must run successfully. As long as there is a problem, the test is not called and is marked as SKIP in the report.

2.Softdependencies. Even if some dependent methods fail, they run the same way. If you just need to ensure that your Test methods are executed in order, you don't care if their dependent methods are successful. Then this mechanism is very useful. You can implement soft dependency by adding "alwaysRun=true" to @ Test.  

Examples of hard dependencies:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Test  
public void serverStartedOk() {}  
@Test(dependsOnMethods = { "serverStartedOk" })  
public void method1() {}

In this example, method1() relies on the method serverStartedOk() to ensure that serverStartedOk() always runs first.

You can also make several methods dependent on groups:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Test(groups = { "init" })  
public void serverStartedOk() {}  
@Test(groups = { "init" })  
public void initEnvironment() {}  
@Test(dependsOnGroups = { "init.* })  
public void method1() {}

In this case, method1 () depends on the group matching the regular expression "init. *", which ensures that serverStartedOk() and initEnvironment() are always called before method1().

Note: as mentioned earlier, calls in the same group are not guaranteed to be sequential in a Kwa test.

If you use hard dependency and the dependent method fails (alwaysRun=false, that is, the default is hard dependency), the dependent method is not marked FAIL but SKIP. The skipped methods will be marked in the final report (HTML is not indicated by red or green). The main reason is that the skipped methods are not necessarily failed, so they are marked for distinction.

Both dependsOnGroups and dependsOnMethods can accept regular expressions as parameters. For dependsOnMethods, if the dependent method has multiple overloads, all overloaded methods will be called. If you want to use only one of these overloads, you should use dependsOnGroups.

3, Class level annotation

Usually @ Test can also be used to annotate classes, not just methods:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 * java Automatic test exchange group: 694280102
 *
 * Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Test  
public class Test1 {  
    public void test1() {  
    }  
    public void test2() {  
    }  
}

@ Test at the class level makes all public methods in the class Test methods, regardless of whether they have been annotated or not. Of course, you can still annotate the Test method repeatedly with @ Test annotation, especially when you want to add some special properties to it.

For example:

package hongge;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import hongge.TestSum;

/**
 * @author Beijing - Hongge
 * 
 *java Automatic test exchange group: 694280102
 *
 *Java Automation test framework-04 - Test Method of TestNG
 *
 * 2019 October 23, 2010
 */
@Test
public class Test1 {
    public void test1() {
    }

    @Test(groups = "g1")
    public void test2() {
    }
}

In the above example, test1() and test2() are both processed, but on top of that test2() still belongs to the group "g1".

Summary

Posted by Okami on Sat, 09 May 2020 01:06:00 -0700