今天被同事问到一个问题,问题描述如下:

一个测试类,只有一个带参构造函数。在带参构造函数上加@Test,同时加@Parameters注解从testng.xml中传递参数。为保证测试函数在带参构造函数之后执行,所以测试方法前的@Test加了dependsOnMethods属性,依赖于带参构造函数。

重现问题的示例代码如下:

package com.ibm.testng.test;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test; public class WebTest {
//Times staying on the server
private int stayTime; //Constructor with params
@Test
@Parameters({"stayTime"})
public WebTest(int stayTime) {
System.out.println("Constructor with parameter!");
this.stayTime = stayTime;
} @Test(dependsOnMethods="WebTest")
public void stayOnServer() {
System.out.println("The times staying on server: " + stayTime);
}
}

输出结果:

 

根据输出结果可知,错误原因是没有找到stayOnServer()依赖的测试函数WebTest()。可能会疑问,不是有名称为WebTest()的函数吗,而且还用@Test注解了,为什么会提示找不到呢?

这个错误,跟TestNG的执行原理有关。TestNG启动之后,先调用构造函数创建所有的测试实例,然后才进行测试。因此,构造函数与测试函数的执行时机不一样,构造函数在所有测试方法之前先执行,没有必要再通过@Test的dependsOnMethods属性使测试函数依赖于构造函数。

构造函数没必要用@Test注解(注解了也不会报错),但是TestNG不会把它当做测试函数,它也不会和其他测试函数一起执行。可能习惯性地认为带参构造函数前的@Parameters一定要和@Test一起使用,其实不是这样的,@Parameters可以放的位置有如下两种情况:

1. 任何已经被@Test,@Factory或者Configuration annotation(@BeforeXXX/@AfterXXX)注解的函数。

2. 测试类中至多一个构造函数前面。TestNG会调用该构造函数创建测试实例,并从testng.xml中获得该构造函数需要的参数。

可能你希望使用某个构造函数来创建测试实例,但是TestNG会根据自己的规则选择构造函数。TestNG选择构造函数的规则:

1. 通常情况下,会选择默认无参构造函数或者自己添加的无参构造函数。

2. 如果有带参构造函数,且被@Parameters注解,就会选择该带参构造函数。

3. 如果同时有无参构造函数和带参构造函数,且带参构造函数没有被@Parameters注解,选择无参构造函数。

4. 如果只有带参构造函数,但是带参构造函数没有被@Parameters注解,执行测试函数时抛出org.testng.TestNGException。

对于带参构造函数的测试类,使用@Factory注解,不仅可以解决带参构造函数没有被@Parameters注解而导致的org.testng.TestNGException,而且还可以充分发挥TestNG参数化测试的优势。以添加如下@Factory注解的代码为例:

    @Factory
    public static Object[] create() {
        System.out.println("Create test objects!");
        List<WebTest> objectList = new ArrayList<WebTest>();
        for(int i=1; i<4; i++) {
            objectList.add(new WebTest(i*10));
        }
       
        return objectList.toArray();
    }

上面代码会创建3个stayTime分别为10,20,30的测试实例。如果使用@Parameters注解,必须创建3个test分别将10,20,30从testng.xml传入。因此,@Factory为带参构造函数的类创建一系列有规律的测试实例提供了便利。

最新文章

  1. jQuery中prop() , attr() ,css() 的区别
  2. 转载:kafka参数详解
  3. 0005 《SQL必知必会》笔记01-SELECT语句
  4. boost compile
  5. partial(C# 参考)
  6. 泛型之Dictionary
  7. Fling!
  8. 对于一些css样式的巧妙方法进行总结。
  9. PHP - __clone 对象克隆
  10. 多文件上传插件Stream,是Uploadify的Flash版和Html5版的结合,带进度条,并支持html5断点续传(附件上传),拖拽等功能
  11. 【转载】[ORACLE]详解not in与not exists的区别与用法
  12. Flask 扩展 缓存
  13. python [[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]
  14. 【Luogu3733】[HAOI2017]八纵八横(线性基,线段树分治)
  15. linux学习笔记 yum 在线管理软件包
  16. Python操作excel的几种方式--xlrd、xlwt、openpyxl
  17. [LOJ#6033]. 「雅礼集训 2017 Day2」棋盘游戏[二分图博弈、匈牙利算法]
  18. 《图像处理实例》 之 目标旋转矫正(基于区域提取、DFT变换)
  19. 2018.07.24 bzoj3531: [Sdoi2014]旅行(树链剖分+动态开点)
  20. 整理javascript基础

热门文章

  1. C# 6.0 新特性 (四)
  2. php、mysql编译配置
  3. Java SHAA加密
  4. shell动画
  5. 2018IEEE冬季生物识别学校 5天课程
  6. codevs 1392 合并傻子
  7. codevs 3160 最长公共子串 后缀自动机
  8. 【BZOJ】1996: [Hnoi2010]chorus 合唱队【区间dp】
  9. bzoj 1030
  10. ajax请求数据填充表格———使用art-template模板提高效率