testng的@Factory及其与@DataProvider的区别

  Factory,顾名思意就是工厂,也就是工厂方法,在软件开发中一般结合多态使用,用来根据不同的条件创建不同的类对象。

  在这里,Factory一般用来创建一个测试类的多个实例,每个实例属性不同,以执行不同的测试,Factory构造实例的方法必须返回Object[],也就是一组测试类的实例。

  以testng官网的例子来说明,测试类如下,在测试用例testServer中,访问m_numberOfTimes次web页面,这里打印出了访问的次数和执行该用例的实例地址。

 public class WebTest {
private int m_numberOfTimes;
public WebTest(int numberOfTimes) {
m_numberOfTimes = numberOfTimes;
} @Test
public void testServer() {
for (int i = 0; i < m_numberOfTimes; i++) {
// access the web page
System.out.println("Access the web page, times " + i + ", the instance is " + this);
}
}
}

  构造测试类WebTest实例的工厂如下,该工程创建了5个WebTest实例:

 public class WebTestFactory {
@Factory
public Object[] createInstances() {
Object[] result = new Object[5];
for (int i = 0; i < 5; i++) {
result[i] = new WebTest(i+1);
}
return result;
}
}

  然后在XML文件中指定测试类为WebTestFactory,即可运行测试,注意:只需指定工厂类即可,无需再指定测试类。

 <suite name="suite1">

     <test name="test1" verbose="2">
<classes>
<class name="sea.WebTestFactory" />
</classes>
</test> </suite>

  运行结果如下,可见总共执行了5个用例,每个用例访问web页面的次数不同。

 Access the web page, times 0, the instance is sea.WebTest@1593948d
Access the web page, times 1, the instance is sea.WebTest@1593948d
Access the web page, times 2, the instance is sea.WebTest@1593948d Access the web page, times 0, the instance is sea.WebTest@1b604f19
Access the web page, times 1, the instance is sea.WebTest@1b604f19
Access the web page, times 2, the instance is sea.WebTest@1b604f19
Access the web page, times 3, the instance is sea.WebTest@1b604f19 Access the web page, times 0, the instance is sea.WebTest@482f8f11
Access the web page, times 1, the instance is sea.WebTest@482f8f11 Access the web page, times 0, the instance is sea.WebTest@51565ec2 Access the web page, times 0, the instance is sea.WebTest@7823a2f9
Access the web page, times 1, the instance is sea.WebTest@7823a2f9
Access the web page, times 2, the instance is sea.WebTest@7823a2f9
Access the web page, times 3, the instance is sea.WebTest@7823a2f9
Access the web page, times 4, the instance is sea.WebTest@7823a2f9 PASSED: testServer
PASSED: testServer
PASSED: testServer
PASSED: testServer
PASSED: testServer

  可以看到Factory的使用也比较简单,思考一下,在上面的例子中一个用例运行了5次,每次访问页面的次数不同,那么用DataProvider能否实现呢?

  采用DataProvider实现的代码如下,这里通过DataProvider来提供每个用例访问web页面的次数,一共5个参数,用例会执行5次:

 public class Test1 {

     @DataProvider(name = "data1")
public Object[][] createdata() {
return new Object[][] {
{1},
{2},
{3},
{4},
{5}
};
} @Test(dataProvider = "data1")
public void testServer(int m_numberOfTimes) {
for (int i = 0; i < m_numberOfTimes; i++) {
// access the web page
System.out.println("Access the web page, times " + i + ", the instance is " + this);
}
} }

  执行结果如下:

Access the web page, times 0, the instance is sea.Test1@58651fd0
Access the web page, times 0, the instance is sea.Test1@58651fd0
Access the web page, times 1, the instance is sea.Test1@58651fd0
Access the web page, times 0, the instance is sea.Test1@58651fd0
Access the web page, times 1, the instance is sea.Test1@58651fd0
Access the web page, times 2, the instance is sea.Test1@58651fd0
Access the web page, times 0, the instance is sea.Test1@58651fd0
Access the web page, times 1, the instance is sea.Test1@58651fd0
Access the web page, times 2, the instance is sea.Test1@58651fd0
Access the web page, times 3, the instance is sea.Test1@58651fd0
Access the web page, times 0, the instance is sea.Test1@58651fd0
Access the web page, times 1, the instance is sea.Test1@58651fd0
Access the web page, times 2, the instance is sea.Test1@58651fd0
Access the web page, times 3, the instance is sea.Test1@58651fd0
Access the web page, times 4, the instance is sea.Test1@58651fd0
PASSED: testServer(1)
PASSED: testServer(2)
PASSED: testServer(3)
PASSED: testServer(4)
PASSED: testServer(5)

  可以看到,就访问web页面的次数来说,这里结果与Factory方法没有什么不同,那这两者有什么区别呢?

  DataProvider:为测试用例提供参数,有多少组参数就会执行多少次用例,因此它是让一个测试类实例的某个方法执行多次,但每次执行都是采用的同一个实例(从上面结果的实例地址可以看出)。

  Factory:创建一个测试类的多个实例,每个实例中的所有测试用例都会被执行,因此它是让一个测试类被执行多次,每次执行采用的是不同实例。

  因此,如果想要使用不同的测试数据执行一个测试用例多次,那么采用DataProvider;如果想要多次执行一个测试类的所有用例,那么采用Factory。

  当然,Factory与DataProvider也可结合在一起使用,请看下面例子:

  在测试类Test1中有2个用例,其中用例test2通过dataProvider提供参数,而在DataProvider中提供了3组参数,因此测试类Test1每次会执行4个用例;

  在工厂类FactoryWithDataprovider中,通过DataProvider为工厂方法提供参数,因此工厂方法会创建2个Test1的实例。

 public class Test1 {
private String name;
public Test1(String name) {
this.name = name;
} @Test
public void test1() {
System.out.println("test1: His name is " + name);
} @Test(dataProvider = "data1")
public void test2(String hobby) {
System.out.println("test2: " + name + " likes " + hobby);
} @DataProvider(name = "data1")
public Object[][] createdata() {
return new Object[][] {
{"baozoumanhua"},
{"movie"},
{"music"}
};
}
} public class FactoryWithDataprovider { @DataProvider(name = "data2")
public Object[][] createdata() {
return new Object[][] {
{"wangnima"},
{"wangnimei"},
};
} @Factory(dataProvider = "data2")
public Object[] createInstace(String name) {
return new Object[] {
new Test1(name)
};
}
}

  执行结果如下:2个实例,每个实例执行4个用例,总共8个用例。

test1: His name is wangnima
test1: His name is wangnimei
test2: wangnima likes baozoumanhua
test2: wangnima likes movie
test2: wangnima likes music
test2: wangnimei likes baozoumanhua
test2: wangnimei likes movie
test2: wangnimei likes music
PASSED: test1
PASSED: test1
PASSED: test2("baozoumanhua")
PASSED: test2("movie")
PASSED: test2("music")
PASSED: test2("baozoumanhua")
PASSED: test2("movie")
PASSED: test2("music")

  

上一篇:EffectiveJava——用函数对象表示策略


下一篇:TestNG中@Factory的用法一:简单的数据驱动