单元测试(Unit Testing)基础
来源:互联网 发布:房地产数据分析图片 编辑:程序博客网 时间:2024/04/26 16:03
作者
Richard Paul
Kiwiplan NZ Ltd
27 Feb 2009
单元测试是什么?
在计算机编程里,单元测试是一种用来验证单独的代码是否正确的方法
http://en.wikipedia.org/wiki/Unit_testing
单元测试带来的好处
- 自动化的回归测试,保证代码持续地正常
- 作为代码的一种可运行的,一直保持更新的文档
- 让代码更加稳定,使人能放心重构
- 能与系统的其它部分分开进行测试,并且其它系统部分可能还不存在。
- 更少的BUG!
单元测试与功能测试
单元测试是从程序员的观点来写的,他们保证特定的类或者方法正常地执行一系列指定的任务。
功能测试是由用户的观点而来的, 这些测试确保系统是按用户的需求来运行的。
http://www.ibm.com/developerworks/library/j-test.html
单元测试的结构
- 一个用例一个测试方法
- 测试方法互相独立地运行
public class ItemControllerTest { private ItemController itemController; @Mock private ItemService itemService; private Map<String, Object> modelMap; @Before public void setup(){ itemController = new ItemController(itemService); modelMap = new HashMap<String, Object> (); } @Test public void testViewItem() throws Exception { Item item = new Item(1, "Item 1"); when(ItemService.getItem(item.getId())).thenReturn(item); String view = itemController.viewItem(item.getId(), modelMap); assertEquals(item, modelMap.get("item")); assertEquals("viewItem", view);}
单元测试最佳实践
单元测试应该运行得快
- 允许程序员快速地编程
- 除非真正需要,不要碰到数据库
测试应该只断言其需要的场景
- 包含太多不必要的测试会带来过高的维护
单元测试应与代码同时编写
单元测试应该在代码提交时自动运行
- 使用持续集成的服务器,比如Hudson, Jenkins.
- 快速反馈集成时出现的问题
测试驱动开发
- 添加一个基础测试
- 编写刚好足够通过测试的代码
- 添加另一个测试,重复第二步
测试驱动的优势
- 鼓励你考虑如何使用你的对象
- 开发更快,不需要编译和部署项目来确定一段代码可以运行
- 调试一段单元测试要比调试一个部署好的应用程序要容易得多
- 一系列的回归测试让你重构代码的时候不用担心破坏已有的功能
- 单元测试可以覆盖更多的边缘测试情景,因为作为程度员你更熟悉对象的模型
显示接缝(Seam)
- 接缝是指被测试的代码与其它组件隔离开的分割线
- 与接缝另一面组件的合作应该是可替换的,以确保我们可以隔离想要测试的代码。
- 能表现出接缝的代码可以认为是低耦合的
应用接缝
- 在实际运行中,使用的都是实际的对象。
- 代码有接缝:可以使用模拟的对象(Mock)来替换实际的其它组件进行测试。
- 反模式-静态代码:无接缝,无法替换代码中与其它组件的合作部分,导致复杂冗长的测试代码。
- 本地创建合作对象:无接缝,被测试的类自己创建合作的其它类的对象,我们无法替换这些对象。
反模式(Anti Panttern)更多资料
Static Methods are Death to Testability
http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/
To "new" or not to "new"…
http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/
Mocking框架
Mocking框架提供了便利的方法来来”仿造”其它组件的对象,使得我们能专心测试想要的代码。
这些框架包括
Java
- Mockito
- EasyMock
- JMock
- .Net
.Net
- Moq (需要.Net 3.5)
- Rhino
- TypeMock
实例 - 访问一个合作对象
为了给使用其它服务类的代码提供一个接缝,需要把这些服务类替换出去。
依赖注入
Java
- Spring框架
- Guice
.Net
- SpringFramework.Net
- Castle MicroKernel/Windsor
服务访问
Poor mans dependency injection
实例 - 依赖注入
资源被注入进需要他们的类中
构造器注入
public class ItemController { private ItemService itemService; public ItemController(ItemService itemService) { this.itemService = itemservice; }...
Setter注入
public class ItemController { private ItemService itemService; public ItemController () {} public void setItemService(ItemService itemService) { this.itemService = itemService; }...
实例 - 服务访问
如果你没有依赖注入容器,使用单例模式也对测试有好处
public class ServiceAccess { private ItemService itemService; public static ItemService getItemService() { return itemService; } public void setItemService(ItemService itemService) { ServiceAccess.itemService = itemService; }}
在你的测试里,可以把itemService变成Mock版本,这样就能有接缝了
实例 - 环境
Java : Eclipse, JUnit 4.5, Mockito 2.7
VB.net: Visual Studio 2005, NUnit 2.4, Rhino Mocks 3.5
更多Java相关的例子(Mockito)请参考
http://www.rapaul.com/2008/11/19/mocking-in-java-withmockito/
测试覆盖率
让测试覆盖率亮绿灯
Java - EMMA, 有Eclipse 插件EclEmma
.Net - NCover, 有Visual Studio支持
总结
- 每个测试用例应该明确地定义在单独的测试方法里
- 单元测试提供阐述代码如何工作的能运行的文档
- 测试的可维护很重要,因为测试代码占代码的比重很大
- 记录下单元测试覆盖的用例
- 过度地定义单元测试会导致更多的维护量
- 制造接缝使得代码之前耦合低,并且通过Mock对象能让单元测试变得简单
测试驱动开发注重代码是如何使用的,而且降低了编译和部署的周期 = 更快
- 单元测试(Unit Testing)基础
- 理解单元测试(Unit Testing)
- 【Android】unit testing 单元测试
- 单元测试Unit Testing
- 软件单元测试(Software Unit Testing)
- About Unit Testing单元测试摘要
- Unit-Testing in a Project --- 单元测试
- android应用开发之:单元测试(unit testing)
- flask入门的教程-(单元测试) Unit Testing
- iOS单元测试入门(Unit Testing)
- 单元测试(Unit Testing) – 对已有代码添加单元测试
- ASP.NET MVC + MVC Contrib + Unit Testing MVC 单元测试
- hadoop编程小技巧(8)---Unit Testing (单元测试)
- VS2010(2012)中使用Unit Testing进行单元测试
- Unit Testing
- unit testing
- Unit Testing
- Unit testing
- cxf发布webservice
- Ubuntu apt-get 详解
- Advanced use of Global Transaction Identifiers
- 学习php的日子
- 破碎的琉璃提供伤感日志_不愿离去,带走繁华
- 单元测试(Unit Testing)基础
- 软件开发流程
- pc行业指的什么?
- xcode debug模式断言擒bug记
- 常用正则表达式
- 史上最详细最容易理解的HMM文章
- 单链表的建立,测长,打印,删除,插入,排序,逆置
- FTP 多用户各自独立访问空间
- Cloud Foundry使用dev_setup部署多节点之排错分析