Рекомендации по зависимостям файловой системы в тестах unit/integration
Я только начал писать тесты для большого количества кода. Там есть куча классов с зависимостями файловой системы, то есть они читают файлы CSV, файлы конфигурации чтения/записи и т.д.
В настоящее время тестовые файлы хранятся в тестовом каталоге проекта (это проект Maven2), но по нескольким причинам этот каталог не всегда существует, поэтому тесты терпят неудачу.
Знаете ли вы рекомендации по работе с зависимостями файловой системы в тестах unit/integration?
Изменить: Я не ищу ответа на эту конкретную проблему, описанную выше. Это был просто пример. Я бы предпочел общие рекомендации по обработке зависимостей с файловой системой/базами данных и т.д.
Ответы
Ответ 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");