Автоматизированные Тесты. Продолжение
Начало
Подразумевает ли термин «модульное тестирование» тестирование каждой единицы реализации? Не совсем. Кент Бек, автор книги «Экстремальное программирование: разработка через тестирование», признал, что название «модульный тест», возможно, не лучший выбор. В этом контексте «модуль» относится к определённому поведению, которое может включать взаимодействие нескольких модулей реализации. Некоторые даже определяют «модуль» как целый пакет или библиотеку, и эта точка зрения также верна. Некоторые используют термины «изолированные» и «коммуникабельные» тесты, чтобы различать тесты, использующие и не использующие моки зависимостей.
Пишите код помогающий писать тесты
Написание теста должно быть простым, а тестовый код — понятным. Важно создать тестовую инфраструктуру, которая упрощает процесс написания тестов. Часто используют класс TestContext, содержащий общий код для написания тестов. Например, он может содержать код запуска приложения, отправки запроса, подтверждения ответа, регистрации мока и т. д. Так вы сможете сосредоточиться на написании теста, а не на шаблонном коде:
// Arrange
using var ctx = new TestContext();
ctx.ReplaceService<IService, MockImplementation>();
ctx.SetConfigurationFile("""{ "path: "/tmp" }""");
ctx.SeedDatabase(db =>
db.Users.Add(new User { Username = "user" }));
var user = ctx.SetCurrentUser("user");
// Act
var response = await ctx.Get("/user");
// Assert
Assert.AreEqual(response, """
Id: 1
UserName: user
""");
Нужно ли имитировать зависимости?
Моки (Moq) — способ протестировать приложение без использования реальных зависимостей. Поэтому, используя моки, вы тестируете не реальное приложение, а его разновидность. Важно максимально приблизить эту разновидность к реальности. Может быть сложно поддерживать тесты с моками. Сервисы, которые вы имитируете, могут изменить поведение, и вы можете не заметить этого, поскольку не используете их напрямую. Также приходится писать много кода для настройки тестов.
Разработчики, как правило, используют слишком много моков. Нужно ли имитировать файловую систему? Это не так-то просто, и у многих неправильные предположения о ней. Например, в Windows она чувствительна к регистру, некоторые имена файлов или символы в них недопустимы. В случае кроссплатформенного приложения может потребоваться протестировать поведение, специфичное для ОС. Почему бы просто не писать во временный каталог? То же самое касается БД. Можно использовать Docker для запуска БД, чтобы протестировать SQL и ограничения базы?
В большинстве случаев нужно имитировать внешние сервисы, которые не находятся под вашим контролем. Рассмотрите возможность использования фактических сервисов, когда это возможно. Конечно, желательно, чтобы тесты были изолированы. Здесь есть много стратегий. Например, если нужно читать или записывать файлы, можно создать временный каталог для каждого теста. Если вы запускаете БД в контейнере, можно использовать разные имена баз для изоляции тестов. Можно положиться на эмуляторы, предоставляемые поставщиками облачных услуг, для локального запуска некоторых зависимостей. Так вы будете уверены, что код работает, как ожидалось, и не нужно писать сложные моки. Убедитесь, что приложение можно настроить, например, легко подставлять разные строки соединений или папки для хранения данных приложения.
Полезные инструменты для избежания моков
- TestContainers или .NET Aspire. Если запуск Docker-контейнера медленный, можно переиспользовать его между несколькими тестовыми запусками. .NET Aspire также может предоставлять ресурсы в облаке (Azure, AWS и т. д.).
- Эмуляторы облачных сервисов. Например, Azure предоставляет эмулятор для хранилища.
Продолжение следует…
Источник: https://www.meziantou.net/automated-tests.htm