【问题标题】:Spock Extension - Extracting variable names from Data TablesSpock 扩展 - 从数据表中提取变量名称
【发布时间】:2020-11-19 21:58:42
【问题描述】:

为了提取数据表值以在 Spock 的报告扩展中使用,我使用 以下代码:

@Override
public void beforeIteration(IterationInfo iteration) {
    Object[] values = iteration.getDataValues();
}

这将返回给我对数据表中对象的引用。但是,我想得到 引用该值的变量的名称。

例如,在下面的测试中:

private static User userAge15 = instantiateUserByAge(15);
private static User userAge18 = instantiateUserByAge(18);
private static User userAge19 = instantiateUserByAge(19);
private static User userAge40 = instantiateUserByAge(40);

def "Should show popup if user is 18 or under"(User user, Boolean shouldShowPopup) {
        given: "the user <user>"

        when: "the user do whatever"
        ...something here...

        then: "the popup is shown is <showPopup>"
        showPopup == shouldShowPopup

        where:
        user        | shouldShowPopup
        userAge15   | true    
        userAge18   | true    
        userAge19   | false    
        userAge40   | false    

}

有没有办法接收字符串“userAge15”、“userAge18”、“userAge19”、“userAge40”而不是它们的值?

这样做的动机是对象 User 很复杂,包含大量信息,如姓名、姓氏等,其 toString() 方法会使我生成的报告中的 where 子句不可读。

【问题讨论】:

    标签: testing groovy bdd spock


    【解决方案1】:

    您可以使用specificationContext.currentFeature.dataVariables。它返回包含数据变量名称的字符串列表。这应该适用于 Spock 1.3 和 2.0。

    编辑:哦,抱歉,您不希望数据变量名称为["a", "b", "expected"],而是["test1", "test1", "test2"]。抱歉,我无法帮助您,如果可以,我也不会,因为那只是编程 IMO 的一种可怕方式。我宁愿确保toString() 输出在必要时以适当的方式缩短或修剪,或者(附加地或替代地)打印类名和/或对象 ID。

    最后但同样重要的是,编写测试是一种发现应用程序潜在问题的设计工具。您可能想问自己为什么toString() 结果不适合打印在报告中并重构这些方法。也许您的 toString() 方法使用换行符,应该简化为打印对象的单行表示。也许您想将多行表示分解为其他方法和/或拥有一组相关方法,例如toString()toShortString()toLongString()(之前都在 API 中看到过)或者可能是特定的方法,例如 toMultiLineString() .


    OP 后更新大大改变了问题:

    如果您的扩展程序的用户觉得报告不够清晰,她可以在数据表中添加一列userType,其中包含“15 岁”等值。

    或者可能更简单,只需添加一个值如 15、18、19、40 的 age 列,并通过 instantiateUserByAge(age)user 列或测试的 given 部分中直接实例化用户,而不是创建批次静态变量。 age 值将由您的扩展报告。结合使用 #age 的展开功能方法名称,这应该足够清楚了。

    创建用户的成本如此之高,您必须将它们放入静态变量中吗?如果不是真的有必要,你想避免静态,因为如果这些对象是可变的并且它们的内部状态在一个测试中发生变化,它们往往会对其他测试产生副作用,例如因为有人方便地使用userAge15 来测试setAge(int)。尝试通过静态变量避免过早的优化,这通常只节省微秒。即使您确实决定预先创建一组用户并在所有测试中重新使用它们,您也可以将它们放入以年龄为键的地图中,并方便地从您的功能方法中检索它们,同样只需使用年龄数据表作为查询地图的输入值,直接或通过辅助方法。

    底线:我认为您不必为了迎合编写糟糕测试的用户而更改扩展程序。这些用户应该学习如何编写更好的测试。作为副作用,报告也会看起来更全面。 ?

    【讨论】:

    • 在我写完这个答案之后,OP完全改变了示例代码,所以我提到的名称和值不再适合这个问题。对可能对此感到恼火的每个人表示歉意。但这样的答案仍然有效。无论如何,实际上更新,在之前已经回答之后可能对我来说不方便,有助于解释 OP 的用例。所以我也更新了我的答案,添加了与新问题相关的新的、更具体的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 2018-08-14
    • 2014-08-16
    • 2019-10-08
    • 1970-01-01
    相关资源
    最近更新 更多