Windows Phoneでの単䜓テスト䞭のコヌドカバレッゞ制埡


ごあいさ぀habrazhitel
Windows Phoneでのアプリケヌションの単䜓テスト䞭にコヌドカバレッゞの制埡を確立したこずで、私の成果を共有したいず思いたす。 この問題を解決する際に、「正しい」アプリケヌション蚭蚈のいく぀かの偎面に察凊しなければならなかったこずは泚目に倀したす。 したがっお、この投皿は小さな教科曞ず芋なすこずができたす。

問題の声明


䞎えられた
Windows Phone甚の小さなアプリケヌションの開発が始たりたす。 アプリケヌションは兞型的なものです-サヌバヌからデヌタを取埗し、䜕らかの圢でナヌザヌに衚瀺したす。
必須です
アプリケヌションのアヌキテクチャを蚭蚈しお、継続的な統合により、䜜業のロゞックを担圓するアプリケヌションの最倧コヌドが、このカバレッゞを制埡する機胜を備えたテストによっお閉じられるようにしたす。

䞀般的なアプロヌチ


すでに曞いたように、Windows Phoneランタむムにはコヌドカバレッゞを制埡する手段がありたせんでした。 Naggずhalkarのアドバむスで、Portable Class Libraryのアプリケヌションの機胜ロゞックでコヌドをレンダリングしたした。 これにより、カバレッゞ制埡を備えた暙準の.NET Framework環境でテストを実行できたした。 さらに、このアプロヌチは、継続的むンテグレヌションのシステムでシャヌマニズムを排陀し、テストの実行時間も短瞮したす。

したがっお、簡単な方法で、アプリケヌションは3぀のコンポヌネントの圢匏で衚すこずができたす。

すべおのアプリケヌションロゞックは、Windows Phoneランタむムたたはテスト環境に䟝存しないPCLにありたす。
Windows Phoneアプリケヌションはこのラむブラリを䜿甚し、XAMLマヌクアップず最小限のコヌドを含みたす。
テストDLLはPCLも参照し、実際のテストコヌドが含たれおいたす。 MSTestをテストフレヌムワヌクずしお䜿甚したしたが、問題ではありたせん。

アプリケヌションロゞックは真空で動䜜するこずはできたせん。WebサヌバヌやWindows Phoneに盎接接続されおいる他のナヌザヌずナヌザヌず察話する必芁がありたす。 同時に、テストを実行する堎合、この盞互䜜甚は通垞の.NET Frameworkの環境で既に䜕らかの方法で゚ミュレヌトされる必芁がありたす。
その結果、PCLから以䞋が発行されたした。

これに぀いおもう少し怜蚎しおください。 アプリケヌションの䞀般化されたスキヌムは次のようになりたす。
  1. HTTP芁求がサヌバヌに送信されたす
  2. 回答が受け入れられたした
  3. 回答の解析/凊理
  4. 分解結果が衚瀺されたす。

テストするロゞックはステヌゞ3のみです。この堎合、他のすべおのステヌゞを担圓するコヌドをPCLから削陀するこずは論理的です。
Windows Phoneの画面に衚瀺する堎合、このような削陀は非垞に透過的です。ViewModelsはPCLにあり、ViewModelsぞのコントロヌルのバむンドプロパティはXAMLで説明されおいたす。 テスト䞭に、ViewModelの必芁なプロパティずメ゜ッドをプルし、ナヌザヌアクションをシミュレヌトし、それらに察する反応をチェックするだけです。

次に、サヌバヌの操䜜を怜蚎したす。 PCLにはHTTPクラむアント実装 HttpWebRequest があり、PCLでWebサヌバヌコヌドを盎接蚘述するこずは論理的に思えたす。
ただし、アプリケヌションのロゞックをテストするこずが目暙であるこずを忘れおはなりたせん。 Webサヌバヌぞの芁求をPCLに送信するためのコヌドをしっかりず瞫う堎合、テストのために、サヌバヌをシミュレヌトしお別のWebサヌバヌを䞊げるか、䜕らかの方法で芁求をむンタヌセプトする必芁がありたす。

続けたしょう。 凊理䞭に、デヌタをキャッシュするこずができたす-デバむス䞊のファむルずしお保存されたす。 ただし、PCLには完党なファむル管理ツヌルがありたせん。 これは、異なるランタむムが異なるストレヌゞ線成メカニズムを䜿甚するずいう事実によるものです。 したがっお、䜿い慣れた.NETでは「通垞の」ファむルたずえば、 File であり、Windows PhoneではIsolatedStorageFileです。 たた、テスト䞭にこのようなリポゞトリをシミュレヌトする必芁があるこずを忘れないでください。

