Проблемы с JUnit 4 test suite - PullRequest
       22

Проблемы с JUnit 4 test suite

2 голосов
/ 11 июня 2010

У меня проблема с некоторыми тестами JUnit 4, которые я запускаю с набором тестов.

Если я запускаю тесты по отдельности, они работают без проблем, но при запуске в наборе большинство из них, 90% методов тестирования, не работают с ошибками. То, что я заметил, - то, что всегда первые тесты работают хорошо, но остальные терпят неудачу. Другое дело, что некоторые из тестов методов не выполняются в правильном порядке (отражение не работает должным образом или работает, потому что поиск методов не обязательно находится в созданном порядке). Обычно это происходит, если существует более одного теста с методами с одинаковыми именами. Я попытался отладить некоторые из тестов, и кажется, что от строки к следующей значение некоторых атрибутов становится null.

Кто-нибудь знает, в чем проблема, или поведение "нормальное"?

Заранее спасибо.

P.S .: Хорошо, тесты не зависят друг от друга, ни один из них не делает, и все они имеют @BeforeClass, @Before, @After, @AfterClass, поэтому между тестами все проясняется. Тесты работают с базой данных, но база данных очищается перед каждым тестом в @BeforeClass, поэтому это не должно быть проблемой.

Простой пример:

ТЕСТ ЛЮКС:

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
importy testclasses...;

@RunWith(Suite.class)
@Suite.SuiteClasses({ Test1.class, Test2.class })
public class TestSuiteX {
 @BeforeClass
 public static void setupSuite() { System.out.println("Tests started"); }   
 @AfterClass
 public static void setupSuite() { System.out.println("Tests started"); }   
}

ИСПЫТАНИЯ: Тесты проверяют функциональность серверного приложения, работающего на Glassfish.

Теперь тесты расширяют базовый класс, у которого есть @BeforeClass - метод, который очищает базу данных и логин, и @AfterClass, который только выполняет выход из системы. Это не источник проблем, потому что то же самое произошло до введения этого класса.

Класс имеет некоторые открытые статические атрибуты, которые не используются в других тестах, и реализует 2 метода управления.

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

Пример тестовых классов:

    imports....

    public class Test1 extends AbstractTestClass {  
    protected static Log log = LogFactory.getLog( Test1.class.getName() );

    @Test
    public void test1_A() throws CustomException1, CustomException2 {

        System.out.println("text");

        creates some entities with the server api.
        deletes a couple of entities with the server api.

        //tests if the extities exists in the database
        Assert.assertNull( serverapi.isEntity(..) );

    }

}

и второй:

public class Test1 extends AbstractTestClass {

    protected static Log log = LogFactory.getLog( Test1.class.getName() );

    private static String keyEntity;
    private static EntityDO entity;

    @Test
    public void test1_B() throws CustomException1, CustomException2 {

        System.out.println("text");

        creates some entities with the server api, adds one entities key to the static attribute and one entity DO to the static attribute for the use in the next method.
        deletes a couple of entities with the server api.

        //tests if the extities exists in the database
        Assert.assertNull( serverapi.isEntity(..) );

    }

    @Test
    public void test2_B() throws CustomException1, CustomException2 {

        System.out.println("text");

        deletes the 2 entities, the one retrieved by the key and the one associated with the static DO attribute

        //tests if the deelted entities exists in the database
        Assert.assertNull( serverapi.isEntity(..) );

    }

Это базовый пример, реальные тесты более сложные, но я пробовал с упрощенными тестами, и все же он не работает. Спасибо.

Ответы [ 3 ]

3 голосов
/ 11 июня 2010

Ситуация, которую вы описываете, звучит как побочная проблема. Вы упоминаете, что тесты прекрасно работают в изоляции, но зависят от порядка операций: это обычно является критическим симптомом.

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

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

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

1 голос
/ 11 июня 2010

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

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

Если у вас есть общий код настройки / разрыва теста, вы должны поместить его в отдельные методы, отмеченные @Before / @After. Они выполняются до и после каждого метода испытаний.

Обновление: Вы написали

база данных очищается перед каждым тестом в @ BeforeClass

если это не опечатка, это может стать источником ваших проблем. Очистка БД в методе @Before - @BeforeClass запускается только один раз для каждого класса.

0 голосов
/ 11 июня 2010

Будьте осторожны при использовании @BeforeClass, чтобы настроить вещи раз и навсегда, и @Before, чтобы настроить вещи перед каждым отдельным тестом. И будьте осторожны с переменными экземпляра.

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

...