经过研究junit3.8的源代码,学习了junit的测试思想。在此做成一个总结:
1.junit中测试单位分成两种:
TestCase 与 TestSuite
其中TestCase为最小的测试单位,即:每个单元测试的最小功能模块。说到这里,大家可能会想到那么我们平时写的测试类不就是一个最小测试单位吗。例如:
package onlyfun.caterpillar.test;
import onlyfun.caterpillar.MathTool;
import junit.framework.TestCase;
public class MathToolTest extends TestCase {
public MathToolTest(String testMethod) {
super(testMethod);
}
public void testGcd() {
assertEquals(5, MathTool.gcd(10, 5));
}
public static void main(String[] args) {
junit.textui.TestRunner.run(MathToolTest.class);
}
}
那么 MathToolTest这个类不就是最小的测试单位吗。这里要着重说明下,最小的测试单位是每一个方法。
具体大家可以看看junit源代码TestCase 类,TestCase类中有一个private String fName;
这个成员变量指出了此TestCase对应的method:(这里就是
public MathToolTest(String testMethod) {
super(testMethod);
}
这段代码指定方法名的用途 ).
下面说说TestSuite我们测试的时候不可能一个个最小的单元测试模块TestCase这样运行吧(注意:这里TestCase指的是每一个方法)。于是TestSuite出现了。它将多个TestCase整合起来一起测试。可能你会说junit.swingui.TestRunner.run(ChartServiceImplTest.class);
我这样运行的junit没有写TestSuite啊。让我们看看源代码:
BaseTestRunner类中
synchronized public void runSuite() {
if (fRunner != null) {
fTestResult.stop();
} else {
setLoading(shouldReload());
reset();
showInfo("Load Test Case...");
final String suiteName= getSuiteText();
final Test testSuite= getTest(suiteName);
if (testSuite != null) {
addToHistory(suiteName);
doRunTest(testSuite);
}
}
}
...........................
/**
* Returns the Test corresponding to the given suite. This is
* a template method, subclasses override runFailed(), clearStatus().
*/
public Test getTest(String suiteClassName) {
if (suiteClassName.length() <= 0) {
clearStatus();
return null;
}
Class testClass= null;
try {
testClass= loadSuiteClass(suiteClassName);
} catch (ClassNotFoundException e) {
String clazz= e.getMessage();
if (clazz == null)
clazz= suiteClassName;
runFailed("Class not found \""+clazz+"\"");
return null;
} catch(Exception e) {
runFailed("Error: "+e.toString());
return null;
}
Method suiteMethod= null;
try {
suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
} catch(Exception e) {
// try to extract a test suite automatically
clearStatus();
return new TestSuite(testClass);
}
if (! Modifier.isStatic(suiteMethod.getModifiers())) {
runFailed("Suite() method must be static");
return null;
}
Test test= null;
try {
test= (Test)suiteMethod.invoke(null, (Object[])new Class[0]); // static method
if (test == null)
return test;
}
catch (InvocationTargetException e) {
runFailed("Failed to invoke suite():" + e.getTargetException().toString());
return null;
}
catch (IllegalAccessException e) {
runFailed("Failed to invoke suite():" + e.toString());
return null;
}
clearStatus();
return test;
}
哈哈,还是没有逃脱生成TestSuite的魔爪吧。只不过可能一个是你自己写的一个是默认生成的这点区别而已。
2.好了通过上面的一个介绍,不知道大家对于junit的运行是否有了一个概要的思路。下面我们说下TestSuite的生成方式:
junit.textui.TestRunner.run(ChartServiceImplTest.class);
这样调用的方式在1中说明了,是junit框架自己生成的TestSuite对象。生成的过程如下:
首先查看该类中是否包含了public static Test suite() 方法,如果包含了,直接采用此处方法生成的Test对象(即:TestSuite)对象。如下:
public class ChartServiceImplTest extends TestCase {
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTestSuite(ChartServiceImplTest.class);
suite.addTest(new ChartServiceImplTest("testMethod"));
return suite;
}
public void testQueryChartList() {
fail("Not yet implemented");
// assertEquals(true,true);
}
public ChartServiceImplTest(String methodName){
super(methodName);
}
}
如果不包含,则采用类反射方式查询TestCase中test开头的方法,封装成一个个的Testcase,然后统一生成TestSuite.
Testcase对象中包含了一个变量private String fName;运行时将根据fName查找Testcase对象中的名称为fName的方法,然后采用类反射的方式运行该方法(即:执行test开头的测试方法)。
3.通过查看可以得出:
public static Test suite() {
TestSuite suite= new TestSuite();
suite.addTestSuite(ChartServiceImplTest.class);
suite.addTest(new ChartServiceImplTest("testMethod"));
return suite;
}
suite对象可以包含suite对象,也可以包含TestCase对象。这里大家看到了这个地方
suite.addTestSuite(ChartServiceImplTest.class);恐怕会问:怎么是suite对象呢。
我们看下源代码: /**
* Adds the tests from the given class to the suite
*/
public void addTestSuite(Class testClass) {
addTest(new TestSuite(testClass));
}
/**
* Adds a test to the suite.
*/
public void addTest(Test test) {
fTests.addElement(test);
}
大家看出来了吧,先转换为TestSuite对象的。
ok继续研究:addTest方法其实但是为Test类类型,我们查看Test类源代码:
/**
* A <em>Test</em> can be run and collect its results.
*
* @see TestResult
*/
public interface Test {
/**
* Counts the number of test cases that will be run by this test.
*/
public abstract int countTestCases();
/**
* Runs a test and collects its result in a TestResult instance.
*/
public abstract void run(TestResult result);
}
可以看出,TestSuite与TestCase对象都将运行public abstract void run(TestResult result)这个方法。TestResult 对象可以控制控制台或者swing界面,从而控制显示正确与错误.好了说到有点乱。
总结说就是:TestRunner将会运行TestSuite的run(TestResult result)方法。
1.而这个TestSuite本身内部有包含了TestSuite与TestCase对象,所以:
2.这个TestSuite的run(TestResult result)实现中:
运行其包含的TestCase的run(TestResult result)方法
运行其包含的TestSuite的run(TestResult result)方法(这个回到步骤1(源代码实现就是如此))
4.junit运行方式:
junit.textui.TestRunner.run(ChartServiceImplTest.class);
junit.awtui.TestRunner.run(ChartServiceImplTest.class);
junit.swingui.TestRunner.run(ChartServiceImplTest.class);
大家不妨看啊看看 junit.swingui.TestRunner源代码,如果swing学得好的话,自己也能写出一个junit测试展示。(eclipse的junit插件不就是如此吗)
分享到:
相关推荐
junit测试的一点心得,在spring中加载外部配置文件是的一点小技巧junit测试
这篇博客“学习JUnit4过程中的总结”可能是作者在深入研究JUnit4后的一些心得体验和技巧分享。下面我们将深入探讨JUnit4的核心特性、如何使用以及它在软件开发中的重要性。 首先,JUnit4引入了注解(Annotation)的...
- `提纲.doc`可能包含对JUnit学习的结构化大纲,帮助系统学习。 - `testingandroid-090828164936-phpapp02.pdf`可能是关于Android测试的详细指南,可能涵盖JUnit在Android开发中的实践。 - `Fibonacci.pdf`可能...
- **JUnit**:常用的单元测试框架,用于编写测试用例。 - **Espresso**:Android官方提供的用于UI测试的框架。 - **Mockito**:用于创建模拟对象的库,方便测试依赖的组件。 ### 十五、NotificationManager and ...
标题 "ANT学习心得【第一部分】" 暗示了我们即将探讨的是Apache Ant,一个广泛使用的Java构建工具。在Java开发中,Ant是管理项目编译、打包、测试等任务的重要工具,它通过XML配置文件来定义构建过程。这篇博文可能...
本实验报告的主要目的是掌握单元测试的方法,并学习如何在Eclipse中使用Junit进行测试。通过对Calculator类的测试,掌握了Junit单元测试的技术。 一、实验步骤和结果 1. 修改之前的Calculator类的测试结果 在本...
【Java学习心得】 Java是一种广泛使用的面向对象的编程语言,对于初学者来说,掌握Java的基础和进阶知识至关重要。以下是我作为一个经验丰富的开发者在Java学习过程中的几点心得体会: 1. **基础牢固**:学习Java...
这篇“JUnit使用札记”可能是博主在实践中总结的一些关于如何有效利用JUnit进行测试的心得体会。博客链接虽然无法直接访问,但从标题我们可以推测文章可能包含了JUnit的基本用法、关键特性和最佳实践。 JUnit的核心...
这篇博客文章的作者在分享自己的学习心得,认为JUnit是一个非常有用且值得推荐的工具。从标签“源码”和“工具”我们可以推测,文章可能涉及了JUnit的源码分析以及如何在实际开发中应用它。 JUnit测试框架的核心...
这个应用包含了完整的源代码、使用手册以及开发者的心得体会,对于学习Android移动软件开发的学生来说,这是一个宝贵的资源。以下是关于这个项目的详细知识点: 1. **Android应用程序开发基础**:首先,你需要了解...
### CMMI 三级认证PI学习心得 #### 一、引言 在软件开发与管理领域,CMMI(Capability Maturity Model Integration)被广泛认可为一个衡量组织成熟度的标准模型。其中,产品集成(Product Integration, PI)作为CMMI...
本文将从我的个人经验出发,分享在学习日语和进行对日Java开发过程中的一些心得体会。 首先,语言是沟通的桥梁。在对日Java开发中,语言能力的重要性不言而喻。不仅要理解日语技术文档,还要与日本客户或团队成员...
在单元测试方面,JUnit是Java中广泛使用的测试框架,测试方法必须是public的,返回类型为void,且无参数。例如,一个错误的示例是试图对未初始化的List对象调用`add()`方法,这会导致空指针异常。正确做法应是实例化...
"Junit学习笔记.mht"可能是一位经验丰富的开发者对JUnit使用的心得体会,包含了一些实战中的技巧和最佳实践,如如何编写可读性高的测试代码,如何组织测试结构,以及如何利用JUnit与其他工具(如IDEs)集成等。...
6. **测试工具**:JUnit等测试框架利用反射访问私有方法,进行单元测试。 7. **插件系统**:在插件系统中,通过反射加载和调用插件类,实现动态加载功能。 8. **日志框架**:如Log4j,通过反射获取日志记录方法,...
14. **单元测试**:JUnit是Java的单元测试框架,通过编写测试用例来验证代码功能,确保代码质量。 15. **Maven与Gradle**:这两个构建工具简化了项目依赖管理和构建过程,使得大型项目的管理更加方便。 以上只是...
学习如何使用JUnit、Selenium或其他测试工具,以及理解测试金字塔模型,能够帮助开发者确保软件的稳定性和可靠性。 数据分析部分可能涵盖了数据清洗、预处理、建模和可视化等步骤。使用Excel、Python的Pandas库或R...
在这个"Selenium练习源码含心得注释"的压缩包中,我们可以期待找到一系列的Selenium实战代码示例,以及作者在学习过程中的心得体会。 首先,让我们了解Selenium的基本概念。Selenium支持多种编程语言,如Python、...