Factory,顾名思意就是工厂,也就是工厂方法,在软件开发中一般结合多态使用,用来根据不同的条件创建不同的类对象。
在这里,Factory一般用来创建一个测试类的多个实例,每个实例属性不同,以执行不同的测试,Factory构造实例的方法必须返回Object[],也就是一组测试类的实例。
以testng官网的例子来说明,测试类如下,在测试用例testServer中,访问m_numberOfTimes次web页面,这里打印出了访问的次数和执行该用例的实例地址。
1 public class WebTest { 2 private int m_numberOfTimes; 3 public WebTest(int numberOfTimes) { 4 m_numberOfTimes = numberOfTimes; 5 } 6 7 @Test 8 public void testServer() { 9 for (int i = 0; i < m_numberOfTimes; i++) { 10 // access the web page 11 System.out.println("Access the web page, times " + i + ", the instance is " + this); 12 } 13 } 14 }
构造测试类WebTest实例的工厂如下,该工程创建了5个WebTest实例:
1 public class WebTestFactory { 2 @Factory 3 public Object[] createInstances() { 4 Object[] result = new Object[5]; 5 for (int i = 0; i < 5; i++) { 6 result[i] = new WebTest(i+1); 7 } 8 return result; 9 } 10 }
然后在XML文件中指定测试类为WebTestFactory,即可运行测试,注意:只需指定工厂类即可,无需再指定测试类。
1 <suite name="suite1"> 2 3 <test name="test1" verbose="2"> 4 <classes> 5 <class name="sea.WebTestFactory" /> 6 </classes> 7 </test> 8 9 </suite>
运行结果如下,可见总共执行了5个用例,每个用例访问web页面的次数不同。
1 Access the web page, times 0, the instance is sea.WebTest@1593948d 2 Access the web page, times 1, the instance is sea.WebTest@1593948d 3 Access the web page, times 2, the instance is sea.WebTest@1593948d 4 5 Access the web page, times 0, the instance is sea.WebTest@1b604f19 6 Access the web page, times 1, the instance is sea.WebTest@1b604f19 7 Access the web page, times 2, the instance is sea.WebTest@1b604f19 8 Access the web page, times 3, the instance is sea.WebTest@1b604f19 9 10 Access the web page, times 0, the instance is sea.WebTest@482f8f11 11 Access the web page, times 1, the instance is sea.WebTest@482f8f11 12 13 Access the web page, times 0, the instance is sea.WebTest@51565ec2 14 15 Access the web page, times 0, the instance is sea.WebTest@7823a2f9 16 Access the web page, times 1, the instance is sea.WebTest@7823a2f9 17 Access the web page, times 2, the instance is sea.WebTest@7823a2f9 18 Access the web page, times 3, the instance is sea.WebTest@7823a2f9 19 Access the web page, times 4, the instance is sea.WebTest@7823a2f9 20 21 PASSED: testServer 22 PASSED: testServer 23 PASSED: testServer 24 PASSED: testServer 25 PASSED: testServer
可以看到Factory的使用也比较简单,思考一下,在上面的例子中一个用例运行了5次,每次访问页面的次数不同,那么用DataProvider能否实现呢?
采用DataProvider实现的代码如下,这里通过DataProvider来提供每个用例访问web页面的次数,一共5个参数,用例会执行5次:
1 public class Test1 { 2 3 @DataProvider(name = "data1") 4 public Object[][] createdata() { 5 return new Object[][] { 6 {1}, 7 {2}, 8 {3}, 9 {4}, 10 {5} 11 }; 12 } 13 14 @Test(dataProvider = "data1") 15 public void testServer(int m_numberOfTimes) { 16 for (int i = 0; i < m_numberOfTimes; i++) { 17 // access the web page 18 System.out.println("Access the web page, times " + i + ", the instance is " + this); 19 } 20 } 21 22 }
执行结果如下:
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的实例。
1 public class Test1 { 2 private String name; 3 public Test1(String name) { 4 this.name = name; 5 } 6 7 @Test 8 public void test1() { 9 System.out.println("test1: His name is " + name); 10 } 11 12 @Test(dataProvider = "data1") 13 public void test2(String hobby) { 14 System.out.println("test2: " + name + " likes " + hobby); 15 } 16 17 @DataProvider(name = "data1") 18 public Object[][] createdata() { 19 return new Object[][] { 20 {"baozoumanhua"}, 21 {"movie"}, 22 {"music"} 23 }; 24 } 25 } 26 27 public class FactoryWithDataprovider { 28 29 @DataProvider(name = "data2") 30 public Object[][] createdata() { 31 return new Object[][] { 32 {"wangnima"}, 33 {"wangnimei"}, 34 }; 35 } 36 37 @Factory(dataProvider = "data2") 38 public Object[] createInstace(String name) { 39 return new Object[] { 40 new Test1(name) 41 }; 42 } 43 }
执行结果如下: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")