it-swarm-ja.com

Swift)でコアデータをユニットテストするための回避策

私はまだプログラミングにかなり慣れていませんが、私の最初のアプリは最近承認され、現在AppStoreで販売されています。私のアプリはCoreDataを使用しており、Swiftで記述されています。最初の問題が発生した後、単体テストなしでアプリを作成することにしました。ここで、回帰を防ぐために単体テストを実装したいと思います。

管理対象オブジェクトは、NSManagedObjectサブクラスのクラスメソッド内に作成され、AppDelegateで宣言したグローバル変数「context」を使用して、Appleのデフォルトコードで作成されたNSManagedObjectContextを格納します。グローバル変数は一般的に推奨されていないことは知っていますが、このアプローチは私にとって最も理にかなっており、記述が簡単で、アプリ自体のバグやその他の問題を許容していません。残念ながら、これにより単体テストが困難になります。テストターゲット内にCoreDataスタックを作成するためにいくつかの異なるアプローチを試しましたが、アプリコードをたくさん書き直さないと、何も機能しないようです。テスト可能にするためだけにそれをしたくはありません。 Quick/NimbleやMagicalRecordなどのフレームワークの使用を検討しましたが、それが私の問題にどのように役立つかわかりません。

私は回避策を見つけましたが、これが悪い考えだと人々が考えているかどうか興味があります。プライマリターゲット(テスト以外)にTestingClassというクラスを作成しました。最初のViewControllerviewDidAppearでは、startTestsメソッドを呼び出します。 TestingClassはstrait Swiftで記述されており、テストフレームワークはありません。falseと思われるifステートメントがいくつかあります。trueの場合、配列に文字列を追加します。テストが完了し、配列数が0より大きい場合、内容が出力されて中止されます。

アップデートを出荷する準備ができるまで、これを使用する予定です。そうである場合は、TestingClassを無効にして、その呼び出しを削除します。誰かがこのようなことをしたことがあるかどうか私は興味があります。 「正しい」方法でテストを行う方法を考えればよいでしょうか。

1
Steve S

最初に、より広い質問を見てみましょう。ある意味で、あなたの質問は、実用主義とコーディングの理論的な「最良の方法」のバランスに要約されます。私は、特にあなたの特定の状況で、実用的なプログラミングキャンプにいます。実用的なコーディングとは、現在のソフトウェアスタックが課す制限を回避することを意味します。

あなたの特定のケースでは、スタックを特に理解していると、課題に直面します。回避策を特定し、当面は機能するようにしました。これらの課題の一部は、グローバル変数の使用によってもたらされる可能性がありますが、あなたが述べたように、保存する必要のある情報には意味がありました。

TestingClassを使用することは、テストの目的を果たし(物事が期待どおりに動作することを確認し)、アプリケーションの制約内で作業しているため、完全に有効なアプローチだと思います。あなたが作成しました。開発中にテストハーネスを配置し、アプリをリリースする前にそれを削除するのは、あなたが最初ではないことは確かです。

そのアプローチでは、いくつかのリスクがあります。具体的には、本番環境にリリースする前にそのクラスを無効にするのを忘れると、問題が発生する可能性があります。同様に、メインパスとテストパスの間ですべてのコードを効果的に複製する必要があります。したがって、テストパスがメインパスの動作を正確に反映していない場合、バグが回避されるリスクがあります。最後に、複雑なテストケースが構築されますが、どこで壊れたかを理解するために物事をほどく必要があるため、デバッグがより困難になる可能性があります。


したがって、あなたが取った特定のアプローチに関する限り、それは十分に有効です。

従来の自動化された単体テストに従うという意味では「純粋」ではないかもしれませんが、実用主義がその日を支配する必要があると思います。ユニットテストのためにアプリケーションを購入するのではなく、機能するためにアプリを購入します。単体テストへのアプローチは回帰テストを提供し、新しい機能の開発に集中し続けることができます。

1
user53019

非常に経験豊富なプログラマーであっても、複雑なシステムフレームワークに依存するテストコードを単体テストすることは非常に難しい場合があります。私はあなたが最初にできる限り多くの他のコードをユニットテストしようとします。

(また、デバッグバージョンとリリースバージョンの間で手動で変更する必要があるコードを絶対に入れないでください!どこかで間違いを犯すことは避けられません)

0
grahamparks