私は、テストの世界全体でさえ、BDD を初めて使用します。
単純な線形代数ライブラリを迅速に作成するときに、BDD の実践を試みています。したがってMatrix
、Vector
などの多くの値オブジェクト型が存在することになります。コードを記述するときは、TDD の原則に固執する必要があると思います (そうですか?)。
テストに失敗せずにコードを 1 行も書かない
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
}
}
これは、次の 2 つの理由から、見苦しいボイラープレートになります。
- 多くの値オブジェクト型が存在する可能性があり、それらすべてについて繰り返す必要があります
- 2 つのオブジェクトが等しくない原因となるケースはたくさんあります。上記の仕様を例にとると、
==
likeの実装はreturn lhs.rows == rhs.rows
テストに合格します。この「バグ」を明らかにするには、 のような別の期待値を追加する必要がありexpect(matrixWithDifferentColmunCount) != aMatrix
ます。繰り返しになりますが、このような繰り返しはすべての値オブジェクト タイプで発生します。
では、この「isEqual」(またはoperator==
) メソッドをエレガントにテストするにはどうすればよいでしょうか? または、まったくテストしないでください。
フレームワークのテストにswiftとQuickを使用しています。Quick は、ボイラープレートを減らすためにSharedExampleと呼ばれるメカニズムを提供します。しかし、Swift は静的型付け言語であり、Quick の共有例はジェネリックをサポートしていないため、共有例を直接使用して値オブジェクトをテストすることはできません。
私は回避策を思いつきましたが、それをエレガントなものとは考えていません。