【问题标题】:Spock - expand assertions on collection into separate tests like @UnrollSpock - 将集合上的断言扩展为单独的测试,如 @Unroll
【发布时间】:2015-05-13 15:19:47
【问题描述】:

在 Spock 中,有没有一种方法可以将集合中每个项目的断言转换为可以通过/失败的自己的测试,类似于 when@Unroll 发生的情况?

如果我遵循最简单和最明显的方法(记录在Asserting on a list of items in Spock

when: def list = // do a bunch of stuff
then: list.each { ... assert it.foo == bar ... }

然后测试失败将停止迭代并且不会测试列表中的其他项目。我可以改为在循环中建立一个错误列表,然后将assert 拉到循环之外,但我希望能从测试框架中获得一些影响。

我可以改用where

then: list[idx].foo == bar
where: 
idx || bar 
0   || ...
1   ||  ...
2   ||  ...
....

但是,这会多次重新运行整个测试,这也不是我想要的——我想要一个测试执行,但每个集合元素上的断言报告为独立的测试通过/失败。

【问题讨论】:

    标签: unit-testing groovy spock


    【解决方案1】:

    如 OlgaMaciaszek 建议的那样,使用辅助方法创建列表然后使用 @Unroll 怎么样?

    class UnrolledSpec extends Specification {
    
        def bunchOfStuff() {
            println "Doing a bunch of stuff"
            return [-1, 1, 2, 3, 4, 5]
        }
    
        @Unroll
        def "That all numbers are greater than zero [#number]"() {
            expect:
            println "Testing ${number}"
            number > 0
            where:
            number << bunchOfStuff()
        }
    
    }
    

    输出:

    Doing a bunch of stuff
    Testing -1
    
    Condition not satisfied:
    
    number > 0
    |      |
    -1     false
    
        at UnrolledSpec.That all numbers are greater than zero [#number](UnrolledSpec.groovy:20)
    
    Testing 1
    Testing 2
    Testing 3
    Testing 4
    Testing 5
    

    【讨论】:

    • 问题首先是没有得到列表。这是where@Unroll 的行为——我不想多次执行整个测试。相反,我想执行一次测试,但将断言拆分为单独的集合元素以独立报告成功/失败。
    • 这几乎就是这里发生的事情。您将您的测试代码放在bunchOfStuff() 中,这将被执行一次,然后您在where 子句中的断言将被单独执行和报告。
    【解决方案2】:

    在 Spock 中也是 @Unroll

    更多详情请查看扩展坞:http://spockframework.github.io/spock/javadoc/1.0/spock/lang/Unroll.html

    【讨论】:

    • 是的,我的意思是,当我使用where@Unroll 时,它会多次执行整个测试。我正在寻找一种方法来选择性地展开测试中的一些循环。
    • 我不认为它真的会多次执行测试。我认为它只会改变报告的呈现方式。至少这是我从文档中解释此语句的方式:“请注意,展开对方法的执行方式没有影响;它只是报告中的一种交替。”你可以在这里找到它:spockframework.github.io/spock/docs/1.0/….
    • @Unrollwhere 是两个不同的东西。 where 是导致测试重复的原因; @Unroll 更改结果的呈现方式。
    • 我认为这不能仅使用Spock提供的机制来完成。我认为你能得到的最接近的方法是在setupSpec() 子句中包含任何你不想重复的代码,然后只在测试中放置一个带有断言的expect: 子句和where 表;这样测试将被迭代,但它主要由断言组成,所以不应该给你太多的开销。
    【解决方案3】:

    这是在同一输出上执行多个测试的单个测试执行。

    这个怎么样?

    when: 
    def list = // do a bunch of stuff
    
    then: 
    list*.foo == [bar1, bar2, ...]
    

    最终它就像两个集合之间的断言。如果您检查所有foos 的值应该与bar 完全相同:

    then:
    list*.foo.every { it == bar }
    

    【讨论】:

    • 这仍然表现为单个测试失败 - 就指标而言,无论集合中的一个元素失败还是所有元素都失败,都是一样的。
    猜你喜欢
    • 2020-10-25
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-26
    • 2018-09-21
    相关资源
    最近更新 更多