JUnit 单元测试

测试的分类:
[url]http://stackoverflow.com/questions/520064/what-is-unit-test-integration-test-smoke-test-regression-test[/url]
[url]http://stackoverflow.com/questions/4904096/whats-the-difference-between-unit-functional-acceptance-and-integration-test[/url]
[url]http://stackoverflow.com/questions/3370334/difference-between-acceptance-test-and-functional-test[/url][quote]Unit test
Integration test
Functional & Acceptance test
Regression test
and so on
[/quote]Unit test and Integration test 的详细对比:
[url]http://zeroturnaround.com/rebellabs/the-correct-way-to-use-integration-tests-in-your-build-process/[/url]


[b]Martin Fowle - Mocks Aren't Stubs:[/b]
[url]http://martinfowler.com/articles/mocksArentStubs.html[/url]


Mock frameworks of Unit Test: [b][color=brown]Mockito[/color] JMockit[/b] EasyMock Jmock and so on.


junit3及之前,遵从“约定优于配置”的原则,单元测试类一般遵从以下原则:[quote]1 单元测试类继承 junit.framework.TestCase
2 单元测试类命名为 [b][被测试的类的类名]Test[/b]
3 测试方法(必须)命名为 [b]test[业务逻辑模块][/b],并且为 public void 的
4 failing开头的测试方法会被skipped/ignored[/quote]

junit4之后,引入的注解的方式。如果你使用的是4+的junit,请优先选择注解的方式,原因见:
[url]http://stackoverflow.com/questions/2635839/junit-confusion-use-extend-testcase-or-test[/url][quote]The @Test annotaton is more explicit and is easier to support in tools (for example it's easy to search for all tests this way)
Multiple methods can be annotated with @Before/@BeforeClass and @After/@AfterClass providing more flexibility
Integrated support for testing for expected exceptions using expected=
Support for the @Ignored annotation[/quote]比如,如果使用的是3的格式,则若单元测试类中没有任何test开头的测试方法的话,直接在单元测试类上run as - junit test 是会报下面错误的:
junit.framework.AssertionFailedError: No tests found in com.xxx.MailComposeTest
如果项目是基于maven的,这点尤其烦人,因为会发生 mvn test 失败的事情。如果是用 4 的话,在单元测试类上加一个 @Ignored ,就可以轻松的忽略掉该单元测试类,使之不会被mvn test所测试。
附:
How to skip a test case in Junit
[url]http://junit.org/node/291[/url]
4的方式,单元测试类是不需要继承TestCase的,可以是普通的java类;加在测试方法上的@Test即是单元测试的入口;测试类上可以通过加@RunWith(如@RunWith(value=SpringJUnit4ClassRunner.class))来指定junit内置runner之外的其他runner。另外切记:请不要混合使用3的 [color=red][i]extends TestCase[/i][/color] 和4的 [color=red][i]@Test[/i][/color],即不要这样做:测试类继承了TestCase,而其中的测试方法又添加了@Test注解。因为如果你这样做了的话,你会发现那些未遵循3的测试方法命名规范(形如testXxx)的方法,是无法被执行单元测试的,尽管它已经被添加了@Test注解!(遵循了3的测试方法命名规范的方法可以被执行单元测试,这说明,混合使用3的 [color=red][i]extends TestCase[/i][/color] 和4的 [color=red][i]@Test[/i][/color]最终用的是3的方式,4的方式变得不再起作用)。
另小注:4注解的@Ignore不存在与3的配置的冲突。


测试结果为Failures和Errors的单元测试都被认为是失败的单元测试,都是会造成maven项目build失败的。
测试方法中如果捕获到了Exception(并且未catch),则测试结果为Errors;有时你可能不希望某类异常造成Junit测试的失败,比如自定义的(继承了runtimeexception的)unchecked exception,则使用4的注解的方式,就可以轻松的将某类异常忽略掉,使其不至于导致单元测试的失败。具体有两种配置方式可供选择:
[url]http://stackoverflow.com/questions/11426042/good-practice-for-testing-exceptions-in-junit[/url][quote]

@Rule
public ExpectedException exception = ExpectedException.none();

@Test
public void checkNullObject() throws CustomException {
exception.expect(CustomException .class);
MyClass myClass= null;
MyCustomClass.get(null);
}
@Test(expected=CustomException.class)
public void checkNullObject() throws CustomException {
MyClass myClass= null;
MyCustomClass.get(null);
}
两种方式孰优孰劣参见链接出处[/quote]


[color=red][b]当Junit遇到System.exit():[/b][/color]
单元测试的时候经常会碰到某个方法在某些分支会调用System.exit(exitcode)方法,而一旦程序运行到System.exit()方法,整个JVM就退出了,而junit也是运行于此JVM之上,即整个测试就(无任何返回结果地)终止了。
Junit+System.exit()会jvm退出、测试终止,但在eclipse(3.7 indigo)下,有个很奇怪的现象:"Stop Junit Test Run"按钮会一直保持在可点击状态,给人一种“单元测试并未终止只是被挂起无法继续执行下去”的错觉:
[img]http://dl.iteye.com/upload/attachment/0076/0184/88673683-2e1a-3693-88f6-9885a88f786f.png[/img]
这应该是eclipse的bug:jvm退出,单元测试被强制终止,没有任何的单元测试结果被返回(success、errors、failures,etc),而"Stop Junit Test Run"按钮的状态是基于单元测试的返回结果的,无结果返回,无按钮状态变化。
解决办法:
[url]http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit[/url][quote]其中的最佳答案给出的两个解决思路不错:
1 程序中不要使用System.exit(),而改为抛出一个unchecked exception,如抛出本博文上面部分说的一个自己定义的runtimeexception的子类:SomeAppException,并将测试方法声明为对SomeAppException是expected的。
2 在单元测试类中使用SecurityManager,来让单元测试方法可以检测到System.exit()调用,在jvm因其退出前可以做些额外的处理工作[/quote]


[color=red][b]Junit与多线程:[/b][/color]
Junit的测试主线程,在最后是通过执行System.exit(0)来退出的。System.exit是直接退出jvm,所以,如果测试运行期间你启动了其他线程(且未join入测试主线程),则这些线程就都因为jvm的退出而无法再执行下去。参考资料:
[url]http://www.iteye.com/topic/154410[/url]
另外,junit测试主线程之外的其他线程抛出的Unckecked Exceptions,junit是捕获不到的。这里有个很经典的例子:
[url]http://stackoverflow.com/questions/4039873/weird-problem-using-junit-in-multi-thread-environment[/url]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值