Лучшие практики для зависимостей файловой системы в модульных / интеграционных тестах - PullRequest
21 голосов
/ 18 декабря 2008

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

В настоящее время тестовые файлы хранятся в тестовом каталоге проекта (это проект Maven2), но по нескольким причинам этот каталог не всегда существует, поэтому тесты не пройдены.

Знаете ли вы лучшие методы для работы с зависимостями файловой системы в модульных / интеграционных тестах?

Редактировать: Я не ищу ответ на ту конкретную проблему, которую я описал выше. Это был просто пример. Я бы предпочел общие рекомендации по обработке зависимостей от файловой системы / баз данных и т. Д.

Ответы [ 5 ]

24 голосов
/ 18 декабря 2008

Сначала следует попытаться держать модульные тесты подальше от файловой системы - см. Набор правил модульного тестирования . Если возможно, ваш код должен работать с потоками, которые будут буферами (т. Е. В памяти) для модульных тестов, и FileStream в рабочем коде.

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

Вы можете макетировать доступ к файловой системе / базе данных / сети в ваших модульных тестах.

Вы можете рассматривать модульные тесты, которые используют БД или файловые системы, как интеграционные тесты.

2 голосов
/ 18 декабря 2008

Зависимости от файловой системы здесь бывают двух видов:

  • файлы, от которых зависят ваши тесты; если вам нужны файлы для запуска теста, вы можете сгенерировать их в своих тестах и ​​поместить в каталог /tmp.
  • файлы, от которых зависит ваш код: файлы конфигурации или входные файлы.

Во втором случае часто можно реструктурировать ваш код, чтобы удалить зависимость от файла (например, java.io.File можно заменить на java.io.InputStream и java.io.OutputStream и т. Д.). возможно конечно.

Вам также может понадобиться обработать «недетерминированность» в файловой системе (у меня был чертовски задаток, отлаживающий что-то в NFS). В этом случае вам, вероятно, следует обернуть файловую систему в тонкий интерфейс.

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

InputStream getInputStream(File file) throws IOException {
    return new FileInputStream(file);
}

Затем вы можете заменить его на макет, который вы можете указать, чтобы сгенерировать исключение, или вернуть ByteArrayInputStream или что-то еще.

То же самое можно сказать о URL и URI.

1 голос
/ 18 декабря 2008

Существует два варианта тестирования кода, который необходимо прочитать из файлов:

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

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

Очевидно, что большинство хорошо написанных классов не будут иметь жестких зависимостей от файловой системы.

0 голосов
/ 04 февраля 2009

Дайте файлам теста, как входящим, так и исходящим, имена, которые структурно похожи на имя модульного теста.

В JUnit, например, я бы использовал:

File reportFile = new File("tests/output/" + getClass().getSimpleName() + "/" + getName() + ".report.html");
0 голосов
/ 18 декабря 2008

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

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

...