Menu > Android > Test Note

目次

参考にするリンク

Testing|Android Developers
http://developer.android.com/tools/testing/index.html
JUnit - Android Wiki*
http://wikiwiki.jp/android/?JUnit

関係するパッケージ・クラス


Pickup:android.test.MoreAsserts

JUnitには無い Assert メソッドを提供している。
  • 各種配列のassertEquals()
  • SetのassertEquals()
  • assertMatchesRegex()
  • assertContentsInOrder()
などなど。

Pickup:android.test.mockの各Mock

MockApplication ApplicationクラスのMock
MockContentProvider ContentProviderを継承しているMock
MockContentResolver テスト用にContentResolverを継承しているMock
MockContext ContextクラスのMock
MockCursor Cursorを実装しているMock。テストコードと本物のCursorを分離するために使用する。
MockDialogInterface DialogInterfaceクラスのMock
MockPackageManager PackageManagerクラスのMock
MockResources ResourcesクラスのMock

基本的に、各種Mockの実装・継承メソッドを呼ぶと UnsupportedOperationException が発生する。
必要ならOverrideしてね、ということだと思う。

Pickup:android.test.suitebuilder

2つのクラスが存在する。
こういう感じで利用する。
また指定パッケージのみ使えるようにする includePackages() や、下記にあるTestMethodを利用して特定のメソッドを追加する addRequirements() なんかもある。
メソッド指定でTestCaseを追加する場合に使用する。
TestSuiteに登録する場合は createTest() で返ってくる TestCase を登録しよう。
この辺に使用例がある。

TestSuiteについて

作成しておいたテストを一度に実行したり、特定のクラスだけ実行できるので、作っておくと便利。
Androidでは全てのテストを実行する場合にTestSuiteBuilderが使えるので活用しよう。

あとは部分的に実行する場合だが、本来ならパッケージ毎に機能が分かれているだろうから各所にTestSuiteを設けるのがよい。

バグ対応などで複数のパッケージに渡る修正を行った場合は各パッケージのテストを実行することが望ましい。
しかし、たまに(上層部やお客様から)修正箇所のみのテスト数を求められることがあるので、Annotationを用いた部分実行のSampleについても記載しておく。

パッケージ以下にある全てのTestCase内メソッドをテストする(よくあるやつ)

/**
 * パッケージ以下にある全てのTestCase内メソッドをテストする.
 */
public class AllTests {
    public static Test suite() {
        return new TestSuiteBuilder(AllTests.class).includeAllPackagesUnderHere().build();
    }
} 



パッケージ以下にある全てのTestCase内にある特定のメソッドをテストする

/**
 * パッケージ以下にある全てのTestCase内にある特定のメソッドをテストする.
 * 
 * @see TargetTestAnnotation
 */
public class TargetTests {
 
    public static Test suite() {
        return createTargetTests(443);
    }
 
    private static TestSuite createTargetTests(int refnum) {
        // まずはパッケージ以下のTestCaseを拾う
        TestSuite allTestSuite =
                new TestSuiteBuilder(TargetTests.class)
                        .includeAllPackagesUnderHere()
                        .build();
 
        // 登録したテストケースに重複があるか分からないので、一意にしておく
        LinkedHashSet<String> classes = new LinkedHashSet<String>();
        for (int index = 0, size = allTestSuite.testCount(); index < size; index++) {
            // 返却される Test インタフェースの中身は TestCase なので、toString() すると getName() が見える
            classes.add(allTestSuite.testAt(index).toString());
        }
 
        // クラス名を使用してテストを登録
        TestSuite suite = new TestSuite();
        try {
            for (String className : classes) {
                @SuppressWarnings("unchecked")
                Class<? extends TestCase> cls = (Class<? extends TestCase>) Class.forName(className);
                for (Method method : cls.getMethods()) {
                    // 事前に登録しておいた TargetTestAnnotation からテスト対象のメソッドを抽出
                    TargetTestAnnotation annotation = method.getAnnotation(TargetTestAnnotation.class);
 
                    if (annotation == null)
                        continue;
                    if (linearSearch(annotation.value(), refnum) == -1)
                        continue;
 
                    suite.addTest(new TestMethod(method, cls).createTest());
                }
            }
        } catch (Exception err) {
            throw new RuntimeException();
        }
        return suite;
    }
 
    // Arraysにありそうで無いメソッド
    private static int linearSearch(int[] a, int value) {
        for (int counter = 0, size = a.length; counter < size; counter++) {
            if (a[counter] == value) return counter;
        }
        return -1;
    }
} 

アノテーションはこんな感じ。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TargetTestAnnotation {
    int[] value();
} 

使用例
public class SampleTest extends AndroidTestCase {
 
    // 指定が1つの場合はこれでOK
    @TargetTestAnnotation(443)
    public void test_New_01() throws Exception {
        // テスト内容
    }
 
    // 複数指定することもできる
    @TargetTestAnnotation({
            443, 445
    })
    public void test_New_02() throws Exception {
        // テスト内容
    }
} 



まとめ

関連リンク

&trackback()
タグ一覧:Android Test



タグ:

Android Test
最終更新:2012年12月08日 17:11