【TestNG】testNG传参的用法和高级应用

一.TestNG用法说明

TestNG的详细教程请看链接:https://blog.csdn.net/df0128/article/details/83243822

二.直接从类中传参

此处需要用到注解@DataProvider来进行传参,
如下定义了一个测试用例,名为TestNgLearn1,其有两个参数传入,param1param2,都是int型。其标注@Test内部含有一个dataProvider = "provideNumbers"即为指明其参数来源,其中provideNumbers为参数来源的那个方法的名称。
除了测试用例外还定义了一个方法叫做provideData,其标注为@DataProvider,即说明此方法是一个参数提供方法,其包含多个参数值可供指定,下面分别说明:

1.name参数

name指定该参数提供者的名称,其他测试用例可以通过该名称调用此方法,其实如果此属性不指定的话,会默认将方法名称作为该数据提供者的名称,即其他用例可以通过方法名称来调用此方法;
如下name="provideNumbers"中的provideNumbers即为设定的参数提供者的名称,此名称和测试方法TestNgLearn1注解中需要的数据提供者名称一致,如下是一个最简单的范例:

public class TestCase1 {

	@DataProvider(name = "provideNumbers")
    public Object[][] provideData() {

        return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
    }
	
    @Test(dataProvider = "provideNumbers", groups= {"gp1"})
    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);
    }
}

此处数据提供者返回的的内容必须为Object[][],即一个二维数组,此处要注意,如上面的例子返回了三组参数,故用例应当会被执行三次,即如下结果:

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
PASSED: TestNgLearn1(10, 20)
PASSED: TestNgLearn1(100, 110)
PASSED: TestNgLearn1(200, 210)

===============================================
    Default test
    Tests run: 3, Failures: 0, Skips: 0
===============================================

如上结果符合预期,运行三次,三组值都运行了一次;

2.indices参数

@DataProvider除了必须定义name外,还有两个值可以指定,一个是indices,此值指定返回的参数组中的第几个会被使用,编号从0开始,如下范例指定了indices= {1},name执行结果应当只有第二组参数值,代码如下:

public class TestCase1 {
	@DataProvider(name = "provideNumbers",indices= {1})
    public Object[][] provideData() {

        return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
    }
	
    @Test(dataProvider = "provideNumbers", groups= {"gp1"})
    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);
    }
}

运行结果如下:

this is TestNG test case1, and param1 is:100; param2 is:110
PASSED: TestNgLearn1(100, 110)

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

如上结果符合预期,只使用了三组参数中的第二组,即编号为1的那一组;注意编号不要超出你返回的列表的大小

3.parallel参数

此参数意思是是否并发执行,其值可为true或者false,默认为false,如果为true则会并发执行,范例如下:

public class TestCase1 {

	@DataProvider(name = "provideNumbers",parallel=true)
    public Object[][] provideData() {

        return new Object[][] { { 10, 20 }, { 100, 110 }, { 200, 210 } };
    }
	
    @Test(dataProvider = "provideNumbers", groups= {"gp1"})
    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);
    }
}

结果如下:

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

===============================================
    Default test
    Tests run: 3, Failures: 0, Skips: 0
===============================================

因为范例运行较快,而此处TestNG并未打印很详细的东西,所以看不出来是并发,但是如果是用一个运行较慢的用例来验证,就可以看出来了。

三、从xml文件中传参

除了可以从@DataProvider传入参数外,还可以通过testng.xml中传入参数;
此方法需要在用例上除了@Test外还要添加注解@Parameters,同时xml中要有parameter标签来输入对应的参数,如下范例所示:
测试用例:

public class ParameterSample {
	
  @Test
  @Parameters({ "dbconfig", "poolsize" })
  public void test(String dbconfig, int poolsize) 
  {
	  System.out.println("dbconfig : " + dbconfig);
      System.out.println("poolsize : " + poolsize);
  }
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="none">
  <test name="Test">
    <parameter name="dbconfig" value="db.properties" />
    <parameter name="poolsize" value="10" />
    <classes>
      <class name="com.demo.test.testng.ParameterSample"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

运行xml结果如下:

dbconfig : db.properties
poolsize : 10

===============================================
Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

四、高级应用范例

前面都是传参的基本用法,下面介绍一些传参的稍微高级的用法;

1.@DataProvider传入对象

代码如下

public class ParameterSample {

