我的应用程序的测试用例填写了活动中的TextView
,然后模拟单击将Save
按钮提交到数据库的Instrumentation.waitForIdleSync()
按钮。我用不同的数据重复这几次,调用{{1}},然后检查插入的数据实际上是否在数据库中。我最近连续三次运行此测试而不更改或重新编译我的代码。每次结果都不同:一次测试运行通过,另外两次测试运行报告数据库中缺少不同的数据项。什么可能导致这种行为?是否可能是由于竞争线程之间的某些竞争条件?如果每次运行结果不同,我该如何调试?
答案 0 :(得分: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
答案 1 :(得分: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而不是断言,但这是个人偏好)
答案 2 :(得分:0)
我(终于!)找到了解决这个问题的方法。我现在在测试的finish()
上调用Activity
以确保它与数据库的所有连接都已关闭。这似乎可以确保在运行断言时数据的一致性。