我是BDD的新手,甚至是整个测试世界。
我正在尝试在swift中编写一个简单的线性代数库时采用BDD实践。因此会有很多值对象类型,如Matrix
,Vector
等。在编写代码时,我想我仍然需要坚持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,但不认为它是一个优雅的。
答案 0 :(得分:1)
优雅是测试套件的敌人。测试套件很无聊。测试套件是重复的。测试套件不是&#34; DRY。&#34;您制作测试套件越聪明,您尝试避免样板的次数越多,您测试测试基础架构的次数就越多,而不是代码。
BDD的规则是在编写代码之前编写测试。它是一小部分测试代码,因为它测试了少量的实时代码;你只需写下来。
是的,这可能会走得太远,我并不是说你从不使用辅助功能。但是,当您发现自己正在重构测试套件时,您需要问问自己测试套件的用途。
作为旁注,你的测试并没有测试它的作用。您正在测试相同的构造函数创建Equal对象和不相同的构造函数创建非Equal对象(原则上是两个测试)。这根本没有测试它是一个有价值的对象(尽管它是一个非常好的测试对象)。这不是一件大事。不要让测试哲学妨碍有用的测试;但是让你的标题符合你的测试意图是件好事。