由于必须处理模拟对象而不是大型Grails项目中的集成测试,因此编写单元测试通常会更复杂.该文章甚至建议我们甚至可以废除单元测试干脆只写集成测试,我倾向于同意.
我看到的唯一缺点是与同一单元测试相比,集成测试的执行速度.
根据您在大型Grails项目上的实际经验,您对此有何看法?
如果我们编写一个单元测试来测试完全相同的方法,并编写集成测试,也测试完全相同的方法,这是编写测试的常规方法吗?
您在实际大型Grails项目中的单元测试与集成测试的比例最终得到了什么?
您是否成功完成了大型Grails项目而未编写任何测试?
Dón*_*nal 12
如果可能的话,我总是把我的测试写成单元测试.我这样做是因为:
我要编写集成测试的一个例子是我是否想要测试我定义的Spring bean resources.groovy.虽然我可以实例化该类并直接测试它,但我的测试需要知道该bean的当前实现类(可能会改变).
从长远来看,我认为编写集成测试实际上更复杂,因为随着时间的推移维护它们的成本高于单元测试.Groovy/Grails对模拟/存根提供了极好的支持,因此在单元测试中模拟依赖关系的成本相对较低.这是我的单元测试中的一个真实示例,其中我:
messageSource通常只在集成测试中可用的Spring beanvalidate()方法,检查.errors属性等.class MyUnitTests extends GrailsUnitTestCase {
MessageSource messageSource
protected void setUp() {
super.setUp()
// mockForConstraintsTests is a method provided by GrailsUnitTestCase
[Complex, CategoryCommand].each {mockForConstraintsTests(it)}
// 'mockMessage' will be returned by every method call on messageSource
messageSource = {Object[] args -> "mockMessage"} as MessageSource
}
}
Run Code Online (Sandbox Code Playgroud)
我已经研究过3个大型应用程序,以及无数小型应用程序.我目前的项目包括单元测试和集成测试(目前有2110个单元测试和493个集成测试).
我花了很多时间试图提高测试速度以及使测试更易于维护.
我的集成测试通常是混合测试,如果我正在测试服务,我可能会模拟一些其他服务/方法被调用以确保我获得我想要的值,但是留在其他集成部分来进行HQL或数据库集成.为此,我使用通常单例服务的原型实例,这样我就可以使用服务实例,而不会污染以后的测试.
我发现build-test-data插件对于创建可维护的单元测试是非常宝贵的,因为它允许我创建测试数据,我明确地填充我需要的部分并让插件填写其他所需的细节.在集成测试中创建测试数据比在单元测试中模拟它更容易.
如果你同时使用集成和单元测试,最终连续运行所有测试的速度将成为一个障碍.我的团队使用splitTests.groovy脚本来分离两个单独的线程,一个用于单元测试,一个用于集成测试.这使我们的测试速度提高了约40%.进一步的并行化是可能的,但是我们还没有去过那里(目前的grails gant脚本非常讨厌,我期待grails 2.0中的gradle重写).
单元测试很适合击中方法的所有条件角落和缝隙(尽管如果你有太多,你的圈复杂度可能太高,你应该重构).集成测试对于执行数据库和服务集成非常有用,并且可以帮助您了解更改代码时已损坏的内容.
我认为,从高测试覆盖率中获得的重构勇气部分取决于某些测试是集成测试.如果您所有的单元测试都不与其他代码片段交互,那么当您进行代码更改时,您不会收到受影响区域的警报,并且因为groovy是一种动态语言,编译器可能无法帮助您查找这些地区也是.