zoukankan      html  css  js  c++  java
  • 单元测试Junit使用详解

    1、Junit 是什么?

      JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。

      注意:Junit 测试也是程序员测试,即所谓的白盒测试,它需要程序员知道被测试的代码如何完成功能,以及完成什么样的功能

    2、Junit 能做什么?

      我们知道 Junit 是一个单元测试框架,那么使用 Junit 能让我们快速的完成单元测试。

      通常我们写完代码想要测试这段代码的正确性,那么必须新建一个类,然后创建一个 main() 方法,然后编写测试代码。如果需要测试的代码很多呢?那么要么就会建很多main() 方法来测试,要么将其全部写在一个 main() 方法里面。这也会大大的增加测试的复杂度,降低程序员的测试积极性。而 Junit 能很好的解决这个问题,简化单元测试,写一点测一点,在编写以后的代码中如果发现问题可以较快的追踪到问题的原因,减小回归错误的纠错难度。

    3、Junit 的用法

    首先介绍 Junit 的几种类似于 @Test 的注解:

      1.@Test: 测试方法

        a)(expected=XXException.class)如果程序的异常和XXException.class一样,则测试通过
        b)(timeout=100)如果程序的执行能在100毫秒之内完成,则测试通过

      2.@Ignore: 被忽略的测试方法:加上之后,暂时不运行此段代码

      3.@Before: 每一个测试方法之前运行

      4.@After: 每一个测试方法之后运行

      5.@BeforeClass: 方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分before,是所有测试方法

      6.@AfterClass: 方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After

    junit before,beforeClass,after, afterClass的执行顺序

    JUnit4使用Java5中的注解(annotation),以下是JUnit4常用的几个annotation: 

    • @Before:初始化方法   对于每一个测试方法都要执行一次(注意与BeforeClass区别,后者是对于所有方法执行一次)
    • @After:释放资源  对于每一个测试方法都要执行一次(注意与AfterClass区别,后者是对于所有方法执行一次)
    • @Test:测试方法,在这里可以测试期望异常和超时时间 
    • @Test(expected=ArithmeticException.class)检查被测方法是否抛出ArithmeticException异常 
    • @Ignore:忽略的测试方法 
    • @BeforeClass:针对所有测试,只执行一次,且必须为static void 
    • @AfterClass:针对所有测试,只执行一次,且必须为static void 
    • 一个JUnit4的单元测试用例执行顺序为: 
    • @BeforeClass -> @Before -> @Test -> @After -> @AfterClass; 
    • 每一个测试方法的调用顺序为: 
    • @Before -> @Test -> @After; 

     那么上面的例子,我们可以看到,每个 @Test 方法中都有 Calculator c = new Calculator();即类的实例化,那么我们可以将其放入到 @Before 中

    public class CalculatorTest {

        Calculator c = null;

         

        @Before

        public void testBeforeClass(){

            c = new Calculator();

        }

        @Test

        //测试 add()方法

        public void testAdd(){

            int result = c.add(12);

            //Assert.assertEquals(result, 3);

            //等价于:

            if(result == 3){

                System.out.println("add()方法正确");

            }

        }

         

        @Test

        //测试 sub()方法

        public void testSub(){

            int result = c.sub(21);

            //Assert.assertEquals(result, 1);

            //等价于:

            if(result == 1){

                System.out.println("sub()方法正确");

            }

        }

    }

      

    同理:别的注解用法我们用一个类来看:

    public class JunitTest {

        public JunitTest() {

            System.out.println("构造函数");

        }

        @BeforeClass

        public static void beforeClass(){

            System.out.println("@BeforeClass");

        }

         

        @Before

        public void befor(){

            System.out.println("@Before");

        }

         

        @Test

        public void test(){

            System.out.println("@Test");

        }

         

        @Ignore

        public void ignore(){

            System.out.println("@Ignore");

        }

         

        @After

        public void after(){

            System.out.println("@After");

        }

         

        @AfterClass

        public static void afterClass(){

            System.out.println("@AfterClass");

        }

    }

      结果为:

    @BeforeClass

    构造函数

    @Before

    @Test

    @After

    @AfterClass

      

    注意:编写测试类的原则: 

        ①测试方法上必须使用@Test进行修饰

            ②测试方法必须使用public void 进行修饰,不能带任何的参数

            ③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开

            ④测试类所在的包名应该和被测试类所在的包名保持一致

            ⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖

            ⑥测试类使用Test作为类名的后缀(不是必须)

            ⑦测试方法使用test作为方法名的前缀(不是必须)

    Junit单元测试执行的顺序

    • 在写JUnit测试用例时,有时候需要按照定义顺序执行我们的单元测试方法.
    • 比如如在测试数据库相关的用例时候要按照测试插入、查询、删除的顺序测试。
    • 如果不按照这个顺序测试可能会出现问题,比如删除方法在前面执行,后面的方法就都不能通过测试.
    • 因为数据已经被清空了。而JUnit测试默认的顺序是随机的。所以这时就需要有办法要求JUnit在执行测试方法时按照我们指定的顺序来执行。
    • 按照设计原则,JUnit是不指定测试方法调用执行顺序的。
    • 目前为止,这些方法只是简单地按照反射(reflection) API返回的顺序执行。
    • 但是,使用JVM默认提供的排序是很不明智的,因为Java平台没有指定任何有规律的顺序,
    • 而事实上JDK 7可能会返回一个随机的顺序。
    • 当然,精心编写的测试代码之间并不需要假定任何执行顺序,但有时候,但在某些平台上一个可预测的失败总比随机的失败要好。
    • 本例通过Junit的@FixMethodOrder注解来设定单元测试中方法的执行顺序
    • 可以看到,DefaultOrderTest 和 NotSettingOrderTest 执行结果是一样的
    • JVMOrderTest每次返回不同的结果
    • NameAscOrderTest返回的是按照方法名称的字典序执行的结果

      

    不指定顺序 : 从4.11版本开始,JUnit将默认使用一个确定的,但不可预测的顺序。执行顺序同DefaultOrderTest

    public class NotSettingOrderTest {
    
        @Test
        public void one() {
            System.out.println("1");
        }
        @Test
        public void two() {
            System.out.println("2");
        }
        @Test
        public void three() {
            System.out.println("3");
        }
        @Test
        public void four() {
            System.out.println("4");
        }
    
        /**
         * 无论执行多少次,结果始终为:
         1
         2
         4
         3
         */
    }


    MethodSorters.DEFAULT : 默认的顺序执行 执行顺序同NotSettingOrderTest@FixMethodOrder(MethodSorters.DEFAULT)

    public class DefaultOrderTest {
        @Test
        public void one() {
            System.out.println("1");
        }
        @Test
        public void two() {
            System.out.println("2");
        }
        @Test
        public void three() {
            System.out.println("3");
        }
        @Test
        public void four() {
            System.out.println("4");
        }
    
        /**
         * 每次执行结果都是:
         1
         2
         4
         3
         */
    }


    MethodSorters.JVM : 保留测试方法的执行顺序为JVM返回的顺序。每次测试的执行顺序有可能会所不同。

    @FixMethodOrder(MethodSorters.JVM)
    public class JVMOrderTest {
        @Test
        public void one() {
            System.out.println("1");
        }
        @Test
        public void two() {
            System.out.println("2");
        }
        @Test
        public void three() {
            System.out.println("3");
        }
        @Test
        public void four() {
            System.out.println("4");
        }
    
        /**
         * 每次执行结果都有可能不一样
         */
    }


    MethodSorters.NAME_ASCENDING : 按照方法名的字典顺序升序执行

    @FixMethodOrder(MethodSorters.NAME_ASCENDING)
    public class NameAscOrderTest {
        @Test
        public void one() {
            System.out.println("1");
        }
        @Test
        public void two() {
            System.out.println("2");
        }
        @Test
        public void three() {
            System.out.println("3");
        }
        @Test
        public void four() {
            System.out.println("4");
        }
    
        /**
         * 无论执行多少次,都是按照方法名字的字典序执行:
         4
         1
         3
         2
         */
    }
    正因为当初对未来做了太多的憧憬,所以对现在的自己尤其失望。生命中曾经有过的所有灿烂,终究都需要用寂寞来偿还。
  • 相关阅读:
    Bootstrap组件---nav(导航条)
    (2)基于Bootstrap的网页开发
    Bootstrap组件简要汇总解析(不定期更新)
    知识碎片(长期更新)
    DOM中document对象的常用属性方法总结
    IE678如何兼容css3圆角属性
    17年面试问题总结
    0.1 js复习
    Basic knowledge about energy field
    BDA: single parameter models
  • 原文地址:https://www.cnblogs.com/candlia/p/11919935.html
Copyright © 2011-2022 走看看