Подтвердить что ты не робот

Рекомендации по зависимостям файловой системы в тестах unit/integration

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

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

Знаете ли вы рекомендации по работе с зависимостями файловой системы в тестах unit/integration?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Зависимости от файловой системы здесь представлены в двух вариантах:

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

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

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

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

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

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

То же самое можно сказать и для URL-адресов и URI.

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

Дайте тестовые файлы, как внутри, так и вне, имена, структурно похожие на имя unit test.

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

File reportFile = new File("tests/output/" + getClass().getSimpleName() + "/" + getName() + ".report.html");