У меня есть тестовое окно для моего приложения, которое заполняет TextView
s в действии, а затем имитирует щелчок по кнопке Save
, которая передает данные в базу данных. Повторяю это несколько раз с разными данными, вызываем Instrumentation.waitForIdleSync()
, а затем проверяем, что введенные данные фактически находятся в базе данных. Недавно я провел этот тест три раза подряд без изменения или перекомпиляции моего кода. Результат каждый раз был другим: один тестовый прогон прошел, а два других тестовых прогона сообщили о различных элементах данных, отсутствующих в базе данных. Что может вызвать подобное поведение? Возможно ли это из-за некоторых условий гонки между конкурирующими потоками? Как мне отлаживать это, когда результат отличается при каждом запуске?Запуск теста JUnit несколько раз дает разные результаты
ответ
Похоже, состояние гонки. Помните, что в мире потоковой передачи нет способа обеспечить выполнение времени выполнения.
Я не являюсь разработчиком Android, поэтому я только размышляю, но пользовательский интерфейс работает только на одном потоке событий, поэтому, когда вы вызываете метод из другого потока (ваш тест), вы, вероятно, нарушаете это, поскольку вы находитесь вне потока событий.
Вы можете попробовать использовать семафор или, скорее всего, заблокировать ресурс. 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, а не утверждает, но это личное предпочтение)
I (наконец!) нашел решение этой проблемы. Теперь я вызываю finish()
на тестируемый Activity
, чтобы убедиться, что все его подключения к базе данных закрыты. Кажется, это гарантирует согласованность данных при выполнении утверждений.
- 1. Запуск эспрессо-теста несколько раз
- 2. Физика SpriteKit дает разные результаты каждый раз
- 3. Запуск тестового теста PHPUnit несколько раз
- 4. RSACryptoPad дает разные результаты каждый раз, когда
- 5. Parallel.ForEach дает разные результаты каждый раз
- 6. Запуск теста jUnit для контекста
- 7. Запуск теста JUnit на результаты контроллера в UnsatisfiedDependencyException
- 8. Запуск теста @Ignored JUnit в Eclipse
- 9. StrToTime дает разные результаты
- 10. Xstream дает разные результаты
- 11. OpenQuery дает разные результаты
- 12. Запуск мастера затмения из теста junit?
- 13. Junit 2.0: Различные результаты для одного теста
- 14. Запуск программы дает мне разные результаты в режиме отладки
- 15. Control.PointToScreen дает разные результаты - почему?
- 16. Как регистрировать результаты теста JUnit в файл?
- 17. Запуск теста Junit через командную строку
- 18. Запуск теста JUnit в качестве цели Ant
- 19. Запуск отдельного теста JUnit из отдельного класса
- 20. Запуск многопользовательского теста с junit и TAURUS
- 21. Повторный запуск неудачного теста с использованием Junit
- 22. Запуск теста JUnit только на Linux
- 23. @Autowired дает другой объект в каждый момент времени теста JUnit
- 24. Повторение SYNCDB дает разные результаты?
- 25. CSS Центрирование дает разные результаты
- 26. Сравнение массивов дает разные результаты
- 27. Python BeautifulSoup дает разные результаты
- 28. Сравнение значений дает разные результаты
- 29. Почему кодирование дает разные результаты?
- 30. Java URLEncode дает разные результаты
Спасибо за ссылки на классы Lock и Semaphore. Я посмотрю на них. Добавления Android к JUnit требуют, чтобы некоторые из методов, используемых в моих тестах, запускались в потоке пользовательского интерфейса, например, имитируя нажатие кнопки. Наверное, мне нужно посмотреть, какие другие потоки также работают. Я подозреваю, что есть хотя бы еще один, поскольку я должен явно указать JUnit, какие тесты (или части тестов) выполняются в потоке пользовательского интерфейса. –
И поскольку мой вопрос специфичен для Android, вот документы Android для пакета [java.util.concurrent] (http://developer.android.com/reference/java/util/concurrent/package-summary.html) , –