【Java】著名的单元测试框架JUnit及其生命周期使用

版权声明:本文为博主原创文章,转载复制标题加链接即可√ https://blog.csdn.net/qazcxh/article/details/49849931

【Java】著名的单元测试框架JUnit及其生命周期使用

JUnit是一个Java语言的单元测试框架。大部分的Java开发环境都支持JUnit测试框架。它的优点,我们并不需要编写一些测试的代码来进行测试,只需要在测试的方法上方加上一个@Test注解,然后加上一些参数,你就可以对这段代码进行测试,非常方便。当然需要JDK支持@Annotation注解,目前大部分的JDK都是支持的了。所以这点放心。

  • 无需编写测试代码
  • 测试只需添加简单注解
  • 专属的JUnit界面供查询

所需的工具

  • 支持JUnit的eclipse 也就是你在new里面可以找到JUnit
  • 支持@Annotation注解的JDK JDK5.0以上都支持

简易的JUnit

首先定义一个Person的接口用来描述人的若干行为,用来对Person接口进行测试。其包括年龄,姓名,行走,讲话等。

代码块Person.java

/**
 * 
 */
package jUnitTest;

/**
 * @author CXH
 *
 */
public interface Person {

    public int getAge();//获取年龄
    public String getName();//获取姓名
    public String talkTo(String message);//讲话
    public void walk();//行走
}

接着,对Person就口给予实现。

代码块PersonImpl.java

/**
 * 
 */
package jUnitTest;

/**
 * @author CXH
 * PersonImpl的实现Person代码
 */
public class PersonImpl implements Person {

    /**
     * 
     */
    private int age;
    private String name;

    public PersonImpl(String name,int age) {
        this.age = age;
        this.name = name;
    }

    /* (non-Javadoc)
     * @see jUnitTest.Person#getAge()
     */
    @Override
    public int getAge() {
        return this.age;
    }

    /* (non-Javadoc)
     * @see jUnitTest.Person#getName()
     */
    @Override
    public String getName() {
        return this.name;
    }

    /* (non-Javadoc)
     * @see jUnitTest.Person#talkTo(java.lang.String)
     */
    @Override
    public String talkTo(String message) {
        System.out.println("PersonImpl.talkTo()");
        return message;
    }

    /* (non-Javadoc)
     * @see jUnitTest.Person#walk()
     */
    @Override
    public void walk() {
        System.out.println("PersonImpl.walk()");

    }

}

使用@Test标签标注测试方法

建立一个简单的测试Person各个行为的用例。

  • 基本测试,即为执行(与定义main()方法类似)
  • 限时,测试方法效率。测试walk方法是否能在给定的时间内完成
  • 异常测试,验证方法能否抛出预期的错误。 测试Person的Talk行为除了以“Hello”开始的入参 以外都要拒绝对方抛出IllegalArgumentException,使用@Test的expected属性可以完成异常测试的需求, 接受异常的class

JUnit代码如下:

代码块PersonTest.java

/**
 * 
 */
package jUnitTest;

import org.junit.*;

/**
 * @author CXH
 * 
 */
public class PersonTest {

    private Person person;
    @Before
    public void buildPerson() {
        person = new PersonImpl("Willard", 3);

    }
    /**
     * 使用@Test标签标注测试方法
     */
    @Test
    public void testGetAge() {
        int age = person.getAge();
        assertEquals(3,age);

    }
    /**
     * 限时,测试方法效率。
     * 
     * 测试walk方法是否能在给定的时间内完成
     */
    @Test(timeout=200)
    public void testWalk() {
        person.walk();

    }
    /**
     * 异常测试,验证方法能否抛出预期的错误。
     * 
     * 测试Person的Talk行为除了以“Hello”开始的入参
     * 以外都要拒绝对方抛出IllegalArgumentException,
     * 使用@Test的expected属性可以完成异常测试的需求,
     * 接受异常的class
     */
    @Test(expected=IllegalArgumentException.class)  
    public void testTalk(){
        String message = person.talkTo("Jimy");

            assertNotNull(message);
    }

    private void assertNotNull(String message) {
        if (message!="Hello") {
            throw new IllegalArgumentException();
        }else {
            try {

            } catch (IllegalArgumentException e) {
                System.out.println("忽略异常");
            }
        }
    }
    private void assertEquals(int i, int age) {
        if (i==age) {
            System.out.println("PersonTest.assertEquals()");
            System.out.println("年龄匹配");
        }else {
            System.out.println("PersonTest.assertEquals()");
            System.out.println("年龄不匹配");
        }
    }
}

程序结果截图

JUnit程序执行过程
JUnit窗口使用

JUnit的生命周期

  • @BeforeClass:修饰static的方法,在整个类执行之前执行该方法一次。比如你的测试用例执行前需要一些高开销的资源(连接数据库)可以用@BeforeClass搞定。值得注意的是如果测试用例类的父类中也存在@BeforeClass修饰的方法,它将在子类的@BeforeClass之前执行。
  • @AfterClass:同样修饰static的方法,在整个类执行结束前执行一次。如果你用@BeforeClass创建了一些资源现在是时候释放它们了。
  • @Before:修饰public void的方法,在每个测试用例(方法)执行时都会执行。
  • @After:修饰public void的方法,在每个测试用例执行结束后执行。
  • @Test:测试的主函数,相当于main()方法。
  • Constructor:每个测试用例都会重新创建当前的Class实例,可以看到Constructor执行了两次。
    简单理解,就是说每做一个@Test,那么在做之前会调用@Before里的内容,在做之后会调用@After里的内容。而对于同一类里做的多个@Test,做之前只会调用一次@BeforeClass里的内容,做之后只会调用一次@AfterClass里的内容,而且BeforeClass在Before之前,AfterClass在After之后。看流程图理解。

JUnit生命周期流程图

Created with Raphaël 2.1.0 开始 BeforeClass Before Test After i=0;i<Test.sum();i++? AfterClass 结束 yes no

LifeCycleTest.java

/**
 * 
 */
package jUnitTest;

import org.junit.*;

/**
 * @author CXH
 *
 */
public class LifeCycleTest
{

    public LifeCycleTest()
    {
        super();
        System.out.println("<<Person Constructor>>");
    }

    @BeforeClass
    public static void beforeClassM()
    {
        System.out.println("<<Before Class>>");
    }


    @Before
    public void beforeM()
    {
        System.out.println("<<Before>>");
    }


    @AfterClass
    public static void afterClassM()
    {
        System.out.println("<<After Class>>");
    }


    @After
    public void after()
    {
        System.out.println("<<After>>");
    }

    @Test
    public void testMethod1()
    {
        System.out.println("Test Method 1.");
    }

    @Test
    public void testMethod2()
    {
        System.out.println("Test Method 2.");
    }
}

程序结果截图

生命周期使用

猜你喜欢

转载自blog.csdn.net/qazcxh/article/details/49849931