记得我以前写过一个文章是有关于4层web结构单元测试的,今天打算对TDD的环境问题重新讨论一下。
我当时的4层结构的单元测试时间上是从DAO到Service到Action再到JSP一种渐进测试,但是的想法是,先测DAO,那么Service对DAO的调用就有保证了,测试了Service,那么action调用service就有保证了。。。这样一层一层下来,我每层测试的目标也就达到了。这里其实我用了一个技巧,就是通过测试的顺序,来逐渐的构建了每层测试所需的外部环境。当然从这个角度来看,我当时使用的方法更贴近于集成测试了。
一般做TDD的时候最大的问题就是如何处理外部环境,这一般包括本身业务逻辑环境和技术框架环境。
在当前这个新项目中,我首先尝试对一个具体渲染器的测试方式就是用mock,这里用的是比较好用的easyMock。开始的时候觉得mock的方法很好用,但是当我发现我的待测方法中有多个需要mock的对象时(a.getX();b.getY();c.getZ())或者一个mock对象要通过多次级联获取时(如 a.getB().getC().getD().getE())就会发现mock的代价让你高到很不原意mock的地步。
而且当我们的框架却制造了一个让我无法逾越的障碍,就是我们对于manager(DAO)的调用都是用一个类的静态方法封装管理(比较奇怪为什么不用spring来进行管理呢)。这样静态方法就没法mock了,于是乎,要想测试就要采用build的方法了,就是你可以在你的testCase中事先通过已经实现好的DAO方法把需要使用到的业务对象真实的build出来,这样你就可以知道你的被测方法中通过dao调用到的数据究竟是什么了,于是就可以对你期望获得的结果和经过实际方法得到的结果进行对比验证了。
看起来好像也是比较方便,但是实际上当你待测对象的业务模型,依赖于3-4级以上的相关模型时,你就会感觉到,这样build是一个代价非常高的事情。这种代价通常会让开发者丧失对TDD的兴趣了。
我发现其实在测试的时候我更加关注的是业务数据的build,而系统架构通常是服务于业务的。所以我就开始考虑,能否有个方法构建出最基本需要的业务模型数据呢。查阅了一些网上工具,发现没有能够满足我当前需求(kodo做持久层,还有我们自己研发的知识引擎),于是就自己简单做了一个InitialTestObject,想法很简单就是通过一个xml文件然后根据已知的业务模型结构定义好数据,然后根据固定的规则初始化好业务数据,并且存放到一个map中去(方法比较简单我就不列出源码了),然后再使用时把初始化放到setUp中去,这样在测试的时候就可以根据你的需要直接从map中获取到一个实际的业务对象用于测试的时候使用了,最后记得要在测试完成后要在tearDown中清除初始化的数据。这样处理后我发现在测试时就感觉到很方便了,用到什么直接从map中取就可以了。
也许有人会说这样做不还是是集成测试了吗,你build的时候需要数据库、持久层啊什么的,这里我不想来争论究竟是属于单元测试还是集成测试,因为它属于什么对于我们的功能来说是没有意义。无论什么测试的最终目标就是让我们的功能可用。
至于构建环境的实现我只是给出了一个对于我当前项目代价最小的方法,其实如果你的项目不是使用静态方法的话,可以考虑构建一个完全mock的环境这样就可以称之为单元测试了。
而且对于这个InitialTestObject我觉得可以做成一个开源的小工具,支持各种不同的持久层(jdo,hibernate),然后根据我们定义的持久层模型做为我们的业务规则,就不需要自己编写具体的初始化规则代码了,你只需要写xml数据并指定好对应的持久层模型,希望大家可以对这个想法对提提建议,也许已经有人做了,那我就不做重复功了。
下篇预告:think in refactor 时间:待定
分享到:
相关推荐
TDD:通过大量测试寻找最优解决方案.docx
java-hello-tdd:使用Java的TDD
Laravel-TDD:Api con TDD en laravel
trying-out-TDD:尝试TDD的统一
tdd 简单的TDD实现
curso-spring-tdd:Design de API的RestFul comSpring启动,TDD全新JUnit5
node-tdd:通过Jest学习TDD,以进行具有JWT身份验证的节点应用程序
FizzBuzz TDD 关于 研究测试驱动开发(TDD)的项目。 锻炼: 编写一个程序,打印从1到100的数字。但是,对于三个打印数字“ Fizz”(而不是数字)的倍数,以及五个打印“嗡嗡声”的倍数。 对于三和五的倍数的...
triangle_tdd:DDT-JUnit5-Maven-GitHub-Push上的自动测试
故事书TDD 使用Storybook的示例故事和TDD
TDD python中的TDD和单元测试实践
建造运行ng build来构建项目。 构建工件将存储在dist/目录中。 使用--prod标志进行生产构建。运行单元测试运行ng test以通过执行单元测试。运行端到端测试运行ng e2e通过执行端到端测试。进一步的帮助要获得有关...
时间在 JAVA 中学习 TDD @odd-e
Flutter,TDD,Clean Archtecure,SOLID。 TDD,固体,清洁建筑的概念。EmProdução Este App aindaestáem desenvolvimento。
埃迪的TDD学习笔记 :police_car_light: 警告不要合并任何PR。 :memo: 内容所有摘要都放在“问题”选项卡中。 当前,列出了以下内容: NHN FE개발랩摘要-Finsihed 견고한JS소프트웨어만들기-进行中测试Vue.js应用程序...
无论如何,我想通过添加测试驱动开发(TDD),一些JavaScript和部署使本教程更进一步。 这篇文章就是该教程。 请享用。 另外,如果您一般不熟悉Flask和/或Web开发,那么掌握以下基本概念很重要: GET和POST请求...
atg-tdd 使用Oracle Web Commerce(ATG)简化TDD的框架 #Idea我认为生产代码应该在可行的情况下包含在单元测试中。 拥有单元测试套件有一个巨大的好处,不断验证我们的代码是否按预期工作。 不仅在初始实施阶段,...
webservice-tdd 一个示例JSON Web服务,其Java客户端使用TDD进行了功能和单元测试。 所采取的步骤是在单独的提交中。 技术领域 专家 春天 杰克逊 Tomcat7 建造 使用货物部署应用程序。 使用-Djacoco.skip=true关闭...
flask-api-tdd
TDD周期TDD推荐的周期有五个阶段: 1. écrire un premier test ;2. vérifier qu'il échoue (car le code qu'il teste n'existe pas), afin de vérifier que le test est valide ;3. écrire juste le code ...