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

一个测试类,只有一个带参构造函数。在带参构造函数上加@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. Educational Codeforces Round 45 (Rated for Div. 2) F - Flow Control

    F - Flow Control 给你一个有向图,要求你给每条边设置流量,使得所有点的流量符合题目给出的要求. 思路:只有在所有点的流量和为0时有解,因为增加一条边的值不会改变所有点的总流量和, 所以 ...

  2. 454. 四数相加 II

    给定四个包含整数的数组列表 A , B , C , D ,计算有多少个元组 (i, j, k, l) ,使得 A[i] + B[j] + C[k] + D[l] = 0. 为了使问题简单化,所有的 A ...

  3. Spring MVC——搭建HelloWeb工程

    1.确保环境配置配置正确(Myeclipse(eclipse)+Tomcat) 2.新建web project 3.将Spring MVC所需的jar包粘贴到WebRoot/WEB-INF/lib下 ...

  4. HDU 6201 transaction transaction transaction(树形DP)

    transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/1 ...

  5. python计数器Count

    python计数器Count # -*- coding:utf-8 -*- """ python计数器Counter 需导入模块collections "&qu ...

  6. hdu dp 1257 最小拦截系统

    最少拦截系统 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Statu ...

  7. sql:将字符类型字段转换成数字并排序

    使用cast 函数可以把字符类型字段(数学形式)转换为数字 比如 AND m.nfrc_meeting_no=? ORDER BY cast(m.BOOTH AS INT) ASC "; 结 ...

  8. 【刷水-二分答案】BZOJ1650 & BZOJ1639

    BZOJ1650-[Usaco2006 Dec]River Hopscotch 跳石子 [题目大意] 数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次条都从一个石子跳到相邻的下一个石子 ...

  9. [GCJ2017R3]Cooclement

    题目大意: 一种数列按照如下方式变化: 新数列第i位等于原数中数字i的出现次数. 变化过程中数列长度不变. 例如数列12的变化过程为12-11-20-01-10. 现在告诉你一个数列x,请求出x可能是 ...

  10. <form> 标签 // HTML 表单 // from 表单转换成json 格式

    <form> 标签   // HTML 表单    // from 表单转换成json 格式 form 表单,对开发人员来说是在熟悉不过的了,它是页面与web服务器交互时的重要信息来源 表 ...