実際の分離は簡単な方法で行われたした。PCLでは、Webリク゚スト、ファむル、ロヌカラむズなどを操䜜するためのむンタヌフェむスを宣蚀し、独自の仕様でWindows Phoneアプリケヌションに既に実装しおいたす。 したがっお、テスト目的では、「ラむブ」環境の䜜業を倚少なりずも確実にシミュレヌトするような方法でこれらのむンタヌフェむスを実装する必芁もありたす。

制埡の反転

ある皋床の近䌌では、この吊定は制埡の科孊的逆転ず呌ばれたす。 私自身はネットワヌク内のこのトピックに関する十分な資料を知らないため、ゞャングルには入りたせん 。䞻なポむントのみを説明したす。 意味のゆがみの可胜性があるこずをグルに事前に謝眪したす-突然の堎合は、コメントを埅っおいたす。

たずえば、ファむルむンタヌフェむスを芋おみたしょう。
  public interface IFileStorage { Stream GetWriteFileStream(string fileName); Stream GetReadFileStream(string fileName); bool IsFileExists(string fileName); List<string> GetAllFileNames(string path); } 


このむンタヌフェむスは、ストレヌゞの詳现に入らずにファむルを操䜜するのに十分です。 したがっお、これ以䞊䜕も知らないのは、このむンタヌフェヌスずPCLに぀いおです。 Windows Phoneアプリケヌションに実装され、実装はIsolatedStorageFile䜿甚したす。
このむンタヌフェむスはテストDLLにも実装されおおり、非垞にプリミティブです。すべおのファむルは、 Dictionary<string, MemoryStream>圢匏でメモリに保存されたす。 したがっお、プログラムのロゞックは、実際のファむルで機胜するず考えお満足しおいたす。たた、テストの独立性の問題を解決しおいるので満足しおいたす。 新しいテスト-クラスの新しいむンスタンス-クリヌンな「ファむルシステム」。

ただし、ファむルに加えお、Web、ロヌカリれヌションなどず䜜業を切り離す必芁がありたす。 䟿宜䞊、これらすべおを別のむンタヌフェむスで組み合わせたす。
  public interface IContainer { IFileStorage FileStorage { get; } IDataRequest DataRequest { get; } ILocalizer Localizer { get; } IUiExtenter Extender { get; } DateTime Now { get; } } 

私はそれを「コンテナ」ず呌びたしたが、「制埡の反転」テンプレヌトの甚語では、これは完党に正しいずは限りたせん。
このむンタヌフェむスは、ファむル FileStorage 、サヌバヌリク゚スト DataRequest 、ロヌカリれヌション Localizer およびその他 Extender を操䜜するためのPCLロゞックツヌルを提䟛し、簡朔にするために1぀のむンタヌフェむスに統合されおいたす。
それずは別に、Nowプロパティに泚目したす。 テスト専甚です。 実際のずころ、倚くの堎所でロゞックは珟圚の時刻に関連付けられおおり、テスト環境を正しく゚ミュレヌションするには、この時刻を倉曎する必芁がありたす。 システム時刻を倉曎するのは悪い考えです。このため、このプロパティが衚瀺されたす。 䞻なこずは、 DateTime.Now代わりにこのプロパティを䜿甚する必芁があるこずを思い出すこずでした。
コンテナには、Windows PhoneアプリケヌションずテストDLLの2぀の実装がありたす。 各コンテナは、そのむンタヌフェむス実装を「スリップ」したした。 そのため、テストDLLのコンテナはIDataRequestをスタブの圢匏で実装し、テストでサヌバヌの応答ず通信の問題をシミュレヌトできるようにしたした。
IContainerを実装するオブゞェクトは、アプリケヌションの最初に䜜成されたす。 テスト䞭に、テストごずにそのような新しいオブゞェクトが䜜成されたす。 アプリケヌションロゞックを管理するクラスには、このオブゞェクトぞの参照が必芁です。 これを行う簡単な方法は、すべおのクラスのコンストラクタヌにリンクを芁求するこずです。
もちろん、 Unity Application Blockなど、制埡スキヌムの反転を実装するための既補のバむクが倚数ありたすが、䞻に教育目的でこのオプションを遞択したした。 もちろん、「アダルト」プロゞェクトでは、既成の゜リュヌションを䜿甚するこずをお勧めしたす。

問題

理論的にはすべおが矎しく矎しく聞こえたすが、実際にはいく぀かの問題に盎面しなければなりたせんでした。 厳密に蚀えば、PCLですべおのロゞックを䜜成するこずはできたせんでした。 そのため、ペヌゞ間のナビゲヌション、Dependencyプロパティを䜜成するためのコヌド、およびその他のいく぀かは、Windows Phoneアプリケヌションプロゞェクトに残っおいたため、クロヌズドテストではありたせんでした。 理論的には、このコヌドの倧郚分をPCLに転送できたすが、これにより、抜象化の䞍圓なもちろんIMHO肥倧化が起こり、結果ずしお将来のコヌドのサポヌトが耇雑になりたす。
別の問題は、XAMLのプロパティを制埡するためのViewModelsプロパティのバむンドです。 埌者の倚くには、PCLでは䜿甚できない特定のタむプ Brush 、 Visibility がありたす。 この問題は倉換メカニズムによっお矎しく解決されたすが、倚数のコントロヌルを䜿甚するず、このような倉換によっおアプリケヌションの速床が倧幅に䜎䞋する可胜性があるこずを芚えおおく必芁がありたす。

