初学JUnit

  • 以JUnit为例,学习单元测试相关知识

JUnit

什么是单元测试

写了个类,要给别人用,会不会有bug?怎么办?测试一下。
用main方法测试好不好?不好!

  1. 不能一起运行!
  2. 大多数情况下需要人为的观察输出确定是否正确

为什么要进行单元测试

  1. 重用测试,应付将来的实现的变化。
  2. 提高士气,明确知道我的东西是没问题的。

测试用例是不是用来证明你是对的,而是用来证明你没有错

JUnit4 HelloWorld

  1. new project
  2. 建立类
  3. 建立testcase

放弃旧的断言,使用hamcrest断言

  1. assertThat
  2. 使用hamcrest的匹配方法–更自然
  3. 示例

    a.

1
2
3
4
5
assertThat( n, allOf( greaterThan(1), lessThan(15) ) );
assertThat( n, anyOf( greaterThan(16), lessThan(8) ) );
assertThat( n, anything() );
assertThat( str, is( "bjsxt" ) );
assertThat( str, not( "bjxxt" ) );

b.

1
2
3
4
5
6
assertThat( str, containsString( "bjsxt" ) );
assertThat( str, endsWith("bjsxt" ) );
assertThat( str, startsWith( "bjsxt" ) );
assertThat( n, equalTo( nExpected ) );
assertThat( str, equalToIgnoringCase( "bjsxt" ) );
assertThat( str, equalToIgnoringWhiteSpace( "bjsxt" ) );

c.

1
2
3
4
5
assertThat( d, closeTo( 3.0, 0.3 ) );
assertThat( d, greaterThan(3.0) );
assertThat( d, lessThan (10.0) );
assertThat( d, greaterThanOrEqualTo (5.0) );
assertThat( d, lessThanOrEqualTo (16.0) );

d.

1
2
3
4
assertThat( map, hasEntry( "bjsxt", "bjsxt" ) );
assertThat( iterable, hasItem ( "bjsxt" ) );
assertThat( map, hasKey ( "bjsxt" ) );
assertThat( map, hasValue ( "bjsxt" ) );

Failure和Error

  1. Failure是指测试失败
  2. Error是指测试程序本身出错

JUnit4 Annotation

  1. @Test: 测试方法
    1. (expected=XXException.class)
    2. (timeout=xxx)
  2. @Ignore: 被忽略的测试方法
  3. @Before: 每一个测试方法之前运行
  4. @After: 每一个测试方法之后运行
  5. @BeforeClass: 所有测试开始之前运行
  6. @AfterClass: 所有测试结束之后运行

运行多个测试

注意–遵守约定

  1. 类放在test包中
  2. 类名用XXXTest结尾
  3. 方法用testMethod命名

其他框架

TestNG

下面是一些具体的编写测试代码的技巧或较好的实践方法:

  1. 不要用TestCase的构造函数初始化Fixture,而要用setUp()和tearDown()方法。
  2. 不要依赖或假定测试运行的顺序,因为JUnit利用Vector保存测试方法。所以不同的平台会按不同的顺序从Vector中取出测试方法。
  3. 避免编写有副作用的TestCase。例如:如果随后的测试依赖于某些特定的交易数据,就不要提交交易数据。简单的回滚就可以了。
  4. 当继承一个测试类时,记得调用父类的setUp()和tearDown()方法。
  5. 将测试代码和工作代码放在一起,一边同步编译和更新。(使用Ant中有支持junit的task. )
  6. 测试类和测试方法应该有一致的命名方案。如在工作类名前加上test从而形成测试类名。
  7. 确保测试与时间无关,不要依赖使用过期的数据进行测试。导致在随后的维护过程中很难重现测试。
  8. 如果你编写的软件面向国际市场,编写测试时要考虑国际化的因素。不要仅用母语的Locale进行测试。
  9. 尽可能地利用JUnit提供地assert/fail方法以及异常处理的方法,可以使代码更为简洁。
  10. 测试要尽可能地小,执行速度快。
  11. 不要硬性规定数据文件的路径。
  12. 利用Junit的自动异常处理书写简洁的测试代码事实上在Junit中使用try-catch来捕获异常是没有必要的,Junit会自动捕获异常。那些没有被捕获的异常就被当成错误处理。
  13. 充分利用Junit 的assert/fail 方法assertSame()用来测试两个引用是否指向同一个对象
    assertEquals()用来测试两个对象是否相等.
  14. 确保测试代码与时间无关.
  15. 使用文档生成器做测试文档。