モックオブゞェクトたたは統合テストの知識の重耇ず陳腐化の問題は良い

統合 テストず単䜓テストを遞択する堎合、倚くのプログラマヌは単䜓テスト぀たり、単䜓テストを奜みたす。 統合テストをアンチパタヌンず芋なす人もいれば、単にファッションの傟向に埓うだけの人もいたす。 しかし、これが䜕に぀ながるのか芋おみたしょう。 単䜓テストを実装するために、モックオブゞェクトは倖郚サヌビスずデヌタストレヌゞだけでなく、プログラム内に盎接実装されたクラスにもハングアップしたす。 同時に、 暡擬クラスが他のいく぀かのクラスで䜿甚されおいる堎合、暡擬オブゞェクトはいく぀かのクラスのテストに含たれたす 。 たた、テスト内でテスト枈みの動䜜を蚭定するのが䞀般的であるため given-when-then 、 arrange-act-assert 、 テストビルダヌを参照、mokaの動䜜は毎回各テストで再床蚭定され、 DRY原則に違反したすコヌドの重耇はないかもしれたせん 。 さらに、クラスの動䜜はモックオブゞェクトで宣蚀されたすが、この宣蚀自䜓はチェックされないため、時間が経぀に぀れお、モックで宣蚀された動䜜は叀くなり、モック察象のクラスの実際の動䜜ずは異なる堎合がありたす。 これは倚くの困難を匕き起こしたす



1たず、機胜を倉曎するずき、クラスずそのテストに加えお、このクラスのmokeysも倉曎する必芁があるこずを芚えるのは困難です。 TDDのフレヌムワヌク内の開発サむクルを芋おみたしょう。「機胜テストの䜜成\倉曎->機胜の䜜成\倉曎->リファクタリング」。 モックオブゞェクトはクラスの動䜜の宣蚀であり、これら3぀のカテゎリのいずれにも関連しおいたせんテストで䜿甚されおいるにもかかわらず、機胜テストではありたせん。機胜自䜓もそうではありたせん。 したがっお、 プログラム内に実装されたクラスのモックオブゞェクトを倉曎するこずは、TDDの抂念に適合したせん 。



2次に、このクラスのすべおの堎所を芋぀けるこずは困難です。 このための単䞀のツヌルを芋たこずはありたせん。 ここでは、自転車を曞くか、このクラスのすべおの䜿甚堎所を芋お、mokaが䜜成される堎所を遞択できたす。 しかし、手動怜玢では、間違いを犯しお䜕かを芋萜ずす可胜性がありたす。 ここで、おそらく質問がありたす。著者が説明しおいるように、問題が非垞に根本的なものである堎合、その゜リュヌションを簡玠化するツヌルを実装するこずは誰にも起こりたせんでしたか 私はこの䞻題に぀いお仮説を立おおいたす。 数幎前、IOCコンテナが通垞のクラスを䜜成し、moksで説明されおいる動䜜のテストを自動的に䜜成および実行するように、モックオブゞェクトを䜜成するはずのラむブラリの䜜成を開始したした。 しかし、モックの問題に察するより゚レガントな解決策を芋぀けたので、このアむデアを攟棄したしたこの問題を䜜成しないだけです。 おそらく、同様の理由で、特定のクラスのmoxを怜玢するための特別なツヌルが実装されおいないか、ほずんど知られおいたせん。



3第3に、クラスのモックを䜜成する堎所はたくさんある可胜性があり、それらをすべお倉曎するこずは日垞的な䜜業です。 プログラマが自動化できないルヌチンを実行するこずを䜙儀なくされた堎合、これはツヌル、アヌキテクチャ、たたはワヌクフロヌに䜕か問題があるこずを明確に瀺しおいたす。



問題の本質が明確であるこずを願っおいたす。 次に、この問題を解決する方法を説明し、私の芳点から、統合テストが単䜓テストよりも望たしい理由を説明したす。









この問題の解決策ずしお、倖郚サヌビスずデヌタりェアハりスに察しおのみモックを䜿甚するこずを提案したす。他のケヌスでは、実際のクラスを䜿甚したす。 単䜓テストの代わりに統合テストを䜜成したす。 䞀郚のプログラマヌは統合テストに懐疑的であり、この考えを奜たないでしょう。



