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

一个测试类,只有一个带参构造函数。在带参构造函数上加@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为带参构造函数的类创建一系列有规律的测试实例提供了便利。

TestNG测试带参构造函数的类的更多相关文章

  1. C++ //构造函数调用规则 //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) //析构函数(空实现) //拷贝函数(值拷贝) //2.如果我们写了有参构造函数 编译器就不会提供默认构造函数 但是会提供拷贝构造函数 //3.如果我们写了拷贝函数 编译器就不再提供 默认 有参 构造函数

    //构造函数调用规则 #include <iostream> using namespace std; //1.创建一个类,C++编译器会给每个类添加至少3个函数 //默认构造(空实现) ...

  2. C++构造函数 & 拷贝构造函数 & 派生类的构造函数 & 虚继承的构造函数

    构造函数 ,是一种特殊的方法 .主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 .特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数 ...

  3. c#之有参和无参构造函数,扩展方法

    例如在程序中创建 Parent类和Test类,在Test有三个构造函数,parent类继承Test类,那么我们可以在Test类自身中添加 扩展 方法吗? 答案:是不可以的.因为扩展方法必须是静态的,且 ...

  4. C++编写字符串类CNString,该类有默认构造函数、类的拷贝函数、类的析构函数及运算符重载

    编码实现字符串类CNString,该类有默认构造函数.类的拷贝函数.类的析构函数及运算符重载,需实现以下“=”运算符.“+”运算.“[]”运算符.“<”运算符及“>”运算符及“==”运算符 ...

  5. union 中可以存储的是不带构造函数的类对象

    union 中可以存储的是不带构造函数的类对象 否则不符合逻辑 为什么不符合逻辑?

  6. c++中在一个类中定义另一个只有带参数构造函数的类的对象

    c++中在一个类中定义另一个只有带参数构造函数的类的对象,编译通不过 #include<iostream> using namespace std; class A { public:  ...

  7. JavaScript面向对象编程(二)构造函数和类

    new关键字和构造函数 在文章JavaScript面向对象编程(一)原型与继承中讨论啦JavaScript中原型的概念,并且提到了new关键字和构造函数.利用new关键字构造对象的实例代码如下: // ...

  8. 关于spring中Assert的应用(方法入参检测工具类)

    关于spring中Assert的应用(方法入参检测工具类) Web 应用在接受表单提交的数据后都需要对其进行合法性检查,如果表单数据不合法,请求将被驳回.类似的,当我们在编写类的方法时,也常常需要对方 ...

  9. Fragment中不能使用自定义带参构造函数

    通过Fragment自定义的静态方法将值从activity传到fragment中,然后就想到这样不是多次一举吗,为什么不直接写个带参构造函数将值传过去呢?试了一下,发现Fragment有参构造函数竟然 ...

随机推荐

  1. 【LOJ】#2129. 「NOI2015」程序自动分析

    题解 开始是想两个并查集的 和A相等,和A不相等 如果AB相等就连 A 相等,B相等 B不相等 A不相等 如果AB不相等就连 A不相等,B相等 B相等,A不相等 但是显然不对,因为和A不相等的不一定和 ...

  2. vue-music 关于搜索历史本地存储

    搜索历史 搜索过的关键词 保存在本地存储 localstorage 中,同时多个组件共享搜索历史数据,将数据存到vuex 中,初始值从本地缓存中取得对应key 的值,没有数据默认为空数组 点击搜索关键 ...

  3. Coding.net简单使用指南

    注意:大家创建项目时一定要选择创建公开仓库!不然别人看不到! Coding.net是一个代码托管平台,简单来说这东西就是一个你在线存放代码的地方. 至于为什么要把代码存到这东西上呢?很多好处,比如防丢 ...

  4. shell脚本基本用法

    下面是一些简单常用的脚本,工作中可能会用到,记录一下. #!/usr/bin/env bash #变量[=两边不要有空格], 在使用的时候需要用${变量名} 或者是$变量名 name="sa ...

  5. BZOJ1073 k短路(A*算法)

    A*算法,也叫启发式搜索,就是设计一个预估函数,然后在搜索的过程中进行有序的搜索,我们设到目前状态的花费为f(x),到目标状态的估计花费为h(x),那么我们按照h(x)+f(x)排序即可,这道题里起点 ...

  6. [BZOJ3676][APIO2014]回文串(Manacher+SAM)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 3097  Solved: 1408[Submit][Statu ...

  7. [HDU5965]扫雷

    [HDU5965]扫雷 题目大意: 一个\(3\times n(n\le10000)\)的扫雷,第\(2\)排没有雷.告诉你第\(2\)排上的数,问有几种埋雷的方案? 思路: 动态规划. 将\(1,3 ...

  8. Cookie&Session会话技术

    一.会话技术简介 1.存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并不知道该客 ...

  9. bzoj 3585: mex && 3339: Rmq Problem -- 主席树

    3585: mex Time Limit: 20 Sec  Memory Limit: 128 MB Description 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区 ...

  10. js 运算符 || && 妙用

    首先出个题:如图: 假设对成长速度显示规定如下:  成长速度为5显示1个箭头:  成长速度为10显示2个箭头:  成长速度为12显示3个箭头:  成长速度为15显示4个箭头:  其他都显示都显示0个箭 ...