2

TextViewアクティビティにsをSave入力し、データをデータベースにコミットするボタンのクリックをシミュレートするアプリのテストケースがあります。これを別のデータで数回繰り返し、を呼び出しInstrumentation.waitForIdleSync()てから、挿入されたデータが実際にデータベースにあることを確認します。最近、コードを変更したり再コンパイルしたりせずに、このテストを3回続けて実行しました。結果は毎回異なりました。1回のテスト実行に合格し、他の2回のテスト実行では、データベースから欠落している異なるデータ項目が報告されました。この種の動作を引き起こす可能性があるのは何ですか?競合するスレッド間の競合状態が原因である可能性がありますか?実行するたびに結果が異なる場合、これをデバッグするにはどうすればよいですか?

4

3 に答える 3

1

競合状態のように見えます。スレッド化の世界では、実行時の順序を保証する方法がないことに注意してください。

私はアンドロイド開発者ではないので、推測にすぎませんが、UI は一般的に 1 つのイベント スレッド上にしかないため、別のスレッド (テスト) からメソッドを呼び出すと、イベント スレッドの外にいるため、おそらくそれを破っています。 .

セマフォまたはリソースのロックを使用してみてください。 http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html http://docs.oracle.com/javase/1.5.0/docs/api /java/util/concurrent/Semaphore.html

于 2013-02-21T02:23:17.730 に答える
1

私は(ついに!)この問題の解決策を見つけました。ここfinish()で、テスト対象Activityのデータベースへの接続がすべて閉じられていることを確認します。これにより、アサーションを実行したときにデータの一貫性が確保されるようです。

于 2013-11-23T02:23:14.547 に答える
0

データベースのデータを直接アサートするのではなく、プローブを作成することをお勧めします。これにより、x 秒 (またはアイドル時間) 待ってからチェックするのではなく、特定の時間までデータベースをチェックし続けるコードを作成することを意味します。私は適切なコンピューターを使用していないため、次のようにします。は疑似コードのみです

public static void assertDatabaseHasData(String message, String dataExpected, long maxTimeToWaitFor){
    long timeToWaitUntil = System.getCurrentTimeMillis() + maxTimeToWaitFor;
    boolean expectationMatched = false;
    do {
        if(databaseCheck() == dataExpected){
            expecttionMatched == true;
        }
    }while(!expectationMatched  && System.getCurrentTimeMillis() < timeToWaituntil);
    assertTrue(message, expectationMatched);
}

コンピューターに到達したら、上記を再検討して改善しようとします(実際には、アサートするのではなくハムクレストを使用しますが、それは個人的な好みです)

于 2013-02-21T08:43:59.240 に答える