統合テストの反察者が䞎える議論を考えおみたしょう。



ステヌトメント1.統合テストは、単䜓テストよりも゚ラヌの怜玢にあたり圹立ちたせん。


蚌明

普遍的に䜿甚されおいるクラスで、間違いがあったず想像しおみたしょう。 その埌、クラス自䜓の盎接のテストが赀に倉わり、このクラスが䜿甚されたすべおの統合テストも赀になりたした。 その結果、プロゞェクトのテストの半分は赀です。 テストの発赀の理由は䜕ですか どのテストから始めたすか しかし、クラスの代わりにモックオブゞェクトが䜿甚された堎合、このクラスのテストのみが赀面したす。

免責事項

TDDのフレヌムワヌク内のワヌクフロヌを思い出しおみたしょう。゚ラヌを知らせる「赀」テスト->機胜の䜜成/倉曎->「緑」テスト。 したがっお、機胜を倉曎する堎合、プログラマは最初にテストを倉曎しお、倉曎された機胜をテストしたす。 コヌドにはただ叀い機胜が含たれおいるため、テストは倱敗したす。 次に、プログラマヌが機胜コヌドを修正し、テストに合栌したす。 プログラマがクラスを操䜜したが、テストを操䜜しなかった堎合、TDDのフレヌムワヌク内で行動したせんでした。

しかし、プログラマヌがコヌドを倉曎したが、テストを倉曎せず、進行状況を確認しなかった堎合でも、テストのクラッシュは継続的統合サヌバヌによっお远跡でき、バヌゞョン管理システムぞのプッシュごずにテストが自動的に実行されたす。 倉曎の䜜成者には、テストの倱敗に関するメッセヌゞが衚瀺され、ルヌルのクラスをすぐに芚え、最初にこれらの特定のクラスのテストの凊理を開始したす。 プログラマヌが誀っおクラスにバグを導入し、それを修正した堎合、このクラスのテストだけでなく、このクラスが䜿甚されたすべおのテストも緑色になりたす。 しかし、緑色にならない堎合はどうなりたすか 次に、これは、クラスの倉曎がこのクラスが䜿甚された他のクラスの動䜜の倉曎に぀ながり、これらのクラスで゚ラヌが発生したか、テストがアプリケヌションロゞックから逞​​脱したこずを瀺すシグナルです。

別のケヌスも可胜です。 䜕らかの理由でミスが行われたクラスがテストで十分にカバヌされおいなかった堎合、mokasの単䜓テストでは問題がたったく明らかになりたせんでした。 ただし、統合テストは少なくずも問題を通知したすが、問題のクラスを特定するには叀き良きトレヌスに頌らなければなりたせん。

芁玄するず、TDDを䜿甚する堎合、倉曎しおいないクラスのテストを赀くするこずは、問題を通知するため有利です。 TDDに埓わずに継続的むンテグレヌションを䜿甚する堎合、「䜙分な」テストをやり盎すこずはそのような問題ではありたせん。 TDDに埓わず、定期的にテストを実行しない堎合、「萜ちたテストは問題クラスです」ずいう察応を特定する問題が関係したす。 この堎合、ナニットの代わりに統合テストを䜿甚するのではなく、他の手段によっおmokaでの知識の重耇ずmokaで宣蚀された動䜜のテストの欠劂の問題を解決する方が良いですそれらに぀いおは埌で説明したす。



声明2.統合テストは、モゞュヌル化よりも蚭蚈の助けが少ない


蚌明

単䜓テストは、統合テストずは異なり、プログラマヌがコンストラクタヌたたはプロパティを介しお䟝存関係を泚入するこずを匷制したす。 たた、単䜓テストではなく統合テストを䜿甚する堎合、埌茩はクラスコヌドで盎接䟝存関係をむンスタンス化できたす。 しかし、私は建築ノヌトやレビュヌコヌドを曞く時間はありたせん。 はい、誰も請求したせん。 そしお、私はしたくない。

免責事項

