浅析junit4及扩展实践

        junit框架相关源代码分析,网上已经有很多了,本篇不做过多相关解说,主要还是要自己多读相关源代码。本篇主要对自动化测试过程相关的测试用例,测试数据,测试结果结合junit做相关扩展说明。

       如果要解读junit详细源码,请参考深入JUnit源码之RunnerJUnit之参数化测试和成组测试的使用 相关系列文档,本篇只对主要类进行说明,主要相关类FrameworkMethod,Description,TestClass,BlockJUnit4ClassRunner,Suite

,BlockJUnit4ClassRunnerWithParameters,parameterized,相关关系可见如下图

 

 

 

  1. junit4主要类介绍

        Description类主要是对被测试对象的描述,它是一个树型结构;junit中测试对象类和方法,如果Description描述的是一个类,那么它的叶子节点必不为空,如果其描述的为一个方法,则其叶子节点为空;

       privatefinal ArrayList<Description> fChildren= newArrayList<Description>(); //无元素

       privatefinal String fDisplayName;      

       privatefinal Annotation[] fAnnotations;

测试树的一般元素/Composite,用fChildren保存其子结点。如一个单元测试类的Description,子结点包括所有@test修饰的方法;而一个Suite的子结点包括几个单元测试类的Description,而单元测试类和成组测试类又可以构成更大的Composite。

       FrameworkMethod是对测试方法的封装,描述了执行最终测试的方法。

       TestClass是对测试类封装,他只有一个参数Class<?> cls,即被测试的执行的类。

       BlockJUnit4ClassRunner类是最基本的Runner,他将传入的Class<?> cls中每个Test注解类封装成一个FrameworkMethod方法并运行。

 

  Suite类可以运行多组不同类型的Runner,比如BlockJUnit4ClassRunner,parameterized或其他自定义Runner;具体见图

 

                  parameterized是参数化的Runner,传入的Class<?> cls必须定义一个被Parameters  注解且返回类型为Collection的静态方法,如 :

                           @Parameters

                           public static Collection usernameData()

它会先执行@Parameters方法获取集合数据,对集合中的每组数据和Class<?>cls构造一个BlockJUnit4ClassRunnerWithParameters并运行其Class<?> cls中@Test注解方法,一般Class<?> cls的@Test注解方法只有一个。

           BlockJUnit4ClassRunnerWithParameters和BlockJUnit4ClassRunner功能差不多,多一个参数Object接受parameterized中集合数据,主要配合Parameterized Runner使用。

 2   junit4中过滤器Filter

      BlockJUnit4ClassRunner过滤调用顺序

      parameterized过滤调用顺序

   

   3  junit相关功能扩展设想

        BlockJUnit4ClassRunner是对类中的每个Test注解方法封装成一个FrameworkMethod并运行,比如

         

public class CalculatorTest {

@Test
    public void testAdd() {
        calculator.add(2);
        calculator.add(3);
        assertEquals(5,calculator.getResult());//第一个参数填写期待结果,第二个参数填写实际结果
       
    }

@Test
    public void testSubstract() {
        calculator.add(10);
        calculator.substract(2);
        assertEquals(8,calculator.getResult());
    }

@Test
    public void testMultiply() {
        calculator.add(2);
        calculator.multiply(3);
        assertEquals(6,calculator.getResult());
    }

}

那么testAdd,testSubstract,testMultiply方法都被封装成FrameworkMethod对象,并反射调用执行。其每个方法被设计

成一个用例,方便测试设计,其主要问题:

 a.   测试数据被写在方法中,修改和查看都不方便。

 b.   一个类里面一个方法只对应一组测试数据(即一个测试用例),这样有很大的代码冗余。

parameterized中的TestCase类必须有@Parameters注解方法,其运行逻辑为,先调用TestCase类@Parameters注解方法,