	@Test(dataProvider = "dbconfig")
	public void testConnection(Map<String, String> map) {

		for (Map.Entry<String, String> entry : map.entrySet()) 
		{
			System.out.println("[Key] : " + entry.getKey() + " [Value] : " + entry.getValue());
		}

	}

	@DataProvider(name = "dbconfig")
	public Object[][] provideDbConfig() {
		Map<String, String> map = readDbConfig();
		return new Object[][] { { map } };
	}

	public Map<String, String> readDbConfig() 
	{
		Map<String, String> map = new HashMap<String, String>();
		try {
			map.put("jdbc.driver", "com.mysql.jdbc.Driver");
			map.put("jdbc.url", "jdbc:mysql://localhost:3306/test");
			map.put("jdbc.username", "root");
			map.put("jdbc.password", "root");

		} catch (Exception e) {
			e.printStackTrace();
		}
		return map;

	}
}

运行结果:

[Key] : jdbc.password [Value] : root
[Key] : jdbc.username [Value] : root
[Key] : jdbc.url [Value] : jdbc:mysql://localhost:3306/test
[Key] : jdbc.driver [Value] : com.mysql.jdbc.Driver
PASSED: testConnection({jdbc.password=root, jdbc.username=root, jdbc.url=jdbc:mysql://localhost:3306/test, jdbc.driver=com.mysql.jdbc.Driver})

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================

不过这样的话就会只有一条用例了。

2.同一个@DataProvider分别对两个测试用例传参

代码如下:

public class ParameterSample {

	@Test(dataProvider = "dataProvider")
    public void test1(int number, int expected) {
        Assert.assertEquals(number, expected);
    }

    @Test(dataProvider = "dataProvider")
    public void test2(String email, String expected) {
        Assert.assertEquals(email, expected);
    }

    @DataProvider(name = "dataProvider")
    public Object[][] provideData(Method method) {

        Object[][] result = null;

        if (method.getName().equals("test1")) {
            result = new Object[][] {
                { 1, 1 }, { 200, 200 }
            };
        } else if (method.getName().equals("test2")) {
            result = new Object[][] {
                { "[email protected]", "[email protected]" },
                { "[email protected]", "[email protected]" }
            };
        }

        return result;
    }
}

运行结果如下:

PASSED: test1(1, 1)
PASSED: test1(200, 200)
PASSED: test2("[email protected]", "[email protected]")
PASSED: test2("[email protected]", "[email protected]")

===============================================
    Default test
    Tests run: 4, Failures: 0, Skips: 0
===============================================

3.同一个@DataProvider被多个用例使用,但根据分组名称传递参数

代码:

public class TestParameterDataProvider4 {
	
	@Test(dataProvider = "dataProvider", groups = {"groupA"})
    public void test1(int number) {
        Assert.assertEquals(number, 1);
    }

    @Test(dataProvider = "dataProvider", groups = "groupB")
    public void test2(int number) {
        Assert.assertEquals(number, 2);
    }

    @DataProvider(name = "dataProvider")
    public Object[][] provideData(ITestContext context) {

        Object[][] result = null;

        for (String group : context.getIncludedGroups()) {

            System.out.println("group : " + group);

            if ("groupA".equals(group)) {
                result = new Object[][] { { 1 } };
                break;
            }

        }

        if (result == null) {
            result = new Object[][] { { 2 } };
        }
        return result;

    }
}

xml内容:

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

运行xml结果如下:

group : groupA

===============================================
Suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

4.@DataProvider返回迭代器

  • 范例一:
    代码:
public class ParameterSample1 {
	
  @Test(dataProvider = "dp")
  public void test(String str, Integer i) 
  {
	  System.out.println(str+i);
  }

  @DataProvider
  public Iterator<Object[]> dp() 
  {
	  List<Object[]> objList = new ArrayList<Object[]>();		
	  for(int i = 1; i < 5; i++)
	  {			
		  objList.add(new Object[]{"第" + i  + "名得分", new Integer(i) });		
		  }		
	  return objList.iterator();

  }
}

执行结果:

第1名得分1
第2名得分2
第3名得分3
第4名得分4
PASSED: test("第1名得分", 1)
PASSED: test("第2名得分", 2)
PASSED: test("第3名得分", 3)
PASSED: test("第4名得分", 4)

===============================================
    Default test
    Tests run: 4, Failures: 0, Skips: 0
===============================================
  • 范例二
    测试用例代码:
public class ParameterSample1 {
	
	@Test(dataProvider = "dp")
	public void test(Demo demo) 
	{
		System.out.println("我从myDataProvider仓库拿到了名字:" + demo.getName() + ";年龄:" + demo.getAge());
	}

	@DataProvider
	public Iterator<Object[]> dp() 
	{
		List<Demo> list = new ArrayList<Demo>();
		Demo demo1 = new Demo();
		demo1.setName("david");
		demo1.setAge(19);
		Demo demo2 = new Demo();
		demo2.setName("sansa");
		demo2.setAge(20);
		list.add(demo1);
		list.add(demo2);
		List<Object[]> fArrList = new ArrayList<Object[]>();
		for (Object f : list) 
		{
			fArrList.add(new Object[] { f });
		}
		return fArrList.iterator();
	}
}

Demo.java:

public class Demo {

	private String name;
	private int age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

运行结果:

我从myDataProvider仓库拿到了名字:david;年龄:19
我从myDataProvider仓库拿到了名字:sansa;年龄:20
PASSED: test(com.demo.test.testng.Demo@6c49835d)
PASSED: test(com.demo.test.testng.Demo@56aac163)

===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================

在上面两个例子中,分别传入了Object[]和自定义对象的迭代器,内容都是从类内部直接写的,其实在实际应用中,对于同一条用例,不同入参的验证,在集成化的情况下大多会选择从文件读取,那么,只需要在上面的代码中加入读取文件的内容并组合的步骤即可;

5.从xml传不同参数运行同一条用例

其实从xml读取参数的方法比较死板,不如使用@DataProvider灵活,实际应用中多用这个来进行全局参数的设定等;
这里介绍下如果想从xml读取参数来运行同一条用例的方法:
代码:

public class ParameterSample {

	@Test
	  @Parameters({ "dbconfig", "poolsize" })
	  public void test(String dbconfig, int poolsize) 
	  {
		  System.out.println("dbconfig : " + dbconfig);
	      System.out.println("poolsize : " + poolsize);
	  }
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="none">
  <test name="Test">
    <parameter name="dbconfig" value="db.properties" />
    <parameter name="poolsize" value="10" />
    <classes>
      <class name="com.demo.test.testng.ParameterSample">
        <methods>
          <include name="test" />
        </methods>
      </class>
    </classes>
  </test> 
  <test name="Test1">
    <parameter name="dbconfig" value="db.properties1" />
    <parameter name="poolsize" value="101" />
    <classes>
      <class name="com.demo.test.testng.ParameterSample">
        <methods>
          <include name="test" />
        </methods>
      </class>
    </classes>
  </test>
</suite>  

运行结果:

dbconfig : db.properties
poolsize : 10
dbconfig : db.properties1
poolsize : 101

===============================================
Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

6、调用其他类中的@DataProvider

在前面的例子中,测试用例和传参的方法都在同一个文件中,那么是否这两个可以不在一个类当中呢?答案是肯定的,只是需要在测试用例上添加dataProviderClass属性即可,其指定的是@DataProvider所在的class,如下这个范例就是从其他类中传入@DataProvider,代码如下:
测试用例类:

public class ParameterSample1 {
	
	@Test(dataProvider = "data", dataProviderClass = ParameterSample.class)
	public void getDataFromOtherClass(String name, int age) 
	{
		System.out.println("name:"+name+"; age:"+age);
	}
}

@DataProvider类:

public class ParameterSample {

	@DataProvider(name = "data",parallel=true)
	public Object[][] data()
	{
		return new Object[][] { {"张三", 12}, {"李四", 13} };
	}

运行测试用例结果如下:

name:张三; age:12
name:李四; age:13
PASSED: getDataFromOtherClass("张三", 12)
PASSED: getDataFromOtherClass("李四", 13)

===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================

需要注意的是此方式下,@DataProvider就不能采用不加注解的方式了,必须要加此注解,还要指定名称,且名称必须和用例上那个调用名称相同;

猜你喜欢

转载自blog.csdn.net/df0128/article/details/83303778