开发者编写高质量测试的征途上可谓布满荆棘,数据库、中间件、不同的文件系统等复杂外部系统的存在,令开发者在编写、运行测试时觉得苦恼异常。由于外部系 统常常运行在不同机器上或者本地单独的进程中,开发者很难在测试中操作和控制它们。外部系统以及网络连接的不稳定性(外部系统停止响应或者网络连接超 时),将有可能导致测试运行过程随机失败。另外,外部系统缓慢的响应速度(HTTP访问、启动服务、创建删除文件等),还可能会造成测试运行时间过长、成 本过高。种种问题使开发者不断寻找一种更廉价的方式来进行测试,mock便是开发人员解决上述问题时祭出的法宝。mock对象运行在本地完全可控环境内,利用mock对象模拟被依赖的资源,使开发者可以轻易的创建一个稳定的测试环境。mock对象本地创建,本地运行的特性更是加快测试的不二法门。
我所在团队设计开发的产品是持续集成服务器,产品特性决定了它需要在各个平台(Windows, Mac, Linux等)与各种版本管理工具(svn, mercurial,git等)、构建工具(ant, nant, rake等)进行集成,对于外部系统的严重依赖让我们在编写测试时遇到了很多困难,我们自然而然的选用了JMock作为测试框架,利用它来隔离外部系统对 于测试的影响,的的确确在使用JMock框架后测试编写起来更容易,运行速度更快,也更稳定,然而出乎意料的是产品质量并没有如我们所预期的随着不断添加 的测试而变得愈加健壮,虽然产品代码的单元测试覆盖率超过了80%,然而在发布前进行全面测试时,常常发现严重的功能缺陷而不得不一轮轮的修复缺陷、回归 测试。为什么编写了大量的测试还会频繁出现这些问题呢? 在讨论之前先来看一个真实的例子:
我们的产品需要与Perforce(一种版本管理工具)进行集成,检测某段时间内Perforce服务器上是否存在更新,如果有,将更新解析为 Modification对象。将这个需求反应在代码中,便是首先通过Perforce对象检测服务器更新,然后将标准输出(stdout)进行解析:
public class PerforceMaterial { private Perforce perforce; ..... ..... public List findModifications(Date start, Date end) { String changes = perforce.changes(start, end); //检测更新,返回命令行标准输出(stdout) List modifications = parseChanges(changes);//将标准输出解析为Modification return modifications; } private List parseChanges(String output) { //通过正则表达式将stdout解析为Modification对象 } } public class Perforce { public String changes(Date start, Date end) { //通过命令行检测更新,将命令行标准输出(stdout)返回 } }
相应的mock测试也非常容易理解:
..... ..... @Test public void shouldCreateModifiationWhenChangesAreFound() { final String stdout = "Chang 4 on 2008/09/01 by p4user@Dev01 'Added build.xml'"; //设置标准输出样本 final Date start = new Date(); final Date end = new Date(); context.checking(new Expectations() {{ one(perforce).changes(start, end); will(returnValue(stdout)); }});//设置perforce对象的行为,令其返回设定好的stdout List list = perforceMaterial.findModifications(start, end);//调用被测方法 assertThat(list.get(0).revision(), is("4")); assertThat(list.get(0).user(), is("p4user@Dev01")); assertThat(list.get(0).modifiedTime(), is("2008/09/01")); }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 测试
, 运行
, 开发者
, stdout
, perforce
外部
微服务不是银弹、不是银弹、mock测试、java mock测试、spring mock 测试,以便于您获取更多的相关知识。