Указание порядка выполнения в тестовом примере JUnit - программирование
Подтвердить что ты не робот

Указание порядка выполнения в тестовом примере JUnit

У меня есть тестовый пример, когда я добавляю объект, обновляю его и удаляю. Следовательно, порядок исполнения важен здесь. Я хочу, чтобы это было:

  • Создать
  • Update
  • Удалить

Как ни странно, для всего одного тестового примера (из 15) JUnit выполняет его в следующем порядке:

  • Удалить
  • Update
  • Создать.

Как сообщить JUnit выполнить их в определенном порядке? В других случаях JUnit работает совершенно нормально (выполняется последовательно). И почему JUnit ведет себя странно в этом случае?

Соответствующий фрагмент кода ниже:

    private static Date date;
    private static int entity;
    static Parking p;
    public ParkingTests(String name) {
       super(name);
    }
    public void testAdd() throws Exception {
           //Add code here
    }
    public void testUpdate() throws Exception {
            //update code here
    }
    public void testDelete() throws Exception {
            //delete code here
    }
  }

Это становится страннее. Я запускаю множество тестовых примеров как часть набора. Если я запускаю только парковочный чемодан, заказ сохраняется. Если я запускаю его вместе с другими, его иногда поддерживают, иногда нет!

4b9b3361

Ответ 1

Ваша ситуация неудобна, так как плохо держать дублирующую работу для изоляции тестов (см. ниже) - но обратите внимание, что большую часть дублирования можно вытащить в setUp и tearDown (@Before, @After), поэтому вам не нужно много дополнительного кода. При условии, что тесты работают не так медленно, что вы часто их не запускаете, лучше очистить процессор от чистых тестов.

public void testAdd() throws Exception {
      // wipe database
      // add something
      // assert that it was added
}
public void testUpdate() throws Exception {
      // wipe database
      // add something
      // update it
      // assert that it was updated
}
public void testDelete() throws Exception {
      // wipe database
      // add something
      // delete it
      // assert that it was deleted
}

Альтернатива заключается в том, чтобы вставить все в один тест с несколькими утверждениями, но это сложнее понять и поддерживать, и дает немного меньше информации, когда тест терпит неудачу:

public void testCRUD() throws Exception {
      // wipe database
      // add something
      // assert that it was added
      // update it
      // assert that it was updated
      // delete it 
      // assert that it was deleted
}

Тестирование с помощью баз данных или коллекций или хранилищ любого рода сложно, потому что один тест может всегда влиять на другие тесты, оставляя нежелательные данные в базе данных/коллекции. Даже если ваши тесты явно не полагаются друг на друга, они все равно могут мешать друг другу, особенно если один из них не работает.

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

Обновление. Обычно лучше стереть данные в начале теста, поэтому один неудачный тестовый прогон не влияет на следующий прогон.

Ответ 2

Обычно тесты junit (методы тестирования) не должны зависеть друг от друга. Ниже взята из junit FAQ

Каждый тест проходит в собственном испытательном устройстве, чтобы изолировать тесты от изменения, сделанные другими тестами. То есть, тесты не разделяют состояние объектов в испытательном оборудовании. Поскольку тесты изолированы, они могут быть запущен в любом порядке...... Порядок вызова тестовых методов не является гарантируется.

Итак, если вы хотите сделать некоторые общие файлы инициализации, вы можете сделать это в методе, аннотированном с помощью @Before и очистке в методе, аннотированном с помощью @After. Или, если эта инициализация не требуется для всех методов тестирования в вашем тестовом классе, вы можете поместить ее в частные методы и соответствующим образом называть их своими тестами.

На стороне примечания, если вы все еще хотите упорядочить тесты, вы можете взглянуть на TestNG.

Ответ 3

Если вы определили, что хотите иметь порядок выполнения для своих тестов, JUnit 4.11 теперь поддерживает это посредством аннотации. См. этот поток для более подробного обсуждения - в основном, вы бы использовали

@FixMethodOrder

чтобы гарантировать некоторый порядок тестирования таким образом. Тем не менее, это обескураживает.

Ответ 4

Если вы используете Java 7, тогда вы должны знать, что Junit получает список всех тестов, используя метод Method [] getDeclaredMethods() из java.lang.Class. Вы можете прочитать из javadoc этого метода или из junit docs, которые: " Элементы в возвращаемом массиве не сортируются и не находятся в каком-либо конкретном порядке.", но в предыдущем списке методов реализации jvm как они были в исходном коде.

Это было взято из этого blog, и он обеспечивает работу.

Ответ 5

В общем, JUnit не гарантирует упорядочение тестовых случаев. Он не гарантируется в алфавитном порядке, ни в порядке в файле. Если порядок тестов был важен, то каждый из них зависит от результата предыдущего. Что делать, если первая не удалась? Должны ли мы даже беспокоиться о более поздних (и зависимых) тестах? Наверное, нет.

Итак, если бы у нас было это:

@Test
public void first(){...}

@Test
public void second() {...}

@Test
public void third() {...}

Мы не знаем, в каком порядке они будут работать. Поскольку мы надеемся, что они придут в порядок, и мы, вероятно, не будем беспокоиться о том, чтобы запустить второй или третий, если предыдущий (ые) не удалось, мы можем сделать это вместо:

@Test
public void firstThree(){
    first();
    second();
    third();
}

public void first(){...}
public void second() {...}
public void third() {...}

Обратите внимание, что на этот раз у нас только один @Test, и он гарантирует упорядочение.

Ответ 6

Если вы хотите запускать junit-тесты в порядке "так же, как они присутствуют в вашем исходном коде", см. мою заметку об этом здесь:

Как запускать тесты junit в порядке их присутствия в исходном коде

Но это действительно не очень хорошая идея, тесты должны быть независимыми.

Ответ 7

Что вы можете сделать:

  • Очистка базы данных перед каждым тестом
  • Сначала начните сначала тестирование первой логической операции. Когда у вас есть достаточная уверенность, предположите, что это правильно и перейдите к следующему и т.д.
  • Сначала напишите тесты на ящик, но начните с тестов черного ящика. Например, если у вас есть триггеры или подобные в вашей базе данных, начните с этого.