まえがき
このトピックでは、
コードカバレッジ 、およびこのツールが必要かどうかについて説明するつもりはありません。 また、iOSプロジェクトでのテストの適切性の問題は提起されません(まだ誰かが必要であると想定します)。
やる気
IDEにプロファイリング/分析ツールが組み込まれている場合、非常に便利です。 xCodeのコードカバレッジの履歴は完全にクラウドレスではありません。xCode3.xとGCCの時代には、すべてが単純であり、必要なリンクとコンパイラフラグが一度にグーグルで検索されました。 xCode 4.1の出現により、LLVM-GCCの使用によりすべてが少し複雑になり、いくつかのトリックを踏まなければなりませんでした(LLVMを自分の手で組み立てるまで)。 4.3では、libprofile_rtライブラリが別のディレクトリに移動され、多くの問題が発生しました。
xCode 4.4のコードカバレッジの設定には数分かかることが実験的に判明しました。安価なので、使用しないのはなぜですか。 実際に実証された代替の実用的な使用例は、プロジェクトコードを直接テストし、「デッド」コードを検索して、その後の分析とクリーニングを行うことです。
xCode 4.4でのプロジェクトのセットアップ
[
単体テストを含める]チェックマークを付けて新しいプロジェクト(iOS / OS X)を作成します。 私の
テストプロジェクトは既成の単体テストで使用できます。
プロジェクトのセットアップには2つのステップが含まれます。
1. target%project-name%を開き、
コード生成セクションでフラグを設定します。
テストカバレッジファイルの生成= YES
機器プログラムフロー= YES
2.
iOSのみ。 ここで説明するクラッシュを回避するには、次の内容のファイルを* .cプロジェクトに追加する必要があります。
#include <stdio.h> FILE* fopen$UNIX2003(const char* filename, const char* mode); size_t fwrite$UNIX2003(const void* ptr, size_t size, size_t nitems, FILE* stream); FILE* fopen$UNIX2003(const char* filename, const char* mode) { return fopen(filename, mode); } size_t fwrite$UNIX2003(const void* ptr, size_t size, size_t nitems, FILE* stream) { return fwrite(ptr, size, nitems, stream); }
これがプロジェクト全体のセットアップです。 ここで、%projectname%テストを実行した後、ディレクトリ(iOS用)
"/Users/%user%/Library/Developer/Xcode/DerivedData/%project-nameBLABLABLABLA%/Build/Intermediates/%project-name%.build/を開く必要があります。
「Debug-iphonesimulator /%project-name%.build / Objects-normal / i386」 このディレクトリでは、カバレッジデータを含む* .gcdaおよび* .gcnoファイルに関心があります。
重要 :テストではなくアプリケーションコードのカバレッジをテストする場合、* .plistで
UIApplicationExitsOnSuspend = YESを指定する必要があります
。 * .gcdaファイルは、プログラムが「エラー」の方法で終了した後にのみ作成されるためです。
明確にするために、テストするクラスのコードといくつかのテストを示します。
#import "MyCalc.h" @implementation MyCalc - (CGFloat)performOperation:(MyMathOperation)operation withA:(CGFloat)a B:(CGFloat)b { CGFloat result = 0.f; switch (operation) { case MyMathOperationAdd: result = a + b; break; case MyMathOperationSubtract: result = a - b; break; case MyMathOperationDivide: result = a / b; break; case MyMathOperationMultiply: result = a * b; break; default: NSLog(@"Unsupported operation"); break; } return result; } - (CGFloat)negate:(CGFloat)number { //this method works incorrectly return number; } @end
- (void)testNegation { CGFloat input = 3; CGFloat expected = -3; CGFloat result = [self.calculator negate:input]; STAssertEquals(result, expected, @"Negation failed. Expected: %f, Actual: %f", expected, result); } - (void)testAddition { CGFloat a = 3; CGFloat b = 4; CGFloat expected = a + b; CGFloat result = [self.calculator performOperation:MyMathOperationAdd withA:a B:b]; STAssertEquals(result, expected, @"Addition failed. Expected: %f, Actual: %f", expected, result); } - (void)testMultiplication { CGFloat a = 14; CGFloat b = 3; CGFloat expected = a * b; CGFloat result = [self.calculator performOperation:MyMathOperationMultiply withA:a B:b]; STAssertEquals(result, expected, @"Addition failed. Expected: %f, Actual: %f", expected, result); }
結果分析
人に優しい形式で統計を表示するためのいくつかのツールを検討してください。
gcov
gcovは、* .gcdaおよび* .gcnoファイルに基づいてカバレッジ統計を生成するユーティリティです。 最近まで、それはGCCでのみ動作しましたが、現時点ではLLVMで完全に動作します。 出力はプレーンテキストのレポートです。
たとえば、テストプロジェクトのMyCalc.gcdaファイルで実行した結果は次のとおりです。

出力には、カバレッジのパーセンテージに関する統計とMyCalc.m.gcovファイルがあります。
-: 0:Source:/Users/dlebedev/src/sandbox/Coverage/iOS/iOSCoverage/../../Common/MyCalc.m -: 0:Graph:MyCalc.gcno -: 0:Data:MyCalc.gcda -: 0:Runs:0 -: 0:Programs:0 -: 1:// -: 2:// MyCalc.m -: 3:// iOSCoverage -: 4:// -: 5:// Created by Denis Lebedev on 23.08.12. -: 6:// Copyright (c) 2012 Denis Lebedev. All rights reserved. -: 7:// -: 8: -: 9:
#####:-行は完了しませんでした。
n:-行はn回実行されました。
詳細は
こちらをご覧ください 。
カバーストーリー
CoverStoryはgcov用のGUIアドオンで、Apple Scriptを使用してHTMLレポートを生成できます。

lcov
lcovは、gcovのもう1つのグラフィカルフロントエンドです。 htmlをディレクトリにグループ化するので、多数のファイルがある場合、およびプロセスの自動化中に非常に便利です-ユーティリティは端末から動作します。
lcovをインストールします。
34行目(-D $ SOURCE $ TARGETをインストール)で、-Dフラグを削除します。
レポートを取得するには、* .gcda-filesを含むフォルダーで次のコマンドを実行します。
lcov -t 'Code coverage report' -o report.info -c -d . genhtml -o html-report report.info
html-reportフォルダー内の結果:

自動化
上記のように、lcovは継続的な統合に便利です。 実証された例は、専らアカデミックであり、迷惑な欠陥があります(スクリプトはCocoaPodsを使用してプロジェクトに適用できませんでした)。
スクリプトコード(iOSテストプロジェクトのフォルダーにもあります):
settings.xcconfigの内容(プロジェクトでフラグを省略できます):
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES GCC_GENERATE_TEST_COVERAGE_FILES = YES
スクリプトとsettings.xcconfigファイルをプロジェクトの横に配置し(最初にターゲット変数とSDK名の変数を必要なものに置き換えます)、実行すると...エラーが発生します。 当初、iPhone Simulatorはコマンドラインからテストを実行できません。 この迷惑な誤解を修正する方法は、
ここで説明されてい
ます 。 その後、スクリプトを再度実行し、統計情報付きのhtml-reportフォルダーを取得します。
UPD: Jenkinsとの緊密な統合のために、
gcovr +
Cobertura Pluginを使用できます。
ヒントをありがとう。