自定义测试类型和测试阶段

Grails文档中已经提到了测试类型和测试阶段的概念,但却未就此深入讲解。从Luke Daley的这篇文章中可以对它们有所了解。Luke已经提交了GRAILS-6301,预计这部分内容在未来会出现在文档中。

什么时候你需要创建自己的测试类型呢?答案是:当你需要单独运行一组测试的时候。因此,简单地说,测试类型的概念类似Test Suite。而测试阶段,则指的是应用在测试时的状态。Grails自带的测试阶段是:Unit、Integration、Functional和Other。

Luke给出了如何创建自己的测试阶段的方法:

// 1. add the name of your phase to this variable with this event handler
eventAllTestsStart = {
    phasesToRun << "custom"
}

// 2. Create a <phase name>Tests variable containing a list of test types (more on this later)
customTests = ["custom"]

// 3. Create pre and post closures
customTestPhasePreparation = {
    // called at the start of the phase
}
customTestPhaseCleanUp = {
    // called at the end of the phase
}

他指出了两个需要注意的地方:即使在Preparation和CleanUp闭包中什么都不作,也必须定义它们;第二步中的测试类型和测试阶段的名字之间没有必然联系。此外,如果你的阶段类似标准阶段,那直接调用这些阶段的Handler即可:

customTestPhasePreparation = {
    integrationTestPhasePreparation()
}
customTestPhaseCleanUp = {
    integrationTestPhaseCleanUp()
}

上例的第2步定义了测试阶段所包含的测试类型,List中的值可以是一个String和一个GrailsTestType,如果使用的是String的话,则隐式转换到GrailsTestType。测试类型关联一个特定的目录和类名的后缀。在1.3之前,Junit测试类型的后缀是Tests;在1.3之后,则是Test和Tests。如果测试类型是通过String指出的,那测试目录就是这个字符串的值。如上例的目录就是:test/custom。

测试类型并不需要创建相应的Handler,但如果要创建的话,Luke给出了例子:

eventTestSuiteStart = { typeName ->
    if (typeName == 'custom') {
        // do stuff
    }
}

eventTestSuiteEnd = { typeName ->
    if (typeName == 'custom') {
        // do stuff
    }
}

为了让上面自定义的测试象标准测试,需要注册JUnit4GrailsTestType。Luke分别给出了类集成测试、类功能测试和类单元测试的完整例子。这里摘录类集成测试部分的代码:

import org.codehaus.groovy.grails.test.junit4.JUnit4GrailsTestType

// 1. add the name of your phase to this variable with this event handler
eventAllTestsStart = {
    phasesToRun << "custom"
}

// 2. Create a custom test type
def testTypeName = "custom"
def testDirectory = "custom"
def testMode = new GrailsTestMode(autowire: true, wrapInTransaction: true, wrapInRequestEnvironment: true)
def customTestType = new JUnit4GrailsTestType(testTypeName, testDirectory, testMode)

// 3. Create a ?phase name?Tests variable containing the test type(s)
customTests = [customTestType]

// 4. Create pre and post closures
customTestPhasePreparation = {
    integrationTestPhasePreparation()
}
customTestPhaseCleanUp = {
    integrationTestPhaseCleanUp()
}

运行:“grails test-app custom:”,关于这部分内容参见这篇文档速读

要是想控制custom测试类型的运行时机,如除非明确指出,就不在运行“grails test-app”时运行,Luke也给出了示例:

eventAllTestsStart = { 
    if (testOptions.customOnly) { 
        phasesToRun = ["integration"] // remove the other phases 
        integrationTests = [] // remove the normal integration  tests 
        addCustomTestType() 
    } else if (testOptions.withCustom) { 
        addCustomTestType() 
    } 
} 

addCustomTestType = { 
        integrationTests << "ipbx"
}

其中,testOptions的值对应grails test-app的参数,这样:

grails test-app // 不运行custom类型
grails test-app -only-custom // 只运行custom类型
grails test-app -with-custom // 运行所有,包括custom类型

这是目前唯一一篇详细介绍Grails测试类型和测试阶段内容的文章,请务必阅读原文。此外,阅读Spock插件源码也有助于理解这方面的内容。

By foxgem - Posted on 07 六月 2010