2013-02-21 3 views
2

У меня есть тестовое окно для моего приложения, которое заполняет TextView s в действии, а затем имитирует щелчок по кнопке Save, которая передает данные в базу данных. Повторяю это несколько раз с разными данными, вызываем Instrumentation.waitForIdleSync(), а затем проверяем, что введенные данные фактически находятся в базе данных. Недавно я провел этот тест три раза подряд без изменения или перекомпиляции моего кода. Результат каждый раз был другим: один тестовый прогон прошел, а два других тестовых прогона сообщили о различных элементах данных, отсутствующих в базе данных. Что может вызвать подобное поведение? Возможно ли это из-за некоторых условий гонки между конкурирующими потоками? Как мне отлаживать это, когда результат отличается при каждом запуске?Запуск теста JUnit несколько раз дает разные результаты

ответ

1

Похоже, состояние гонки. Помните, что в мире потоковой передачи нет способа обеспечить выполнение времени выполнения.

Я не являюсь разработчиком 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

+0

Спасибо за ссылки на классы Lock и Semaphore. Я посмотрю на них. Добавления Android к JUnit требуют, чтобы некоторые из методов, используемых в моих тестах, запускались в потоке пользовательского интерфейса, например, имитируя нажатие кнопки. Наверное, мне нужно посмотреть, какие другие потоки также работают. Я подозреваю, что есть хотя бы еще один, поскольку я должен явно указать JUnit, какие тесты (или части тестов) выполняются в потоке пользовательского интерфейса. –

+0

И поскольку мой вопрос специфичен для Android, вот документы Android для пакета [java.util.concurrent] (http://developer.android.com/reference/java/util/concurrent/package-summary.html) , –

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

I (наконец!) нашел решение этой проблемы. Теперь я вызываю finish() на тестируемый Activity, чтобы убедиться, что все его подключения к базе данных закрыты. Кажется, это гарантирует согласованность данных при выполнении утверждений.

Смежные вопросы