大型Grails项目中的集成和单元测试

时间:2011-04-10 08:18:08

标签: grails groovy

由于必须处理模拟对象而不是大型Grails项目中的集成测试,因此编写单元测试通常会更复杂。这article甚至表明我们甚至可以完全取消单元测试,只编写我倾向于同意的集成测试。

与同一单元测试相比,我看到的唯一缺点是集成测试的执行速度。

根据您在大型Grails项目上的实际经验,您对此有何看法?

如果我们编写一个单元测试,测试完全相同的方法,并编写集成测试,也测试完全相同的方法,这是编写测试的正常方法吗?

在实际大型Grails项目中,您在单元测试与集成测试的比率方面最终得到了什么?

您是否成功完成了大型Grails项目而未编写任何测试?

3 个答案:

答案 0 :(得分:12)

如果可能的话,我总是将我的测试编写为单元测试。我这样做是因为:

  • 单元测试执行得更快
  • 我更喜欢单独测试每个组件,而不是测试集成在一起的所有组件,因为这样可以更容易地识别错误的来源
  • 单元测试环境更简单(例如没有Spring应用程序上下文),因此与正在执行的测试无关的潜在故障源更少

我要编写集成测试的一个示例是我是否要测试我在resources.groovy中定义的Spring bean。虽然我可以实例化该类并直接测试它,但我的测试需要知道该bean的当前实现类(可能会改变)。

从长远来看,我认为编写集成测试实际上更复杂,因为随着时间的推移维护它们的成本高于单元测试。 Groovy / Grails对模拟/存根提供了极好的支持,因此在单元测试中模拟依赖关系的成本相对较低。以下是我单位测试中的一个真实示例,其中我:

  • 模拟通常只在集成测试中可用的messageSource Spring bean
  • 模拟两个命令类,以便我可以调用validate()方法,检查.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
    }
}

答案 1 :(得分:7)

我参与了3个大型应用程序,以及无数小型应用程序。我目前的项目包括单元测试和集成测试(目前有2110个单元测试和493个集成测试)。

我花了很多时间试图提高测试速度并使测试更易于维护。

我的集成测试通常是混合测试,如果我正在测试服务,我可能会模拟一些其他服务/方法被调用以确保我获得我想要的值,但留在其他集成部分来运用HQL或数据库集成。为此,我使用prototype instances of what are normally singleton services以便我可以使用服务实例,而不会污染以后的测试。

我发现build-test-data插件非常适合创建可维护的单元测试,因为它允许我创建测试数据,我明确填充我需要的部分并让插件填写其他所需的详细信息。在集成测试中创建测试数据对我来说比在单元测试中模拟它更容易。

如果你同时使用集成和单元测试,最终连续运行所有测试的速度将成为障碍。我的团队使用splitTests.groovy脚本来分离两个单独的线程,一个用于单元测试,一个用于集成测试。这使我们的测试速度提高了约40%。进一步的并行化是可能的,但是我们还没有去过那里(目前的grails gant脚本非常讨厌,我期待grails 2.0中的gradle重写。)

单元测试很适合击中方法的所有条件角落和缝隙(尽管如果你有太多,你的圈复杂度可能太高,你应该重构)。集成测试对于执行数据库和服务集成非常有用,并且可以帮助您了解更改代码时已损坏的内容。

我认为,从高测试覆盖率中获得的重构勇气部分取决于某些测试是集成测试。如果您所有的单元测试都不与其他代码片段交互,那么当您进行代码更改时,您不会收到受影响区域的警报,并且因为groovy是一种动态语言,编译器可能无法帮助您查找这些领域要么。

答案 2 :(得分:0)

  

这篇文章甚至建议我们甚至可以完全取消单元测试并只编写我倾向于的集成测试

那篇文章是用Grails 1.0编写的

选中此complementary article相同列,同一作者