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

举报
码农飞哥 发表于 2021/05/29 12:47:06 2021/05/29
【摘要】 上一篇我们总体了解了下junit框架的相关知识。这一篇我们将具体来分析相关的知识点。 我们将从以下几个方面来分析 1. junit的运行流程 2. junit的主要类的具体分析。 junit的运行流程 为了更好的分析junit的运行流程,我们先写一个测试类。 被测试类Calculator /** * Created by xiang.wei on 201...

上一篇我们总体了解了下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; }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

测试类

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("测试结束"); }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

测试结果:
测试结果
让我们通过断点调试来开始一段调试之路。
例如:要执行testAdd这个测试用例的话,中间到底要经历哪些过程呢?
1. 测试用例

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

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. 入口程序 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; }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  1. TestCase 类的run方法
public abstract class TestCase extends Assert implements Test{ public void run(TestResult result) { result.run(this); }
}
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  1. 调用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); } }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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; } }
 }
  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  1. 最后一步,调用ResultPrinter类的print方法,打印输出结果
 synchronized void print(TestResult result, long runTime) { printHeader(runTime); printErrors(result); printFailures(result); printFooter(result); }


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

总结:从上述源码中我们可以看出TestResultTestCase直接存在双向依赖的联系。此处我觉得作者应该是为了提高代码的复用性。
junit的介绍就到此为止,欢迎各位批评指正。

文章来源: feige.blog.csdn.net,作者:码农飞哥,版权归原作者所有,如需转载,请联系作者。

原文链接:feige.blog.csdn.net/article/details/79654127

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。