多次运行JUnit测试给出了不同的结果
我有一个测试用例,用于填充活动中的TextView
的应用程序,然后模拟单击将数据提交到数据库的Save
按钮。我用不同的数据重复这几次,调用Instrumentation.waitForIdleSync()
,然后检查插入的数据实际上是否在数据库中。我最近连续三次运行这个测试,没有改变或重新编译我的代码。每次的结果都不一样:一次测试运行通过,另外两次测试运行报告数据库中缺少不同的数据项。什么会导致这种行为?这是否可能是由于竞争线程之间的竞争条件?如果每次运行结果都有所不同,我该如何进行调试?多次运行JUnit测试给出了不同的结果
看起来像一个竞争条件。记住在线程的世界中没有办法确保运行时的顺序。
我不是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
我建议对数据库数据进行探测,而不是直接断言。通过这个我的意思是做一段代码,将不断检查数据库达到一定的时间条件,而不是等待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而不是断言,但是这是个人喜好)
我(终于!)找到了解决这个问题的办法。我现在在测试的Activity
上拨打finish()
以确保其与数据库的所有连接均已关闭。这似乎确保了在运行断言时数据的一致性。
感谢链接到锁和信号类。我会研究这些。添加到JUnit的Android需要在我的测试中使用的一些方法在UI线程上运行,例如模拟按钮单击。我想我需要看看还有哪些线程也在运行。我怀疑还有至少一个,因为我必须明确告诉JUnit在UI线程上运行了哪些测试(或部分测试)。 – 2013-02-22 03:37:44
而且,由于我的问题是具体到Android,这里都为[java.util.concurrent包] Android的文档(http://developer.android.com/reference/java/util/concurrent/package-summary.html) 。 – 2013-02-22 06:02:34