2

メソッドを持つCoordinateクラスがありadd(Coordinate)ます。このクラスの単体テストを作成するときassertEqual、結果に対するテストがあります。


a = Coordinate(1,2,3)
b = Coordinate(5,6,7)

result = a.add(b) 

assertEqual(result.x, 6)
assertEqual(result.y, 8)
assertEqual(result.z,10) 

私はこれをかなり簡単に「偽造」することができます:


def add(self, other):
    return Coordinate(6,8,10)

これは、テストの失敗に対する最も簡単な解決策です。次のステップは、私がこのように偽造するのを防ぐ2番目のテストを作成することです。私は次のいずれかを行うことができます:

  • 異なる番号で別のassertEqualテストを作成します(したがって、偽造はCoordinate(6,8,10)合格しません、または
  • 2つの異なる入力を使用してテストを作成assertNotEqualし、結果がではないことを確認し6,8,10ます。

テストを作成するとassertEquals、非常によく似た2つのテストがあります。これは問題ですか?プロジェクトで同様のコードを見た場合、それをリファクタリングしたくなるでしょう。テストコードに対してもこれを行う必要があります-もしそうなら、これはテストのすべてのペアがリファクタリングされることを意味しませんか?

私がを書いた場合assertNotEqual、テストは「偽の結果」をテストするだけです。これは、アルゴリズムエラーから発生することはないと確信しています。基本的に、テストを作成したら、両方のテストに合格するように結果を偽造するのをやめ、assertNotEqualsテストを安全に削除できますそれでもコードに自信があります。したがって、テストを作成し、偽物を修正し、テストを削除します。 、それはかなりばかげているようです。

この状況で私は何をすべきですか?

4

5 に答える 5

2

あなたが説明するように、テストを「偽合格」できることについてあまり心配する必要はありませんif。メソッド内に複雑なステートメントを記述して、各テストケースを合格させることは常に可能です。代わりに、メソッドに含まれるロジックaddを調べて、テストケースがすべてのコードブランチをカバーしていることを確認してください。これは私の意見では十分なはずです。

于 2012-08-09T11:51:45.860 に答える
2

テストコードが使用する特定のケースに基づいて、悪意を持ってコードを記述し、テストコードを偽造することを防ぐテストを作成することは不可能です。だからあなたは試してはいけません。

私が「不可能」と言うとき、私は単に「非常に難しい」という意味ではありません、それは形式的なシステムを壊す嘘つきのパラドックスの例かもしれません。

于 2012-08-09T11:52:12.667 に答える
2

異なる数の別のassertEqualテストで十分です。可能であれば、次のような「境界線」または一般的でないケースを取り上げます。

a = Coordinate(1,2,3)
b = Coordinate(-5,-6,-7)
...

AssertNotEqualテストはばかげており、リーダーIMOにとって直感的ではありません。

いずれにせよ、私はこの種のテストについてあまり心配しません。読者として、それらを書いた開発者がいくつかのケースをテストしたかったことは本当に明らかであり、それらをリファクタリングしたいのは本当のリファクタリング過激派が必要です。つまり、重複がほとんどない2つのテストだけであり、意図は明らかであり、オブジェクトが変更されたときに300行のコードを書き直す必要があるわけではありません...

于 2012-08-09T18:09:15.300 に答える
1

注:簡単にするために、CoordinateをIntに変更します。また、以下の構文で構成されているため、実行されません。しかし、それは私の主張を理解するはずです

testAdd()
  assertThat(2.Add(2), isEqualTo(4))

次に、Add return 4を常に作成することで、これを偽造できます。三角測量の次に(特定のパラメータを変更して一般的なコードを駆動します)。

testAdd()
  assertThat(2.Add(2), isEqualTo(4))
  assertThat(3.Add(5), isEqualTo(8))

次に、実際の作業を行うためにAddを作成する必要があります。緑色になったら、2つのテストをそのままにするか、単純/些細なテストを削除することができます。ただし、自信が失われない限りです。重複が気になる場合は、テストランナーが「パラメーター化されたテスト」をサポートしているかどうかを確認できます。

[2,2,4]
[3,5,8]
testAdd(operand1, operand2, expectedResult)
  assertThat(operand1.Add(operand2), isEqualTo(expectedResult))
于 2012-08-10T05:48:06.503 に答える
0

Coordinate.Add()メソッドはどのように見えますか?

そのメソッドは追加する方法を処理する必要があるようです(それを偽造するポイントはありません)、そしてあなたがする必要があるのは:

# In your test setUp code
testCoord = Coordinate(6, 8, 10)  # Explicitly setting the value you expect the test to return.
addCoord1 = Coordinate(1, 2, 3)
addCoord2 = Coordinate(5, 6, 7)

# The test
addCoord1.add(addCoord2)
assertEqual(testCoord, addCoord1, "Testing addition of coordinates using add() method.")

私が間違っている場合は訂正してください。ただし、単体テストフレームワークを使用していますか?個人的には、テストケースのセットアップにオブジェクトの作成を入れますunittest

于 2012-08-09T12:47:35.277 に答える