2

アプリケーションをテストするクラスはほとんどありません。4秒以上続く場合はテストに失敗したいのですが。私のコードはテストを中断しますが、場合によっては次のテストクラスを実行しません。

私が書くとき(それはタイムアウトとは何の関係もありませんが、fail()の例にすぎません):

public void testSmth() {
    fail("msg");
}

失敗トレースは空であり、テストを中断して別のテストを開始します。しかし、タイムアウトのようにしたい場合は、次のようにします。

public void testSmth() {
    Timer timer = new Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            fail("msg");
        }
    }, 4000);

    // some tests (that even lasts more than 4 secons) like clickOnImage() etc.
}

テストは中断されますが、次のテストは実行されず、失敗トレースには次のようになります。

テストは完了まで実行できませんでした。理由:'''junit.framework.AssertionFailedError''が原因で、インストルメンテーションの実行に失敗しました。詳細については、デバイスのlogcatを確認してください

そしてLogCatで私は得ました:

07-26 11:46:07.428:E / AndroidRuntime(6195):致命的な例外:タイマー-1

07-26 11:46:07.428:E / AndroidRuntime(6195):junit.framework.AssertionFailedError:msg

07-26 11:46:07.428:E / AndroidRuntime(6195):junit.framework.Assert.fail(Assert.java:47)

07-26 11:46:07.428:E / AndroidRuntime(6195):java.util.Timer $ TimerImpl.run(Timer.java:284)

または多分私がしたいことをするためのいくつかの別の方法がありますか?

ありがとう。

4

2 に答える 2

1

runTest()メソッドを次のようなものでオーバーライドする必要があります。

[編集]このコードは新しいスレッドを作成し、実際のテストを実行します。Futureクラスを使用すると、このスレッドの実行にタイムアウトを設定でき、タイムアウトに達すると停止します。また、例外のキャッチも処理します。(残りのテストは引き続き実行されると述べましたか?)

これは、このタイムアウトを使用して、テストされたコードのどこかでテストが「ハング」したままにならないようにする場合に非常に役立ちます。

public class MyTestClass extends
                ActivityInstrumentationTestCase2<EditorActivity> {

@Override
public void runTest() throws Throwable {
    final Throwable[] exceptions = new Throwable[1];

    ExecutorService executor = Executors.newCachedThreadPool();
    Callable<Object> task = new Callable<Object>() {
        public Object call() throws Exception {

            try {
                doRunTest();
            }
            catch (Throwable t) {
                exceptions[0] = t;
            }

            return Boolean.TRUE;
        }
    };

    int timeOutMinutes = 10;
    String testCaseName = String.format("%s.%s", getClass().getName(), getName());

    Future<Object> future = executor.submit(task);
    try {
        future.get(timeOutMinutes, TimeUnit.MINUTES);
    } catch (TimeoutException ex) {
        Assertions.fail("[Test method timed out after " + timeOutMinutes + " minutes.]\n" + testCaseName);
    } catch (Throwable e) {
        throw e;
    } finally {
        future.cancel(true); // may or may not desire this
    }

    if (exceptions[0] != null) {
        throw exceptions[0];
    }
}


private void doRunTest() throws Throwable {
    super.runTest();
}

}
于 2013-11-21T08:06:30.730 に答える
1

タイムアウトに達した場合にテストに失敗したいだけの場合は、これで十分です。

public void test1() throws Exception {
    long start = System.currentTimeMillis();
    solo.sleep(5000);
    if (System.currentTimeMillis() - start > 4000) {
        fail("msg");
    }
}

public void test2() throws Exception {
    long start = System.currentTimeMillis();
    solo.sleep(3000);
    if (System.currentTimeMillis() - start > 4000) {
        fail("msg");
    }
}

実行中にテストを中断することは困難です。コマンドごとにタイムアウトをチェックすることもできますが、チェックには時間がかかり、テストメソッドの寿命が長くなります。

于 2013-11-21T20:02:48.137 に答える