2013-02-21 80 views
2

我有一个测试用例,用于填充活动中的TextView的应用程序,然后模拟单击将数据提交到数据库的Save按钮。我用不同的数据重复这几次,调用Instrumentation.waitForIdleSync(),然后检查插入的数据实际上是否在数据库中。我最近连续三次运行这个测试,没有改变或重新编译我的代码。每次的结果都不一样:一次测试运行通过,另外两次测试运行报告数据库中缺少不同的数据项。什么会导致这种行为?这是否可能是由于竞争线程之间的竞争条件?如果每次运行结果都有所不同,我该如何进行调试?多次运行JUnit测试给出了不同的结果

回答

1

看起来像一个竞争条件。记住在线程的世界中没有办法确保运行时的顺序。

我不是Android开发人员,所以我只是猜测,但是UI只在一个事件线程一般,所以当你从另一个调用线程的方法(测试),你可能打破,当你在外面的事件线程。

你可以尝试使用旗语或更可能在资源上的锁。 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

+0

感谢链接到锁和信号类。我会研究这些。添加到JUnit的Android需要在我的测试中使用的一些方法在UI线程上运行,例如模拟按钮单击。我想我需要看看还有哪些线程也在运行。我怀疑还有至少一个,因为我必须明确告诉JUnit在UI线程上运行了哪些测试(或部分测试)。 – 2013-02-22 03:37:44

+0

而且,由于我的问题是具体到Android,这里都为[java.util.concurrent包] Android的文档(http://developer.android.com/reference/java/util/concurrent/package-summary.html) 。 – 2013-02-22 06:02:34

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); 
} 

当我要在电脑我会尝试重新审视成以上,使之更好的(我实际上的使用hamcrest而不是断言,但是这是个人喜好)

0

我(终于!)找到了解决这个问题的办法。我现在在测试的Activity上拨打finish()以确保其与数据库的所有连接均已关闭。这似乎确保了在运行断言时数据的一致性。

相关问题