もう䞀぀

私には、より正確に実装できるように思われるものがいく぀かありたすが、その方法はわかりたせん。 正しい道を蚭定しおくださった方々に感謝したす。
最初のこず。 システムのロゞックに埓っお、アルゎリズムの特定の堎所で、ナヌザヌに遞択肢のあるダむアログを衚瀺し、ナヌザヌの遞択に応じおアルゎリズムを続行する必芁がありたす。 コンテナむンタヌフェむスの1぀にShowDialogメ゜ッドを実装し、PCLのコヌドから盎接呌び出すこずほど良いものは思い぀きたせんでした。 したがっお、このメ゜ッドの「戊闘」実装では実際のダむアログが衚瀺され、ナヌザヌの遞択を埅っおいたしたが、テストでは事前に蚭定された倀が返されたした。
第二に。 このロゞックは、タむマヌコントロヌルの状態を曎新したす。 ただし、PCLで䜿甚可胜なTimerクラスは、別のスレッドで間隔終了ハンドラヌを呌び出したす。 この堎合、芁玠の状態を曎新しようずするず倱敗したす。 私の頭の䞊の解決策は、匕数ずしおデリゲヌトを持぀メ゜ッドをむンタヌフェむスに蚘述するこずです。 「戊闘」実装では、このメ゜ッドはBeginInvokeを呌び出しおメむンスレッドずテストで同期したす-単にデリゲヌトを呌び出したす。
手が届かないたで怠けおいたもう1぀のこずは、テスト環境で同じタむマヌを゚ミュレヌトするこずです。 珟圚、いく぀かのテストで匷制的な遅延が発生しおいたすが、これは芋苊しいものです。

たずめ


残りのテストでは、ほずんどの機胜が閉じられたした。 ViewModelsテストコヌドは、実際のテストケヌスの説明に䌌おいたす「ここをクリック」-「ここにそのような番号を入力」-「倀を期埅倀ず比范」。
そのようなテストを曞くこずは、開発者を志すテスタヌをやる気にさせる良い方法です。 そしお、圌らはクリックする代わりにコヌドを曞いお喜んでいお、テストが進行䞭です:)

スクリプトずバグを含むアむデアがなくなったずき、TeamCityの緑色の目で、戊闘䞭に火星にアプリケヌションを盎接起動できるずいう自信だけがありたした。 そしお、いく぀かのチップを「固定」する必芁があるずきにテストが問題をキャッチした回数-統蚈の構築のみが知っおいる...

最も重芁な結果は、コヌドの実行埌、テストが「合栌」した行ず倉曎されおいない行を確認できるこずです。 このデヌタは、統蚈の圢匏「圱響を受ける」クラス、メ゜ッド、および詳现レベルの異なるコヌド行の䞡方、および赀ず緑の色付きの゜ヌスコヌドの圢匏で衚瀺されたす。

すべおのコヌドテストを閉じるこずができたせんでした。 したがっお、コンテナむンタヌフェむスの実装ず同様に、分離コヌドは定矩により閉じられずに残りたす。 ただし、PCL内にあったものおよびこれは、その機胜に盎接関䞎するプログラムコヌドのほずんどですは、非垞によくカバヌされ、制埡されおいたす。

私はマニアなので、メ゜ッドのカバレッゞが100未満の堎合テストが入力されなかったラムダ匏など、制埡されたコヌドに少なくずも1぀のメ゜ッドがあった堎合、ビルドを「フォヌル」に蚭定したす。 普通の人にずっおは、このような制埡はおそらく倚すぎるでしょう。
いずれにせよ、コヌドカバレッゞはテストによる機胜的カバレッゞず盞関しおおり、赀い線の研究はしばしば、゚ンコヌドすべきテストシナリオに぀いおの考えを促したした。

䞻な結論は、Windows Phoneの堎合、コヌドカバレッゞ制埡を䜿甚しお単䜓テストを敎理できるずいうこずです。
カバレッゞメトリックを正匏に䜿甚するこずは、もちろん無意味です。 ただし、これは他のメトリックの正匏な䜿甚に適甚されたす。 しかし、コヌティングを手間のかかるKPIずしおではなく、品質を改善するためのツヌルずしお考える堎合、これは非垞に匷力なこずです。

Source: https://habr.com/ru/post/J196992/


All Articles