21

私のアプリは主に GUI であり、サーバーと通信してほとんどの情報を取得します。何か問題が発生した場合、それは通常、ネットワーク呼び出しにあるか、JSON オブジェクトについて間違った仮定をしている可能性があります。

単体テストは、これらのネットワーク関連および I/O 関連のタスクには適していません。それ以外の場合、単体テストとは呼ばれません。

SO 私の場合、単体テストのポイントを収集しようとしています。Android ボタンをクリックできるかどうか、または EditText が入力内容を確認できるかどうかをテストする必要があるのはなぜですか? これらの退屈なテストを実装することの有用性を理解していません

private void initElements(){
    placeButton = (Button) findViewById(R.id.currplace);
    placeButton.setText(MainActivity.this.getString(R.string.findingLocation));
    placeButton.setEnabled(false);
    selectplaceLayout = (LinearLayout)findViewById(R.id.selectplaceLayout);
    selectplaceLayout.setVisibility(View.GONE);
    splash = (RelativeLayout)findViewById(R.id.splashbg);
    infoLayout = (LinearLayout)findViewById(R.id.infoLayout);
}

上記のメソッドが渡された場合、すべてのアクティビティが onCreate で実行され、アプリが動作することがわかります。これの単体テストは、作成するのに冗長で時間のかかるものです。jUnit と Android のテスト フレームワークのすべてのメソッドに精通しているわけではないため、時間がかかります。

要するに、要点は何ですか?これらのテストについて私が考えるべき特定の方法はありますか? これまでに見たすべての例とチュートリアルは、簡潔にするために最も単純な例についてのみ説明していますが、主にクライアントサーバーアプリでの単体テストの実用的な使用法は考えられません.

宣言して初期化したことを既に知っている Android ビューにアクセスすることで、何を発見することが期待されていますか? 私はこれについてあまりにも限定的に考えているに違いない

ですから、洞察力は高く評価されます

4

3 に答える 3

28

あなたの質問には多くの側面がありますが、私の意見では、おそらくプロジェクトに単体テストは必要ありません。

単体テストは、プロジェクトに多くのビジネス ロジックが必要な場合に非常に役立ちます。この場合、おそらくアプリケーションを複数のレイヤー (たとえば 3 層アーキテクチャー) に分割して、ビジネス ロジック レイヤーに自然な分離を追加し、それを単体テストのセーフティ ネットでカバーする必要があります。

このセーフティ ネットは、ビジネス レイヤーのリファクタリング中にお尻をカバーします。これは、単体テストから得られる主なものの 1 つです (ただし、TDD はいくつかの優れた追加の副作用を提供できます)。

ただし、すべてのユニコーンやレインボー、単体テストにコストがかかるわけではありません。優れた単体テストは分離されています (つまり、コードの小さなチャンクを処理します)。これは、クラスをテストするために抽象化のレイヤーを追加する必要があることを意味します。

これは、システムにプラスの影響を与えるか、マイナスの影響を与える可能性があります。階層化により、システムがより柔軟になりますが、複雑さが増します。

そうは言っても、単体テストの価値は、プロジェクトに導入する抽象的なビジネスロジックの量に比例します。このように考えることもできます - 抽象レイヤーをアーキテクチャに追加するのがやり過ぎの場合 - 単体テストを追加しないでください - 物事をより複雑にするだけです (アーキテクチャとビルドの賢明さ)。

あなたの説明に基づくと、あなたの典型的なアプリは、外部サーバー側のほとんどのプレゼンテーション層になる傾向があります。Android ハンドセットに情報を表示し、ユーザー アクションをサーバー側へのコマンドに変換して、主要なビジネス ロジックを実行する (制御する) こと以外は、それほど多くのことはしません。

このアプローチでは、おそらくあなたが書くコードのほとんどは、「これとあれを表示する方法」または「この場合とその場合にサーバーにシグナルを送る方法」に関連しています。この種のコードは明らかにプラットフォームに大きく依存しているため、テストを行いたい場合は、Android 固有のコードや動作を大量にモックする必要があります。

さて、Android はやや特殊なプラットフォームです。パフォーマンスが最適化され、開発者がアプリをすばやく開始して作成できるように設計されています。多くの場合、これはあなたが使用している「スイスナイフ」クラスの一部を意味し、一般的にこれはコードの記述を高速化しますが、それらのクラスをモックすることは本当に地獄になる可能性があります. 言うまでもなく、これらのモックを有効にするには、プラットフォームが内部でどのように機能するかを理解する必要があります。つまり、これらのテストを行うことによるオーバーヘッドが高くなります。

プレゼンテーション レイヤーのテストに関するもう 1 つの問題は、プレゼンテーション レイヤーがビジネス レイヤーよりもはるかに動的に変化する傾向があることです。そしてもちろん、これは、さらにオーバーヘッドを追加する 3 つのテストをリファクタリングする必要があることを意味します。

ただし、さまざまなユーティリティ/ヘルパー クラスについて 1 つ言わなければなりません。これらのクラスがプレゼンテーション レイヤーに属し、Android コードに依存していても、重要なロジック実行し、それらの単体テストを簡単にモックして記述できる場合でも、実際にはこれを実行することをお勧めします。ただし、そのようなコードがたくさんある場合は、アーキテクチャ/レイヤリングを適切に設計しておらず、何をしているのかを再考する必要があることを示している可能性があります。

最後に、あなたの質問に答えるには、まず次の質問に答える必要があります。

プラットフォームから分離された抽象レイヤーをアプリケーションに追加するのは過剰設計になりますか (あなたの場合はそうなるようです)? はいの場合 - 単体テストを使用しないでください - 遅くなるだけです。いいえ - それらを使用してください。

多くのリファクタリングを行いますか? それが大量のコードとメンテナンスを伴う大規模なプロジェクトである場合は、レイヤー化と単体テストに投資することになるでしょう (しかし、一見したところ、これはあなたの場合ではないようです)。そうでない場合は、単体テストを気にせず、迅速に行ってください。

単体テストを作成するためにプラットフォームを何度もモックする必要がありますか? はいの場合(あなたのケースのようです)-単体テストを作成しないでください-それらは努力する価値がありません。

これが役立つことを願っています。

于 2013-05-24T19:24:10.327 に答える
-1

Android.Docsから

Android アプリをテストするには、通常、次のタイプの自動単体テストを作成します。

ローカル テスト: ローカル マシンでのみ実行される単体テスト。これらのテストは、実行時間を最小限に抑えるために、Java 仮想マシン (JVM) でローカルに実行するようにコンパイルされています。このアプローチを使用して、Android フレームワークに依存しない、またはモック オブジェクトを使用して満たすことができる依存関係を持つ単体テストを実行します。

インストルメント化されたテスト: Android デバイスまたはエミュレーターで実行される単体テスト。これらのテストは、テスト対象のアプリのコンテキストなどの計測情報にアクセスできます。このアプローチを使用して、モック オブジェクトを使用して簡単に埋めることができない Android の依存関係を持つ単体テストを実行します。

注:単体テストは、複雑な UI インタラクション イベントのテストには適していません。代わりに、UI テストの自動化で説明されているように、UI テスト フレームワークを使用する必要があります。

于 2018-06-25T09:51:16.957 に答える