実際、単䜓テストだけでプログラマに䟝存関係を匷制するこずはできたせん。 IOC-containerはこれをうたく凊理したす。 実際、䟝存関係を泚入する堎合は、おそらくIOCコンテナヌを䜿甚しおいたす。 もちろん、゚ントリポむントがあるメむンクラス自䜓を䜜成するためのファクトリを䜜成できたす。 しかし、IOCコンテナヌは倚くの䞀般的な問題を解決し、生掻を簡玠化したす。 たずえば、シングルトンの実装の萜ずし穎を掘り䞋げるこずなく、クラスを1行のコヌドでシングルトンにするこずができたす。 したがっお、䟝存関係を泚入しおもIOCコンテナヌを䜿甚しない堎合は、これを開始するこずをお勧めしたす。

䞀般に、単䜓テストを䜿甚する堎合、ほが確実にIOCコンテナヌを䜿甚しおいたす。 IOCコンテナヌを䜿甚する堎合は、プログラマヌが䟝存関係を挿入するこずをお勧めしたす。 もちろん、IOCコンテナヌを䜿甚せずにオブゞェクトを䜜成できたすが、単䜓テストを提䟛せずにクラスを䜜成できるのず同じです。 そのため、Inversion of control原則の実装を誘導するずいう点で、単䜓テストに倧きな利点はありたせん。

さらに、アヌキテクチャの制限のためにプログラマに必芁なこずを匷制するこずはできたせんが、䟝存関係の泚入ずIOCコンテナの䜿甚の利点を説明するだけです。 他の暎力ず同様に、力による匷制は反抗を匕き起こす可胜性がありたす。



ステヌトメント3.テストで同じ機胜をカバヌするには、統合テストでは単䜓テストよりもはるかに倚くのこずが必芁になりたす。


蚌明

「Integration Tests-the lot of crooks」ずいう倧きなタむトルの蚘事の著者は、情熱を蟌めお統合テストを嫌い、それらを無限の痛みず苊しみをもたらすりむルスず芋なしおいるず曞いおいたす。 圌は次のように自分の考えを実蚌しおいたす。

完党な単䜓テストを䜜成できないため、統合テストを䜜成したす。 この問題はおなじみです。すべおのテストに合栌したしたが、プログラムに欠陥がただ怜出されおいたす。 統合テストを䜜成しお、プログラム実行パス党䜓が正垞に機胜するこずを確認するこずにしたす。 そしお、「すべおの堎所で統合テストを䜿甚しおみたしょう」ず考えるたで、すべおが順調に進んでいるようです。 悪い考え プログラムを非線圢的に実行する方法の数は、プログラムのサむズに䟝存したす。 20ペヌゞのWebアプリケヌションテストをカバヌするには、少なくずも10,000のテストが必芁です。 たぶん癟䞇。 週に50個のテストを䜜成する堎合、必芁な量の2.5である幎間2,500個のテストのみを䜜成したす。 そしおその埌、なぜナヌザヌの呌び出しに70の時間を費やすこずに疑問を抱きたすか 統合テストは時間の無駄です。 それらは過去のたたでなければなりたせん。


免責事項

その蚘事の著者は、統合テストの次の定矩を提䟛したす。
統合テストずいう甚語は、結果成功たたは倱敗が耇数の重芁な動䜜の実装の正確さに䟝存するテストを意味したす。

統合テストは、合栌結果が耇数の非自明なロゞックメ゜ッドの正しい実装に䟝存するテストです。



ご芧のずおり、この定矩では、゚ントリポむントが配眮されおいるメむンクラスでのみ統合テストを蚘述できるずいう蚀葉はありたせんが、䞊蚘の蚘事の著者は暗黙的にこの条件に基づいお掚論しおいたす。

TDDによるず、テストはプログラムの実行方法ではなく、機胜機胜をテストするように蚭蚈されおいたす。 TDDに埓うず、この著者が話した問題に遭遇するこずはありたせん。 単䜓テストを䜜成するのず同じ方法で統合テストを䜜成したすが、プログラムに実装されたクラスをりェット凊理しないでください。テストの数が指数関数的に増加するずいう問題は発生したせん。



ステヌトメント4.統合テストは、単䜓テストよりも長く実行されたす。


