5

我有许多工作/通过的功能性 geb/spock 测试(每个都扩展了 GebReportingSpec),这些测试使用功能测试套件开头的 BootStrap.groovy 创建的测试数据测试 Web 应用程序。

我想将测试数据创建移动到每个 Spec 中的 startup() / teardown() 方法中,实际上我想让它们从基类继承它,但显然 StepWise 存在继承问题。

所以,目前我的每个测试规范类看起来都像:

@Stepwise
class ExampleSpec extends GebReportingSpec {

    def "valid root user logs in"() {

        given: "I am at the login page"
        to LoginPage

        when: "I enter root's credentials"
        username = "root"
        password = "password"

        and: "I click the login button"
        loginButton.click()

        then: "I am logged in and directed to the welcome page"
        at WelcomePage
    }
}

现在,我的问题是我似乎无法创建一个可以创建测试数据的新测试(在第一个测试之上)。如果没有有效的 given/when/then 语句,测试似乎不会被执行,并且从现有测​​试中调用方法似乎也不起作用。我已经研究了 grails-remote-control 插件来帮助我,我相信这将使我能够成功地调用闭包来设置数据,但我不确定从 GebReportSpecs(或一些抽象父级)中调用它的最佳机制.

下面是我希望能够做的事情的简要概述,或者通过将“setupData()”作为第一个测试,或者通过在测试中调用该方法......似乎都不起作用。

def remote = new RemoteControl()
def setupData() {

    def id = remote {        
        def ShiroUser user = new ShiroUser(username: "root", ...)
        user.save()
        user.id
   }
   println(id)
}

.... Tests then follow

是否有像 @before 这样的注释可以强制调用这些方法?

任何建议表示赞赏。

解决方案:我已在正确答案中接受了 dmahapatro 在下面的回复,但也为那些可能觉得有用的人提供了下面的最终解决方案示例。

4

2 回答 2

3

未经测试)
GebReportingSpec扩展GebSpec最终扩展spock.lang.Specification其具有夹具方法

您可以像这样使用它们:

@Stepwise
class ExampleSpec extends GebReportingSpec {
    def setupSpec(){
       super.setupSpec()
       //setup your data
    }

    def cleanupSpec(){
       super.cleanupSpec()
       //I do not think you would need anything else here
    }

    def "This is test 1"(){

    }

    def "This is test 2"(){

    }
}

您不能将 setup 用作测试方法之一,因为不会为单个测试用例维护状态。它是这样的: -

setup called -> test1 -> teardown called  
setup called -> test2 -> teardown called  
setup called -> test3 -> teardown called  
.........
于 2013-06-18T01:27:37.040 回答
1

## 解决了 ##

感谢dmahapatro(和 erdi)。我特别掩盖了 setupSpec() 和 cleanup(),因为它们在 GebReportingSpec 中是私有的。

为了完整起见,我将使用grails 远程控制插件发布我最终解决方案的简化版本,以防万一它对其他人有所帮助。唯一需要注意的是,setup/teardown 似乎在每个 Spec 中调用一次,而不是在每次测试之前。这对我来说实际上是最好的,因为我的测试数据非常复杂并且需要时间来创建。因此,您有一组来自 Spec 的测试数据,这些数据通过 Spec 中的测试进行修改,然后在执行下一个 Spec 之前最终清除。

@Stepwise
class TestDataBaseSpec extends GebReportingSpec {

    protected void createTestUsers() {

        def remote = new RemoteControl()
        def created = remote {

        def createUser = { name, roles, pwHash ->
            def user = new ShiroUser(username: name, passwordHash: pwHash, passwordSetDate: new Date())
            roles.each { user.addToRoles(it) }
            user.save(failOnError: true)
            return user
        }

        createUser("root", [ShiroRole.findByName("base_user")], pwHash)
        // .. repeat for more
        }
    }

    protected void deleteTestUsers() {

        def remote = new RemoteControl()
        def created = remote {
            ShiroUser.findAll().each {
                it.delete(flush: true)
            }
            return true
        }
    }
}

@Stepwise
class ExampleSpec extends TestDataBaseSpec {

    def setupSpec() {
        super.createTestUsers()
    }

    def cleanupSpec() {
        super.deleteTestUsers()
    }

    def "valid root user logs in"() {

        given: "I am at the login page"
        to LoginPage

        when: "I enter root's credentials"
        username = "root"
        password = "password"

        and: "I click the login button"
        loginButton.click()

        then: "I am logged in and directed to the welcome page"
        at WelcomePage
    }
}
于 2014-01-30T10:07:36.873 回答