我应该如何测试 BDD 中值对象类型的“isEqual”方法?

Posted

技术标签:

【中文标题】我应该如何测试 BDD 中值对象类型的“isEqual”方法?【英文标题】:How should I test "isEqual" method of value object types in BDD? 【发布时间】:2017-02-22 03:15:46 【问题描述】:

我是 BDD 的新手,甚至是整个测试领域的新手。

在快速编写一个简单的线性代数库时,我正在尝试采用 BDD 实践。所以会有很多值对象类型,比如MatrixVector等等。在写代码的时候,我想我还是需要坚持TDD原则(对吗?):

在没有失败测试的情况下不编写任何单行代码

要实现一个值对象类型,我需要使其符合Equatable 协议并实现它的== 运算符。这是添加代码,所以我需要一个失败的测试。如何为这种场景编写规范?

有人可能会建议一些方法,例如:

describe("Matrix") 
    it("should be value object") 
        let aMatrix = Matrix<Double>(rows: 3, cols:2)
        let sameMatrix = Matrix<Double>(rows: 3, cols:2)
        expect(sameMatrix) == aMatrix
        let differentMatrix = Matrix<Double>(rows: 4, cols: 2)
        expect(differentMatrix) != aMatrix
    

这将是一个丑陋的样板,原因有两个:

    可能有很多值对象类型,我需要对它们都重复一遍 可能有很多情况会导致两个对象不相等。以上面的规范为例,== 的实现如return lhs.rows == rhs.rows 将通过测试。为了揭示这个“错误”,我需要添加另一个期望,例如expect(matrixWithDifferentColmunCount) != aMatrix。同样,所有值对象类型都会发生这种重复。

那么,我应该如何优雅地测试这个“isEqual”(或operator==)方法?还是我根本不应该测试它?


我正在使用 swift 和 Quick 来测试框架。 Quick 提供了一种称为SharedExample 的机制来减少样板。但是由于 swift 是一种静态类型语言,而且 Quick 的共享示例不支持泛型,所以我不能直接使用共享示例来测试值对象。

我想出了一个workaround,但不要认为它是一个优雅的。

【问题讨论】:

【参考方案1】:

优雅是测试套件的敌人。测试套件很无聊。测试套件是重复的。测试套件不是“干燥的”。您制作的测试套件越聪明,您就越努力避免样板代码,您就越是在测试您的测试基础架构而不是您的代码。

BDD 的规则是在编写代码之前先编写测试。这是少量的测试代码,因为它正在测试少量的实时代码;你就写吧。

是的,这可能太过分了,我并不是说你从不使用辅助函数。但是当您发现自己正在重构测试套件时,您需要问自己测试套件的用途。

附带说明,您的测试并未测试它所说的内容。您正在测试相同的构造函数创建 Equal 对象和不同的构造函数创建非 Equal 对象(原则上是两个测试)。这根本没有测试它是一个值对象(尽管测试它是一件非常好的事情)。这不是什么大不了的事。不要让测试理念妨碍有用的测试;但最好让您的标题符合您的测试意图。

【讨论】:

这是真的(很遗憾)。

以上是关于我应该如何测试 BDD 中值对象类型的“isEqual”方法?的主要内容,如果未能解决你的问题,请参考以下文章

BDD 和微服务

如何在行为 (BDD) 中查看 print() 语句

如何设置 cedar 以对 ios 应用程序进行 bdd 测试?

行为驱动开发(BDD) - 深入了解

如何测试 GraphQl API? [关闭]

展开树中值的范围函数?