- 以JUnit为例,学习单元测试相关知识
JUnit
什么是单元测试
写了个类,要给别人用,会不会有bug?怎么办?测试一下。
用main方法测试好不好?不好!
- 不能一起运行!
- 大多数情况下需要人为的观察输出确定是否正确
为什么要进行单元测试
- 重用测试,应付将来的实现的变化。
- 提高士气,明确知道我的东西是没问题的。
测试用例是不是用来证明你是对的,而是用来证明你没有错
JUnit4 HelloWorld
- new project
- 建立类
- 建立testcase
放弃旧的断言,使用hamcrest断言
1 | assertThat( n, allOf( greaterThan(1), lessThan(15) ) ); |
b.
1 | assertThat( str, containsString( "bjsxt" ) ); |
c.
1 | assertThat( d, closeTo( 3.0, 0.3 ) ); |
d.
1 | assertThat( map, hasEntry( "bjsxt", "bjsxt" ) ); |
Failure和Error
- Failure是指测试失败
- Error是指测试程序本身出错
JUnit4 Annotation
- @Test: 测试方法
- (expected=XXException.class)
- (timeout=xxx)
- @Ignore: 被忽略的测试方法
- @Before: 每一个测试方法之前运行
- @After: 每一个测试方法之后运行
- @BeforeClass: 所有测试开始之前运行
- @AfterClass: 所有测试结束之后运行
运行多个测试
注意–遵守约定
- 类放在test包中
- 类名用XXXTest结尾
- 方法用testMethod命名
其他框架
TestNG
下面是一些具体的编写测试代码的技巧或较好的实践方法:
- 不要用TestCase的构造函数初始化Fixture,而要用setUp()和tearDown()方法。
- 不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。
- 避免编写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,就不要提交交易数据。简单的回滚就可以了。
- 当继承一个测试类时,记得调用父类的setUp()和tearDown()方法。
- 将测试代码和工作代码放在一起,一边同步编译和更新。(使用Ant中有支持junit的task. )
- 测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。
- 确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
- 如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。
- 尽可能地利用JUnit提供地assert/fail方法以及异常处理的方法,可以使代码更为简洁。
- 测试要尽可能地小,执行速度快。
- 不要硬性规定数据文件的路径。
- 利用Junit的自动异常处理书写简洁的测试代码事实上在Junit中使用try-catch来捕获异常是没有必要的,Junit会自动捕获异常。那些没有被捕获的异常就被当成错误处理。
- 充分利用Junit 的assert/fail 方法assertSame()用来测试两个引用是否指向同一个对象
assertEquals()用来测试两个对象是否相等.- 确保测试代码与时间无关.
- 使用文档生成器做测试文档。