【问题标题】:How can I reuse some parts of my tests?如何重用测试的某些部分?
【发布时间】:2013-11-11 16:00:03
【问题描述】:

我需要实现以下逻辑:

  1. 做点什么
  2. 检查逻辑
  3. 做点别的事情
  4. 类似的校验逻辑

我使用when/then 块进行简单测试。但我真的不知道如何实现更复杂的(如上所述)+我想尽可能多地重用代码。但是有了块,实现起来就变得更加复杂了

【问题讨论】:

  • 如果您将逻辑转移到私有方法并简单地使用 when: doThis() then: checkThis() when: doThat() then: checkThat()(显然按照 spock 标准缩进),您会遇到任何问题吗?
  • 要么,要么使用@spock.lang.StepWise。后者对于集成和验收测试很有用。

标签: testing groovy spock


【解决方案1】:

我采取了几种方法来重用 Spock 中的代码。

功能级别 在您的设置中创建一个闭包:块。您可以将其视为仅可用于此功能的方法。

def "test"() {
    setup:
        def containsCat = {String it -> it.contains('cat')}
    expect:
        !containsCat('I love my dog')
        containsCat('I love my cat')
}

def "test that cannot reference containsCat(String)"() {
    // Test stuff
} 

规格等级 虽然可以使用 @Shared 闭包,但我更喜欢使用私有辅助方法,除非辅助逻辑只有一两行。

class tester extends Specification {
@Shared
def containsDog = {String it -> it.contains('dog')}
private containsCat(String inputString) {
    inputString.contains('cat')
}

def "test"(String myPet) {
    expect: containsCat(myPet)
    where: myPet = 'I love my cat'
}

def "test2"() {
    expect: containsDog(mySistersPet)
    where: mySistersPet = 'I love my dog'
}

包级别
我有一组类都可以从共享一个微型测试框架中受益。我的偏好是使用特征。除了功能测试本身之外,它们可以保存任何代码。如果 trait 将引用来自测试本身的数据,请确保创建一个抽象方法,以确保 trait 引用数据。

trait petTester {
    private containsDog(String inputString) {
        inputString.contains('dog')
    }    
    private containsCat(String inputString) {
        inputString.contains('cat')
    }    
}

class myPetTester extends Specification implements petTester {
    def "test"(String myPet) {
        expect: containsCat(myPet)
        where: myPet = 'I love my cat'
    }
}

class mySistersPetTester extends Specification implements petTester {
    def "test2"() {
        expect: containsDog(mySistersPet)
        where: mySistersPet = 'I love my dog'
    }    
}

【讨论】:

    【解决方案2】:

    你也可以使用interaction { doStuff() }

    但是,如果您发现您的 doStuff() 很大并且您的许多测试都使用相同的交互方法,那么可能是时候考虑将您的生产类中的一些代码移动到一个单独的类中,然后拥有一个期望您的测试类调用您的新类。

    【讨论】:

      【解决方案3】:

      如果你想两次运行相同的测试,只是改变一些参数,你可以使用where

        def "foo"(Boolean barIsEnabled) {
            when:
            myService.testBar(barIsEnabled)
      
            then:
            myService.readBar() == "123456"
      
            where: "this code shoud work with bar enabled or disabled"
            barIsEnabled  | ignored
            true          | _
            false         | _
        }  
      

      参考:http://spockframework.github.io/spock/docs/1.0/data_driven_testing.html

      如果你只是想重用then逻辑,创建一个私有方法并在里面添加许多assert

      def "foo"() {
        when:
        def pc = shop.buyPc()
      
        then:
        matchesPreferredConfiguration(pc)
      }
      void matchesPreferredConfiguration(pc) {
        assert pc.vendor == "Sunny"
        assert pc.clockRate >= 2333
        assert pc.ram >= 4096
        assert pc.os == "Linux"
      }
      

      参考:http://spockframework.github.io/spock/docs/1.0/spock_primer.html#_helper_methods

      【讨论】:

        猜你喜欢
        • 2021-03-21
        • 2011-12-30
        • 1970-01-01
        • 2017-04-07
        • 1970-01-01
        • 2011-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多