1. ホーム
  2. unit-testing

[解決済み] ユニットテストでは重複したコードが許容されるのか?

2022-07-24 13:13:40

質問

以前、いくつかのユニットテストを台無しにしてしまいました。 DRY --にするためにリファクタリングしたとき、それぞれのテストの意図が明確ではなくなりました。 テストの読みやすさと保守性の間にはトレードオフがあるようです。 ユニット テストに重複するコードを残しておくと、読みやすくなりますが、その後に SUT を変更する場合、私は重複するコードの各コピーを追跡して変更しなければなりません。

このトレードオフが存在することに同意しますか? もしそうなら、あなたはテストが読みやすいことと、保守しやすいことのどちらを優先しますか?

どのように解決するのですか?

重複したコードは、他のコードと同じようにユニットテストのコードでも臭います。 テストに重複したコードがあると、更新するテストの数が不均衡になるため、実装コードをリファクタリングするのが難しくなります。 テストは、テストされるコードに対する作業を妨げる大きな負担となるのではなく、自信を持ってリファクタリングするのを助けるべきです。

重複がフィクスチャのセットアップにあるのであれば、より多くの setUp メソッドをもっと活用するか、より多くの (あるいはより柔軟な) 作成メソッド .

もし重複がSUTを操作するコードにあるのなら、なぜ複数のいわゆる「ユニット」テストがまったく同じ機能を行使しているのか、自問自答してみてください。

もし重複がアサーションにあるのなら、おそらくあなたはいくつかの カスタムアサーション . 例えば、複数のテストが以下のようなアサーションの文字列を持っているとします。

assertEqual('Joe', person.getFirstName())
assertEqual('Bloggs', person.getLastName())
assertEqual(23, person.getAge())

では、おそらく単一の assertPersonEqual メソッドが必要でしょう。 assertPersonEqual(Person('Joe', 'Bloggs', 23), person) . (あるいは、単純に等号演算子をオーバーロードして Person .)

おっしゃるとおり、テストコードは読みやすいことが重要です。 特に 意図 が明確であることが重要です。 多くのテストがほとんど同じに見える場合(例えば行の4分の3が同じ、あるいはほとんど同じ)、それらを注意深く読み、比較しなければ、重要な違いを発見し認識することは困難であることがわかります。 そこで私は、重複を排除するためのリファクタリングとして が役に立ちます。 なぜなら、すべてのテストメソッドのすべての行が、テストの目的に直接関連しているからです。 これは、直接関連する行と単なる定型文の行のランダムな組み合わせよりも、読者にとってはるかに有益です。

とはいえ、ときにはテストが、似ているけれども大きく異なる複雑な状況を行使しており、重複を減らすための良い方法を見つけるのが難しいこともあります。 常識的に考えて、テストが読みやすく、その意図が明確で、テストによって呼び出されるコードをリファクタリングするときに、おそらく理論的に最小限の数のテストを更新する必要があることに納得できるなら、不完全さを受け入れ、より生産的なものに進みます。 後でインスピレーションが湧いたときに、いつでもテストをリファクタリングすることができます!