Unit Test Framework

今天看了两篇关于javascript unit test framework的文章,例如http://www.netmagazine.com/features/essential-javascript-top-five-testing-librarieshttp://stackoverflow.com/questions/300855/looking-for-a-better-javascript-unit-test-tool。

看着看着,我就在想Unit Test Framework到底应该做什么,包含哪些功能。归纳了下用过的,或者学过的几个框架,我想一个UT框架,应该有下面几部分功能吧:

1. Test Runner

我认为Test Runner就是获取测试集,驱动测试用例执行,并把运行结果反馈给用户的模块。

例如JUnit/CppUnit,本身都支持两种Runner:命令行的和图形界面的。JsUnit,是在浏览器中可以手工驱动。JsTestDriver,是一个C/S的架构,它不仅可以使用自己的Test Case定义语法,也可以配合使用Jasmine。testAcular则更进一步,它只是TestRunner,可以配合其他各种UT框架。Android JUnit中,则虽然使用了JUnit的Test Case定义方式,但有独立的instrumentationtestrunner以作用于android系统。

Test Runner经常会被定制。例如,Junit就有专门针对Eclipse的Runner。而很多公司内部,都会把测试结果发到一个服务器上去,而不仅仅是本地查看,或者有另外一套build语法来指定测试集,也可以通过定制test runner来实现。

2. Test Suite/Case

为了管理Test Case,需要把他们分组。

于是,JUnit通过composite模式多层管理Test Case。但JsUnit则只有两层:即页面和Test Case。gTest也只有Fixture和Test Method两层。

3. Assert Verification

基本的相等,大于,小于,浮点计算。有的区分equal和be,前者比较指针/引用,后者比较具体值。

Mocha并没有自己的asset模块,而只是调用别的工具的或系统的。

4. Mock

绝大多数UT框架都没有自带的Mock工具,但自带一个Mock工具一个很大优点:Mock中很复杂的Match模块跟UT中的Assert模块可以相当大程度的复用代码。Jasmine即利用了这点。

“Mock”这个名字很不合理,因为所有Mock工具,都同时提供Stub/Mock的功能,所以我觉得叫做Test Double工具更好。

至于其实现,一大类方式是使用Record/Replay,即第一阶段记录好预期的行为,然后执行操作,最后验证预期行为是否被执行。我不是很喜欢这种方式,因为倾向于基于行为的验证。代表则是最有名的EasyMock。

另外一大类则是以mockito为代表。其默认为test double类提供dummy的实现(空实现),然后可以为每个函数以stub方式定义返回值。然后执行操作,并以spy方式记录操作过程。它鼓励基于状态的验证,如果真的需要做基于行为的验证,可以在最后check spy记录的调用过程。Jasmine则直接将其mock系统称为spy。

有的mock为了更好的表达函数是否以期望的参数被调用,有自己的asset模块,例如sinon。

5. 总结

我觉得以上四个模块可以自由组合,一个工具可以只提供一个模块,或者提供全部四个模块。事实上,多数UT框架是同时提供前面三个模块。

你可能感兴趣的:(test,unit)