лучшие практики dbunit для повышения производительности - PullRequest
15 голосов
/ 10 декабря 2011

Каким рекомендациям / принципам следует следовать, кроме тех, которые рекомендованы на реальном сайте dbunit, которые могут значительно ускорить тесты и сохранить их ремонтопригодность? Я жажду библиотеки , например, фабриканта для Java, но это не похоже на то, что это возможно из-за статической типизации.

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

Буду признателен за соблюдение любых принципов, которые приведут к испытаниям, которые хорошо работают и просты в обслуживании.

Ответы [ 2 ]

8 голосов
/ 15 декабря 2011

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

Наборы данных были организованы иерархически. Тестируемая система состояла из нескольких (5-10) модулей, и данные испытаний соответствовали этой схеме. Скрипт юнит-теста выглядел так:

 include(../../masterDataSet.txt)
 include(../moduleDataSet.txt)

 # unit-specific test data
 someProperty=someData

Имена свойств были сопоставлены напрямую с записями БД с помощью какого-то странного инструмента, который я не могу вспомнить.

Тот же шаблон может быть применен к тестам DBUnit. В наборе основных данных вы можете размещать записи всегда с & mdash; как словари, первоначальная загрузка базы данных, как если бы она была установлена ​​с нуля.

В наборе данных модуля вы поместите записи, охватывающие тестовые случаи большинства тестов в модуле; Я не думаю, что ваш средний тест включает все ваши 70 таблиц базы данных, не так ли? У вас наверняка должны быть некоторые функциональные группы, которые могут составлять модуль, даже если приложение является монолитным. Попробуйте организовать тестовые данные на уровне модуля вокруг него.

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

Этот подход имеет огромное преимущество обучения; поскольку файлов данных мало, со временем вы фактически начинаете их запоминать. Вместо того, чтобы видеть сотни больших наборов данных, которые отличаются только незаметными деталями (которые вы должны узнавать каждый раз, когда возвращаетесь к тесту через некоторое время), вы можете легко определить, насколько различаются любые два набора данных.

Слово о производительности в конце. На моем 2-ядерном WinXP-компьютере с частотой 2,4 ГГц тест DBUnit включал:

  • , сбросив 14 столов,
  • создание 14 таблиц,
  • вставка ок. 100 записей,
  • выполнение тестовой логики,

занимает 1-3 секунды. Журналы показывают, что первые 3 операции занимают менее секунды, Spring занимает большую часть времени тестирования. Эта логика выполняется каждым тестом, чтобы избежать зависимостей порядка тестирования. Все работает на одной виртуальной машине со встроенным Derby, поэтому, возможно, так быстро.

РЕДАКТИРОВАТЬ: Я думаю, что наборы данных DBUnit XML не поддерживают включение других тестовых файлов, это можно преодолеть, используя базовый класс для всех интеграционных тестов, например ::1010

public class AbstractITest {

    @Before
    public void setUp() throws Exception {
        //
        // drop and recreate tables here if needed; we use 
        // Spring's SimpleJdbcTemplate executing drop/create SQL
        //
        IDataSet masterDataSet = new FlatXmlDataSetBuilder().build("file://masterDataSet.xml");
        DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, dataSet);
    }
}

public class AbstractModuleITest extends AbstractITest {

    @Before
    public void setUp() throws Exception {
        super.setUp();
        IDataSet moduleDataSet = new FlatXmlDataSetBuilder().build("file://moduleDataSet.xml");
        DatabaseOperation.CLEAN_INSERT.execute(dbUnitConnection, moduleDataSet);
    }
}

public class SomeITest extends AbstractModuleITest {
    // The "setUp()" routine only here if needed, remember to call super.setUp().

    @Test
    public void someTest() { ... }
}
3 голосов
/ 10 декабря 2011

Рекомендация в Junit в действии 2e на самом деле состоит не в том, чтобы создавать слишком много наборов данных (например, по одному на каждый тестовый класс), а в количестве, достаточном для поддержки. За исключением нескольких исключительных случаев, я счел возможным использовать основной набор данных для большинства модульных тестов и отдельные наборы данных для интеграционных тестов. Ограничение использования ExpectedDataSets также является опцией.

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

...