Junit-3.8.1源码分析02----具体分析(执行流程)

简介: 上一篇我们总体了解了下junit框架的相关知识。这一篇我们将具体来分析相关的知识点。

上一篇我们总体了解了下junit框架的相关知识。这一篇我们将具体来分析相关的知识点。

我们将从以下几个方面来分析

1. junit的运行流程

2. junit的主要类的具体分析。


junit的运行流程


为了更好的分析junit的运行流程,我们先写一个测试类。

被测试类Calculator

/**
 * Created by xiang.wei on 2018/3/21
 *
 * @author xiang.wei
 */
public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    public int subtract(int a, int b) {
        return a - b;
    }
    public int multiply(int a, int b) {
        return a * b;
    }
    public int divide(int a, int b) {
        return a / b;
    }
}

测试类

import junit.framework.Assert;
import junit.framework.TestCase;
/**
 * Created by xiang.wei on 2018/3/21
 *
 * @author xiang.wei
 */
public class CalculatorTest  extends TestCase {
    @Override
    public void setUp() throws Exception {
        System.out.println("测试开始");
    }
    public void testAdd()
    {
        Calculator calculator = new Calculator();
        int result = calculator.add(1, 2);
        // 判断方法的返回结果
        Assert.assertEquals(3, result);// 第一个参数是期望值,第二个参数是要验证的值
    }
    public void testSubtract()
    {
        Calculator calculator = new Calculator();
        int result = calculator.subtract(1, 2);
        // 判断方法的返回结果
        Assert.assertEquals(-1, result);// 第一个参数是期望值,第二个参数是要验证的值
    }
    public void testMultiply()
    {
        Calculator calculator = new Calculator();
        int result = calculator.multiply(2, 3);
        // 判断方法的返回结果
        Assert.assertEquals(6, result);// 第一个参数是期望值,第二个参数是要验证的值
    }
    public void testDivide() {
        Calculator calculator = new Calculator();
        int result = calculator.divide(12, 3);
        // 判断方法的返回结果
        Assert.assertEquals(4, result);// 第一个参数是期望值,第二个参数是要验证的值
    }
    public void testFail(){
        fail("失败测试");
    }
    @Override
    public void tearDown() throws Exception {
        System.out.println("测试结束");
    }
}


测试结果:

1b0963496c8e1a61b544f4710e1ec254_70.png

让我们通过断点调试来开始一段调试之路。

例如:要执行testAdd这个测试用例的话,中间到底要经历哪些过程呢?

1. 测试用例

public void testAdd()
    {
        Calculator calculator = new Calculator();
        int result = calculator.add(1, 2);
        // 判断方法的返回结果
        Assert.assertEquals(3, result);// 第一个参数是期望值,第二个参数是要验证的值
    }


入口程序 TestRunner类的doRun方法

public TestResult doRun(Test suite, boolean wait) {
        TestResult result= createTestResult();
        //添加抽象观察者
        result.addListener(fPrinter);
        long startTime= System.currentTimeMillis();
        //执行测试用例
        suite.run(result);
        long endTime= System.currentTimeMillis();
        long runTime= endTime-startTime;
        //打印结果
        fPrinter.print(result, runTime);
        pause(wait);
        return result;
    }

TestCase 类的run方法

public abstract class TestCase extends Assert implements Test{
    public void run(TestResult result) {
        result.run(this);
    }
}


调用TestResult类的run方法,执行具体的测试用例

protected void run(final TestCase test) {
        startTest(test);
        Protectable p= new Protectable() {
            public void protect() throws Throwable {
                //具体运行测试用例,此处调用了TestCase类里的方法
                test.runBare();
            }
        };
        runProtected(test, p);
        endTest(test);
    }
    // 一个测试用例开始前设置一些信息
    public void startTest(Test test) {
        final int count= test.countTestCases();
        synchronized(this) {
            fRunTests+= count;
        }
        for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
            ((TestListener)e.nextElement()).startTest(test);
        }
    }


PS: 具体执行测试用例的方法:

public abstract class TestCase extends Assert implements Test {
    public void runBare() throws Throwable {
        setUp();
        try {
            runTest();
        }
        finally {
            tearDown();
        }
    }
/**
     * Override to run the test and assert its state.
     * @exception Throwable if any exception is thrown
     */
    protected void runTest() throws Throwable {
        assertNotNull(fName);
        Method runMethod= null;
        try {
            // use getMethod to get all public inherited
            // methods. getDeclaredMethods returns all
            // methods of this class but excludes the
            // inherited ones.
            runMethod= getClass().getMethod(fName, null);
        } catch (NoSuchMethodException e) {
            fail("Method \""+fName+"\" not found");
        }
        if (!Modifier.isPublic(runMethod.getModifiers())) {
            fail("Method \""+fName+"\" should be public");
        }
        try {
            runMethod.invoke(this, new Class[0]);
        }
        catch (InvocationTargetException e) {
            e.fillInStackTrace();
            throw e.getTargetException();
        }
        catch (IllegalAccessException e) {
            e.fillInStackTrace();
            throw e;
        }
    }
 }


最后一步,调用ResultPrinter类的print方法,打印输出结果

synchronized void print(TestResult result, long runTime) {
        printHeader(runTime);
        printErrors(result);
        printFailures(result);
        printFooter(result);
    }


总结:从上述源码中我们可以看出TestResult和TestCase直接存在双向依赖的联系。此处我觉得作者应该是为了提高代码的复用性。

junit的介绍就到此为止,欢迎各位批评指正。


相关文章
|
Java 测试技术
Junit单元测试不支持多线程测试--原因分析和问题解决
Junit单元测试不支持多线程测试--原因分析和问题解决
334 0
|
4月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
2月前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
27 5
|
3月前
|
SQL JavaScript 前端开发
基于Java访问Hive的JUnit5测试代码实现
根据《用Java、Python来开发Hive应用》一文,建立了使用Java、来开发Hive应用的方法,产生的代码如下
74 6
|
4月前
|
测试技术
单元测试问题之使用TestMe时利用JUnit 5的参数化测试特性如何解决
单元测试问题之使用TestMe时利用JUnit 5的参数化测试特性如何解决
49 2
|
4月前
|
测试技术
如何使用 JUnit 测试方法是否存在异常
【8月更文挑战第22天】
72 0
|
4月前
|
Java 测试技术 Maven
Junit单元测试 @Test的使用教程
这篇文章是一个关于Junit单元测试中`@Test`注解使用的教程,包括在Maven项目中添加Junit依赖、编写带有@Test注解的测试方法,以及解决@Test注解不生效的常见问题。
|
6月前
|
运维 Java 测试技术
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
Spring运维之boo项目表现层测试加载测试的专用配置属性以及在JUnit中启动web服务器发送虚拟请求
49 3
|
6月前
|
Java Maven Spring
spring如何使用junit进行测试
spring如何使用junit进行测试
spring如何使用junit进行测试
|
6月前
|
Java 测试技术 持续交付
Springboot中JUNIT5单元测试+Mockito详解
Springboot中JUNIT5单元测试+Mockito详解
673 1