`
longgangbai
  • 浏览: 7332258 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Junit4参数化测试

阅读更多

 

 


   现有这样一个接口,需要对其进行单元测试,代码如下:

publicclassJDemo{ 
/*
* 执行加法运算 
*/
publicint add(inta,int b){ 
returna+b; 
}

对该接口进行测试时,如果按照以前的测试方法,会编写类似如下的测试代码:

publicclass JDemoTest3 {

//测试0 0的情况 
@Test publicvoid add1(){ 
JDemo demo = newJDemo(); 
assertEquals(0, demo.add(0, 0)); 
} 

//测试正数、负数的情况 
@Test publicvoid add2(){ 
JDemo demo = newJDemo(); 
assertEquals(0, demo.add(1, -1)); 
} 

//测试正数、正数的情况 
@Test publicvoid add3(){ 
JDemo demo = newJDemo(); 
assertEquals(2, demo.add(1, 1)); 
} 
}

上面的测试方法存在严重的代码冗余并且不易维护,尤其当测试用例比较多时更加明显,现在我们基于Junit4的参数化来实现同样的功能,代码如下:

//声明所使用的运行器,如果未声明,则使用默认运行器。 
@RunWith(Parameterized.class) 
publicclassJDemoTest2 {

privateintresult; 
privateintadddata_a; 
privateintadddata_b; 

//参数化必须的构造方法,其中参数的顺序对应参数集中参数的顺序。 
public JDemoTest2(intresult,intadddata_a,intadddata_b){ 

this.adddata_a = adddata_a; 
this.adddata_b = adddata_b; 
this.result = result;
} 

@Test 
publicvoid add(){ 
JDemo demo = newJDemo(); 
assertEquals(result, demo.add(adddata_a, adddata_b)); 
} 

@SuppressWarnings("unchecked") 
@Parameters 
publicstatic Collection getParameters(){ 
returnArrays.asList(new Object[][]{ 
{0,0,0}, 
{0,1,-1}, 
{2,1,1} 
}); 
} 
}

使用Junit4参数化测试需要遵循其相应的规范,大致如下:
1. 为准备使用参数化测试的测试类指定特殊的运行器org.junit.runners.Parameterized。
2. 为测试类声明几个变量,分别用于存放期望值和测试所用数据。
3. 为测试类声明一个使用注解org.junit.runners.Parameterized.Parameters修饰的,返回值为java.util.Collection的公共静态方法,并在此方法中初始化所有需要测试的参数对。
4. 为测试类声明一个带有参数的公共构造函数,并在其中为步骤2中声明的几个变量赋值。
5. 编写测试方法,使用定义的变量作为参数进行测试。
关于Junit4参数化测试方法基本流程讲解完了,在实际工作中可根据需要加以应用

 

 

Junit与TestNG参数化测试比较

在TestNG中,直接使用@DataProvider进行参数化测试:

Java代码   收藏代码
  1. import org.testng.annotations.DataProvider;  
  2. import org.testng.annotations.Test;  
  3. import static org.testng.Assert.*;  
  4.   
  5. public class Addition {  
  6.     public int add(int a, int b) {  
  7.         return a+ b;  
  8.     }  
  9.       
  10.     @DataProvider(name = "addition")  
  11.     public Object[][] createData(){  
  12.         return new Object[][] {{1,2,3},{0,0,1},{-1,1,0},{-1,-2,-3}};  
  13.     }  
  14.       
  15.     @Test(dataProvider = "addition")  
  16.     public void addtionTest(int a1, int a2, int result){  
  17.         Addition ad = new Addition();  
  18.         assertEquals(ad.add(a1, a2), result);  
  19.     }  
  20.   
  21. }  

 而在Junit中一定要新建一个类,在构造函数中初始化数据:

Java代码   收藏代码
  1. import static org.junit.Assert.*;  
  2.   
  3. import java.util.Arrays;  
  4. import java.util.Collection;  
  5.   
  6. import org.junit.Test;  
  7. import org.junit.runner.RunWith;  
  8. import org.junit.runners.Parameterized;  
  9. import org.junit.runners.Parameterized.Parameters;  
  10.   
  11.   
  12. @RunWith(Parameterized.class)  
  13. public class AdditionTest {  
  14.     private int d1, d2;  
  15.     private int result;  
  16.     public AdditionTest(int d1, int d2, int result) {  
  17.         super();  
  18.         this.d1 = d1;  
  19.         this.d2 = d2;  
  20.         this.result = result;  
  21.     }  
  22.       
  23.     @Parameters  
  24.     @SuppressWarnings("unchecked")  
  25.     public static Collection getParamters(){  
  26.         Object [][] object = {{1,2,3},{0,0,0},{-1,1,0},{-1,-2,-3}};    
  27.         return Arrays.asList(object);        
  28.     }  
  29.       
  30.     @Test  
  31.     public void testAddition(){  
  32.         Addition ad = new Addition();  
  33.         assertEquals(this.result, ad.add(this.d1, this.d2));  
  34.     }  
  35.       
  36. }  

 结论:相较之下,用TestNG去实现可以让代码更加简单一些

 

 

ParallelComputer: 并行测试
当需要同时测试testcase的时候,你不需要为自己写thread来做这个事情。JUnit4已经有了这个特性,而且还提供多种同步选择。例如:


/**
 * @author longgangbai
 */ 
public class ParallelComputerTest { 
    
   @Test 
    public void test() {     
      Class[] cls={ParallelTest1.class,ParallelTest2.class }; 
       
      //Parallel among classes 
      JUnitCore.runClasses(ParallelComputer.classes(), cls); 
       
      //Parallel among methods in a class 
      JUnitCore.runClasses(ParallelComputer.methods(), cls); 
       
      //Parallel all methods in all classes 
      JUnitCore.runClasses(new ParallelComputer(true, true), cls);    
    } 
   public static class ParallelTest1{ 
      @Test public void a(){} 
      @Test public void b(){} 
   } 
   public static class ParallelTest2{ 
      @Test public void a(){} 
      @Test public void b(){} 
   } 

你有3种同步方式:

1: ParallelComputer.classes():所有测试类同时开始执行,但是每个类里面的方法还是顺序执行。在例子里面ParallelTest1 和ParallelTest2 同时开始,但是各自的a(),b() 还是顺序执行。

2: ParallelComputer.methods():测试类顺序执行,但是每个类里面的方法是同时开始执行。在例子里面ParallelTest1 的a() 和b() 同时开始,等结束之后再开始ParallelTest2 。

3: new ParallelComputer(true, true):所有测试类里面方法同时开始执行。在例子里面4个方法同时开始执行。

很有意思吧。

 

Category: 分类测试
当你有很多testcase,但是你不想每次都执行一遍的时候。你可以把testcase分成若干类,然后就可以分类有选择的来执行这些testcase。

例子:譬如你有2类testcase,一类是重要的用Important.class表示,还有一类不那么重要的用Secondary.class表示。


/**
 * @author longgangbai
 */ 
interface Important{}; 
interface Secondary{}; 
@RunWith(Categories.class) 
@IncludeCategory(Important.class) 
@ExcludeCategory(Secondary.class) 
@SuiteClasses( { CategoryTest.Alpha.class,  
                 CategoryTest.Beta.class }) 
public class CategoryTest { 
    
   @Category(Important.class) 
   public static class Alpha{//Alpha is Important except b 
      @Test  
      public void a(){} 
       
      @Test 
      @Category(Secondary.class) 
      public void b(){} 
   } 
    
   public static class Beta{ 
      @Test  
      @Category(Important.class) 
      public void a(){}//a is Important 
   } 

当你执行后会发现只有Alpha.a() 和Beta.a() 执行到,Alpha.b() 被@ExcludeCategory 掉了。

 

MaxCore: 失败优先
  当需要反复测试大量testcase的时候,你往往比较关注那些前一次失败的case。这个时候你就可以利用MaxCore特性在每次执行testcase的时候优先执行那些上次失败的case。

例如:


/**
 * @author longgangbai
 */ 
public class MaxCoreTest { 
    
   private MaxCore fMax; 
    
   @Before 
   public void createMax() { 
      File fMaxFile= new File("MaxCore.ser"); 
      fMax= MaxCore.storedLocally(fMaxFile); 
   } 
    
   @Test  
   public void test(){ 
      Request request= Request.aClass(Delta.class); 
      fMax.run(request); 
      fMax.run(request);//b->c->a 
   } 
    
   public static class Delta{ 
      @Test public void a(){} 
      @Test public void b(){ 
         Assert.fail(); 
      } 
      @Test public void c(){} 
   } 

可以观察到第2次执行的时候Delta.b() 由于第1次的失败而提前到了最先执行。

 

 

DataPoint: 参数数据
当需要测试不同输入参数的时候是不是要写一大堆testcase?不需要,因为JUnit4提供了参数化测试数据的特性。例如你想要测试2个整型数据作为输入参数的时候:


/**
 * @author longgangbai
 */ 
@RunWith(Theories.class) 
public class DataPointTest { 
   @DataPoint 
   public static int ONE= 1; 
   @DataPoint 
   public static int TWO= 2; 
  
   /* You could also use @DataPoints instead of @DataPoint
   @DataPoints
   public static int[] points= { 1, 2 };*/ 
  
   @Theory 
   public void test(int first, int second) { 
   } 

通过观察test() 被执行了4次,每次不同的组合作为参数输入。而且如果参数数目过多,你可以通过@DataPoints 一下子把参数都设进去。用过@RunWith(Parameterized.class) 的朋友可以和DataPoint做一下比较。

TestedOn
这个功能也是参数化数据,只不过它是直接在参数上配置。例如:


@Theory 
public void test2(@TestedOn(ints={1,2})int first) { 
    System.out.println(first); 

结果打印出来"1 ,2" 。

 

 

PrintableResult: 打印结果
这个我认为倒是一个小功能,它只是把测试失败的结果以比较美观的格式打出来。例如:


Result result = JUnitCore.runClasses(SomeTest.class); 
System.out.println(new PrintableResult(result.getFailures())); 

 

分享到:
评论

相关推荐

    Junit参数化测试源代码

    4. **Service测试类**:使用Junit参数化测试验证Service类的各个方法。 在Service测试类中,你可能会看到类似如上的参数化测试结构,测试数据可能是从数据库查询的结果、固定的数组或文件读取的数据。每个测试用例...

    junit参数化测试的使用方法

    ### JUnit参数化测试的使用方法 #### 一、引言 JUnit是Java开发中最常用的单元测试框架之一,它提供了一种简单的方式来编写可重复执行的测试案例。随着软件复杂度的增加,对于某些功能模块可能需要多次使用不同的...

    在Eclipse中使用JUnit4进行单元测试

    为了更好地组织测试,可以使用`@RunWith`注解配合测试运行器(如`Parameterized`或`Suite`),实现参数化测试和组合测试。参数化测试允许为同一个测试方法提供多组输入数据,而`Suite`则能将多个测试类组合成一个...

    eclipse下利用ant、junit进行自动化测试例子源码

    JUnit支持注解、参数化测试、异常测试等特性,使得编写和执行单元测试变得更加简单。 4. **自动化测试**:自动化测试是指通过软件工具自动执行预先编写的测试脚本来检查程序功能是否正确的一种方法。相比手动测试,...

    junit4测试jar包

    5. **参数化测试**:`@Parameterized`测试可以使用不同的参数多次运行同一个测试方法,这对于测试多种输入情况非常有用。 6. **超时测试**:`@Test(timeout = 1000)`可以设置测试方法的执行时间限制,超过设定时间...

    Junit4 basic concept

    JUnit4是JUnit框架的一个重要版本,相较于之前的版本,它引入了许多新特性,如注解(Annotations)、参数化测试等,这些特性极大地简化了测试代码的编写过程,提高了测试的灵活性和可读性。 #### 二、概念介绍 ###...

    JUnit多参数测试实例整合FizzBuzz

    1. **创建参数化测试类**:首先,我们需要创建一个测试类,并使用`@RunWith(Parameterized.class)`注解,声明这是一个参数化的测试类。 2. **定义公共静态方法来提供参数**:这个方法应该返回一个`Collection`对象,...

    junit4单元测试

    除此之外,JUnit4还支持参数化测试,通过`@Parameters`注解和`parameters()`方法可以为测试方法提供多组输入数据,实现对同一函数的多次测试。这对于测试具有多种输入情况的函数非常有用。 异常测试也是JUnit4的一...

    单元测试利器JUnit4

    JUnit4相较于早期版本引入了许多改进,如注解、参数化测试和测试套件等,使得测试代码更加简洁和灵活。 2. 注解(Annotations): JUnit4的核心特点是广泛使用注解,这使得测试类和方法的声明更清晰。例如: - `@...

    Spring+JUnit4 +Ant测试报告

    JUnit4还支持参数化测试、异常测试等多种测试场景,使得测试更加灵活和全面。 接下来,Ant是一个基于XML的构建工具,用于自动化Java项目中的编译、打包、测试等任务。在Spring和JUnit4的测试环境中,Ant通常被用来...

    junit4测试源码

    其次,JUnit4支持参数化测试,这意味着一个测试方法可以使用不同的参数多次执行。`@Parameters`注解用于提供参数数据,`@Parameterized.Parameters`方法返回一个包含参数的集合。 异常测试也是JUnit4的一个重要特性...

    Junit4测试总结

    ### 四、参数化测试 JUnit4的`@Parameters`注解和`Parameterized`测试类可以实现参数化的测试,即用不同的输入数据多次运行同一个测试。 ```java @RunWith(Parameterized.class) public class ParameterizedTest {...

    junit4 jar包 Java单元测试框架绿色免费版.zip

    在实际项目中,开发者通常会配合使用`@RunWith`注解来选择测试运行器(Test Runner),比如`@RunWith(Suite.class)`或`@RunWith(Parameterized.class)`,以实现更复杂的测试场景,如组合测试或参数化测试。...

    junit4单元测试实例

    五、参数化测试 JUnit4的`@Parameters`注解可以用于创建参数化的测试,这意味着一个测试方法可以接受不同的输入参数并进行多次执行。 六、运行器与分类 - `@RunWith`注解:指定测试运行器,如`Parameterized.class`...

    Junit4单元测试入门例子

    在实际项目中,可能还需要引入Mockito等工具对依赖进行模拟,以及使用持续集成工具进行自动化测试。 总结,Junit4使得Java的单元测试变得简单而直观。通过注解,我们可以快速定义测试方法,结合断言库进行结果验证...

    junit4测试工具

    其次,JUnit4支持参数化测试,允许使用不同的输入数据执行同一个测试方法。这通过`@Parameters`注解和相关的静态方法实现,可以大大提高测试覆盖率,确保代码对各种可能的输入都能正确处理。 再者,JUnit4引入了...

Global site tag (gtag.js) - Google Analytics