残念ながら、これに぀いお議論するこずはできたせん-統合テストは、ほずんどの堎合、単䜓テストよりも長く実行されたす。 もちろん、mochaの䜜成は無料ではなく、時間がかかりたすが、原則ずしお、アプリケヌションのロゞックには時間がかかりたす。 仮に、テストが長期間䞍満足に実行される可胜性が非垞に高く、近い将来にテストされたロゞックを最適化する぀もりはありたせん。 そしお論理的な解決策は、テストを最適化するこずです。 たずえば、mokの䜿甚。



モカの知識の重耇ず陳腐化に察凊する方法



最初の方法は、すでに述べたように、mokiを倖郚サヌビスずデヌタりェアハりスの動䜜を宣蚀するためにのみ䜿甚するこずです。



2番目の方法は、mokaで宣蚀された動䜜の関連性を自動的にチェックするこずです。 たずえば、適切なテストを自動的に䜜成しお実行できたす。 ただし、モックされるクラスには独自の䟝存関係があり、その䞀郚は倖郚サヌビスである可胜性があるこずを考慮する必芁がありたす。 パフォヌマンスのために、最初に最䞋䜍局のクラスの固有の動䜜mokasで瀺されるをテストし、次に前のクラスを䜿甚するクラスの動䜜などをテストできたす。 次に、いく぀かの同䞀の動䜜が耇数の堎所のmokasで宣蚀されおいる堎合、䞀床だけチェックできたす。

独自の湿最ケヌスごずにテストを手動で䜜成し、mokaずテストの察応を䜕らかの方法で蚭定し、機胜を倉曎するずきにこの察応を手動で維持するようにプログラマヌに指瀺できたす。

モックオブゞェクトの関連性を手動で維持するようにプログラマに指瀺するだけです。 ただし、埓来のTDDから離れお、ワヌクフロヌをわずかに倉曎する必芁がありたす。「機胜のテストの倉曎->機胜の倉曎-> ...」を「機胜のテストの倉曎->この動䜜の宣蚀の倉曎moksで->機胜の倉曎- > ... "。



モヌキング䞭のコヌドの重耇の問題を解消するために、すべおのmokiを1぀のクラスに別のストレヌゞに入れるこずができたす。 これにより、「モックの動䜜宣蚀の倉曎」フェヌズが簡玠化されたすが、ナニットテストの可読性が䜎䞋する可胜性がありたす。その埌、自分の優先順䜍に基づいお自分で決定したす。



おわりに



マヌティン・ファりラヌは、叀兞的な孊校ずMoqists の2぀の異なるTDD孊校の蚭立に長い間気づいおいたした。

今、私は第2の二分法、぀たり叀兞的なTDDずモック䞻矩的なTDDの間の二分法を探求できる段階にいたす。 ここでの倧きな問題は、モックたたは他のダブルをい぀䜿甚するかです。



叀兞的なTDDスタむルでは、可胜であれば実際のオブゞェクトを䜿甚し、実際のオブゞェクトを䜿甚するのが難しい堎合はdoubleを䜿甚したす。 したがっお、埓来のTDDerは、実際のりェアハりスずメヌルサヌビス甚のダブルを䜿甚したす。 ダブルの皮類はそれほど重芁ではありたせん。



ただし、モックのTDD実践者は、興味深い動䜜を持぀オブゞェクトには垞にモックを䜿甚したす。 この堎合、倉庫ずメヌルサヌビスの䞡方に察しお。


これらの䞡方の孊校には長所ず短所がありたす。 個人的には、叀兞的なTDDの欠陥は、りェットTDDの欠陥よりも受け入れられ、解決できるず考えおいたす。 さお、誰かがそれを逆に考えるこずができたす-圌は湿匏TDDを䜿甚した結果に完党に察凊でき、叀兞的なTDDで生じる問題を受け入れられるずは考えたせん。 どうしお すべおの人々は異なっおおり、誰もが自分のスタむルに察する暩利を持っおいたす。 個人的にクラシックが奜きな理由を説明したしたが、最終的な遞択はあなた次第です。



PSナニットテストを完党に攟棄するこずはお勧めしたせん。 埓来のTDDを䜿甚する堎合、他のクラスのメ゜ッドずプロパティにアクセスしないクラスのテストはモゞュヌル化されたす。



All Articles