在Spock中编程跳过一个测试

12

我不明白这个问题。你可以在@IgnoreIf中运行任意代码。你试过吗?我知道这是一个旧问题,但是你到底有什么问题?如果你已经了解自己的Spock内置功能可以实现相同的功能,那么我认为没有必要使用Assume - kriegaex
1
@kriegaex 但是这个闭包没有访问测试变量的权限。问题在于如何在测试进行中忽略测试,基于某些条件,在测试开始后知道。 - Krzysztof Wolny
问题不在技术上,而是在于你的测试方法。其他测试不应该被跳过,但都应该快速失败并变成红色。跳过测试是一种异常情况,并且在统计数据中不会被报告为失败。我总是教我的团队,敏捷开发最好的特点就是透明度。因此,如果你遇到第三方服务器故障,你希望看到 3,000 个集成测试失败,以便了解这个问题的根本影响。想象一下,如果你只有一个失败的测试,而后续的 2,999 个测试被跳过,或者甚至只有 3,000 个被跳过,但还有 10 个测试失败。(待续) - kriegaex
开发团队会有什么反应?他们可能会将跳过的测试视为小问题,因为测试统计数据仍然良好,首先修复其他失败的测试。相反,他们应该联系第三方,并确保尽快在那里解决导致 3,000 个测试丢失质量信息的问题。同样适用于内部第三方系统或自己的组件,无论出于什么原因不可用。跳过测试是信息隐藏。 (待续) - kriegaex
1
另外,您仍然可以在单个集成规范中使用@Stepwise,以便使Spock自动跳过该规范中剩余的方法。 另外,如果您一定要这样做,@Requires@IgnoreIf可以轻松调用测试中的静态方法,检查或记录到远程系统中。 - kriegaex
2个回答

16

使用JUnit的Assume类,具体而言,在测试开始时您可以编写Assume.assumeTrue(canConnectToService())来跳过测试,如果第三方服务不可用。 如果canConnectToService()返回false,则此方法将抛出AssumptionViolatedException,Spock会忽略因AssumptionViolatedException中断的测试,以实现与JUnit的兼容性(请参见此错误报告)。


似乎它不再工作了。异常被抛出,测试失败了。 - lepe
3
对于Spock 2.x,请使用JUnit 5的Assumptions.assumeTrue(https://junit.org/junit5/docs/5.0.0/api/org/junit/jupiter/api/Assumptions.html)或抛出TestAbortedException(https://ota4j-team.github.io/opentest4j/docs/1.0.0/api/org/opentest4j/TestAbortedException.html?is-external=true),因为Spock 2基于Junit 5(请参见https://github.com/spockframework/spock/issues/1185)。 - Magnus Reftel

1

还有一种替代方案(也许以前不存在):

@Requires@IgnoreIf中使用instance

以下是继承示例,但不是必需的:

abstract class BaseTest extends Specification {
    abstract boolean serviceIsOnline()
 
    @Requires({ instance.serviceIsOnline() })
    def "some test" () { .. }
}

子规范:

class OnlineTest extends BaseTest {
    boolean serviceIsOnline() { 
       // Test connection, etc.
       return true
    }
}

class SkipTest extends BaseTest {
    boolean serviceIsOnline() { 
       return false
    }
}

文档

实例

如果需要实例字段、共享字段或实例方法,则使用规范实例。如果使用此属性,则无法直接跳过整个注释元素而不执行夹具、数据提供程序等。相反,整个工作流程将一直持续到特征方法调用,在那里检查闭包,并决定是否中止特定迭代。

作为额外的方式,您可以使用 where 标签以编程方式跳过测试:

class MyTest extends Specification {
    
    List getAvailableServices() {
        // You can test connections here or your conditions
        // to enable testing or not.

        return available
    }

    @Unroll
    def "Testing something"() {
        setup:
           URL url = serviceUrl.toURL()
        expect:
           assert url.text.contains("Hello")
        where:
           serviceUrl << availableServices
    }

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接