得到Collection数据,根据Collection和TestCase生成一组BlockJUnit4ClassRunnerWithParameters(带参数)类,对每组BlockJUnit4ClassRunnerWithParameters中TestCase@Test注解方法封装成FrameworkMethod类并运行,这样的场景一般@Test方法只有一个,即使多组数据对应到一个测试方法上组成多组用例,解决上面的b问题。例如:

@RunWith(Parameterized.class)
public class SquareTest {
    private static Calculator calculator = new Calculator();
    private int param;
    private int result;

@Parameters
    public static Collection date(){
        return Arrays.asList(new Object[][]{
            {2, 4},
            {0, 0},
            {-3, 9},
      });
    }

public SquareTest(int param, int result) {
           this.param = param;
           this.result = result;
    }
   
    @Test
    public void square() {
        calculator.square(param);
        assertEquals(result, calculator.getResult());
    }
   
}

由上可知parameterized解决了一个方法对应一组测试数据的问题,使多组数据对应到一个方法上组成多组测试用例(即上面的b问题)。虽然parameterized解决了一定程度上冗余问题,但junit在使用上依然存在可改进,除了之前的a问题(测试数据写在代码里面)外,比如一个接口测试,设计了一组测试数据(如a,b,c,d,e,f,g,h,i,g,k),其中a,b,c组合数据测试代码对应该一个方法,d,e,f,g数据的测试代码对应一个方法,h数据的测试代码单独对应一个方法,i数据测试代码对应一个方法,g,k对应一个方法,按照目前junit设计的BlockJUnit4ClassRunner和parameterized来组织用例代码,那么我需要设计3个parameterized的测试类对应3组测试数据,1个BlockJUnit4ClassRunner的测试类来对应h,i的测试数据,这样就让测试代码比较乱,我们可不可以设计一个测试类,该测试类中有5个方法来运行该组测试数据,这样一个测试类对应一个接口测试,是不是更好一点。

       扩展思路,1  改写parameterized,增加Collection 数据可构造传入

                     2   增加注解@TestCase,其中cstype = 1,rule = {1},支持用例ID配置规则。

                     3   增加一个过滤器,根据FrameworkMethod中的@TestCase注解和用例ID进行过滤。

                    增加测试数据读取类,将测试数据构造成Collection 和TestClass  传入改写后的parameterized,对Collection中的每组用例数据,按用例ID与TestClass的所有方法进行匹配,只有@TestCase规则符合用例ID的方法才被执行。见图

     

            在下篇中再做相关代码实现分享

转载于:https://www.cnblogs.com/xywq/p/6387533.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
junit4和powermock是两个常用的Java测试框架,它们常被开发人员用来进行单元测试。 junit4是一个成熟的单元测试框架,用于编写和运行Java程序的测试用例。它可以帮助开发人员在开发过程中及时发现代码中的错误,提升代码的质量。junit4提供了一系列的注解和断言来简化测试用例的编写,并且可以与各种开发工具和持续集成工具进行集成。 与此同时,powermock是一个用于扩展junit4的工具,可以帮助开发人员进行更加灵活和强大的单元测试。它可以模拟和修改Java程序中的一些难以测试的对象和行为,例如静态方法、私有方法和构造函数等。powermock使用了一种称为“字节码操作”的技术,能够改变Java字节码的执行路径,从而达到模拟和修改的目的。 使用junit4和powermock可以让开发人员编写更加全面和准确的单元测试用例。在测试过程中,我们可以使用junit4来编写测试用例的框架和断言,而使用powermock来模拟和修改需要被测试的对象。这样就可以在保持单元测试的独立性和可重复性的同时,更好地模拟和验证代码中的行为。 总的来说,junit4和powermock是两个非常有用的Java测试框架。它们可以一起使用,为开发人员提供更强大和灵活的单元测试能力。通过编写全面和准确的单元测试用例,可以提高代码的质量和可维护性,同时也可以减少程序中的BUG和错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值