diff --git a/documentation/docs/recommendations/avaliable-code.md b/documentation/docs/recommendations/avaliable-code.md new file mode 100644 index 000000000..7f903e99b --- /dev/null +++ b/documentation/docs/recommendations/avaliable-code.md @@ -0,0 +1,14 @@ +# Ограничения тестируемого кода + +## Только синхронных код + +YAxUnit выполняет тесты последовательно, вызов каждого теста это синхронный вызов тестового метода, в связи с этим не поддерживается: + +* Тестирование методов построенных на обработчиках +* Тестирование асинхронных методы + +## Тестирование форм + +YAxUnit плохо подходит для тестирования форм. Формы, это в первую очередь про взаимодействие с пользователем, с другими объектами системы. +Для их проверки лучше подходят такие инструменты как [vanessa-automation]([vanessa-automation](https://github.com/Pr-Mex/vanessa-automation)), [add](https://github.com/vanessa-opensource/add) или [tester](https://github.com/grumagargler/tester). Они позволяют проще и комплексно проверить работу форм. +Если же в форме расположена сложная логика слабо связанная с отображением, то ее можно вынести в общий модуль, который будет вызываться из формы и тестировать уже методы этого общего модуля. \ No newline at end of file diff --git a/documentation/docs/recommendations/common-recommendations.md b/documentation/docs/recommendations/common-recommendations.md new file mode 100644 index 000000000..c03386b76 --- /dev/null +++ b/documentation/docs/recommendations/common-recommendations.md @@ -0,0 +1,469 @@ +--- +tags: [Начало, Рекомендации] +sidebar_position: 1 +--- + +# Общие рекомендации по модульному тестированию + +:::tip Перевод +Перевод (gpt) и адаптация статьи [Unit testing best practices with .NET Core and .NET Standard](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices) by [John Reese](https://reese.dev/) +::: + +:::warning +Рекомендации помогут при написании модульных тестов, чтобы обеспечить устойчивость и удобство их понимания. +Ситуации бывают разные и иногда приходится отступать от рекомендаций, но это не повод ими пренебрегать. +::: + +## Избегайте зависимостей от инфраструктуры + +Старайтесь не вводить зависимости от инфраструктуры при написании юнит-тестов. Эти зависимости делают тесты медленными и ненадежными, и их следует оставлять для интеграционных тестов. + +## Название ваших тестов + +Имя вашего теста должно состоять из трех частей: + +* Название тестируемого метода. +* Сценарий, в котором он тестируется. +* Ожидаемое поведение при вызове сценария. + +:::note Почему это важно? +Стандарты именования важны, поскольку они явно выражают цель теста. Тесты — это не просто проверка работоспособности вашего кода, но и документация. Посмотрев на набор юнит-тестов, вы должны иметь возможность понять поведение вашего кода, не заглядывая в сам код. Кроме того, когда тесты не проходят, вы точно видите, какие сценарии не соответствуют вашим ожиданиям. +::: + +```bsl title="Плохо" +Процедура Тест_ОднаСтрока() Экспорт + + Результат = ЮТСтроки.ДобавитьСтроку("Иванов", ""); + + ЮТест.ОжидаетЧто(Результат) + .Равно("Иванов"); + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + Результат = ЮТСтроки.ДобавитьСтроку("Иванов", ""); + + ЮТест.ОжидаетЧто(Результат) + .Равно("Иванов"); + +КонецПроцедуры +``` + +## Организация ваших тестов + +**Подготовка**, **Действие**, **Проверка** — это распространённый паттерн в юнит-тестировании. Как следует из названия, он состоит из трех основных действий: + +* **Подготовьте** объекты, создайте их и настройте по мере необходимости. +* Выполните **действие** над объектом. +* **Проверьте**, что всё соответствует ожиданиям. + +:::note Почему это важно? + +* Такой подход четко разделяет тестируемую логику и этапы подготовки и проверки. +* Снижает вероятность смешивания утверждений с кодом действия. +::: + +Читаемость — один из важнейших аспектов при написании тестов. Разделение этих действий в тесте ясно подчеркивает зависимости, необходимые для вызова вашего кода, как именно ваш код вызывается и что вы пытаетесь проверить. Хотя возможно объединить некоторые шаги и уменьшить размер теста, основной целью является максимальная читаемость теста. + +```bsl title="Плохо" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + // Подготовка + ИсходнаяСтрока = "Иванов"; + ПустаяСтрока = ""; + + // Проверка + ЮТест.ОжидаетЧто(ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ПустаяСтрока)) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + // Подготовка + ИсходнаяСтрока = "Иванов"; + ПустаяСтрока = ""; + + // Действие + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ПустаяСтрока); + + // Проверка + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры +``` + +## Пишите минимально проходящие тесты + +Входные данные для юнит-теста должны быть как можно проще, чтобы проверить поведение, которое вы сейчас тестируете. + +:::note Почему это важно? + +* Тесты становятся более устойчивыми к будущим изменениям в кодовой базе. +* Они ближе к тестированию поведения, а не реализации. +::: + +Тесты, которые включают больше информации, чем требуется для прохождения, могут содержать больше ошибок и затруднять понимание намерения. При написании тестов важно сосредоточиться на поведении. Установка дополнительных свойств в моделях или использование ненулевых значений, когда это не требуется, отвлекает от того, что вы пытаетесь доказать. + + + +```bsl title="Плохо" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + // Подготовка + ИсходнаяСтрока = "Иванов"; + + // Действие + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, "", ";"); + + // Проверка + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + // Подготовка + ИсходнаяСтрока = "Иванов"; + + // Действие + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ""); + + // Проверка + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры +``` + +## Избегайте "магических" строк + +Именование переменных в юнит-тестах так же важно, если не более важно, чем в рабочем коде. Юнит-тесты не должны содержать магических строк. + +:::note Почему это важно? + +* Устраняет необходимость читателю теста проверять основной код, чтобы понять, что делает значение особенным. +* Явно показывает, что вы пытаетесь *проверить*, а не *выполнить*. +::: + +"Магические" строки могут вызывать путаницу у читателя ваших тестов. Если строка выглядит необычно, может возникнуть вопрос, почему для параметра или возвращаемого значения выбрано определенное значение. Такие строки могут отвлекать внимание от теста и заставлять заглядывать в детали реализации. + +:::tip Совет +При написании тестов стремитесь выразить как можно больше намерений. В случае с магическими строками хорошим подходом будет присваивать эти значения переменным, либо использовать случайные значения. +::: + +```bsl title="Плохо" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + Результат = ЮТСтроки.ДобавитьСтроку("Иванов", ""); + + ЮТест.ОжидаетЧто(Результат) + .Равно("Иванов"); + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ПустаяСтрока = ""; + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ПустаяСтрока); + + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры +``` + +## Избегайте логики в тестах + +При написании юнит-тестов старайтесь избегать ручной конкатенации строк, логических условий (таких как `Если`, `Пока`, `Для`, `#Если`) и других условий. + +:::note Почему это важно? + +* Меньше шансов внедрить ошибку в тесты. +* Фокус на конечном результате, а не на деталях реализации. +::: + +Введение логики в тесты значительно увеличивает риск ошибок. Меньше всего вам нужна ошибка в наборе тестов. Вы должны быть уверены, что ваши тесты работают, иначе не сможете им доверять. Тесты, которым вы не доверяете, не имеют ценности. Когда тест не проходит, вы хотите быть уверены, что что-то не так с вашим кодом, и это нельзя игнорировать. + +:::tip Совет +Если логика в тесте кажется неизбежной, подумайте о разделении теста на два или более отдельных теста. +::: + +```bsl title="Плохо" +Процедура ДобавитьСтроку() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + РазделительПоУмолчанию = ";"; + + Варианты = ЮТест.Варианты("ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель, Результат") + .Добавить(ИсходнаяСтрока, "", Неопределено, ИсходнаяСтрока) + .Добавить(ИсходнаяСтрока, ДополнительнаяСтрока, Неопределено, ИсходнаяСтрока + РазделительПоУмолчанию + ДополнительнаяСтрока) + .Добавить(ИсходнаяСтрока, ДополнительнаяСтрока, ";", ИсходнаяСтрока + ";" + ДополнительнаяСтрока) + .Добавить("", ДополнительнаяСтрока, Неопределено, ДополнительнаяСтрока) + ; + + Для Каждого Вариант Из Варианты.СписокВариантов() Цикл + + Если Вариант.Разделитель = Неопределено Тогда + Результат = ЮТСтроки.ДобавитьСтроку(Вариант.ИсходнаяСтрока, Вариант.ДополнительнаяСтрока); + Иначе + Результат = ЮТСтроки.ДобавитьСтроку(Вариант.ИсходнаяСтрока, Вариант.ДополнительнаяСтрока, Вариант.Разделитель); + КонецЕсли; + + ЮТест.ОжидаетЧто(Результат) + .Равно(Вариант.Результат); + + КонецЦикла; + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ""); + + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры + +Процедура ДобавитьСтроку_БезИсходной_ВернетТужеСтроку() Экспорт + + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку("", ДополнительнаяСтрока); + + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры + +Процедура ДобавитьСтроку_СДополнением_ВернетОбъединениеСтрок() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ДополнительнаяСтрока); + + ЮТест.ОжидаетЧто(Результат) + .НачинаетсяС(ИсходнаяСтрока) + .ЗаканчиваетсяНа(ДополнительнаяСтрока) + ; + +КонецПроцедуры + +Процедура ДобавитьСтроку_СУказаннымРазделителем_ВернетОбъединениеСтрокИУказанногоРазделителя() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + Разделитель = ЮТест.Данные().СлучайнаяСтрока(); + ОжидаемыйРезультат = СтрШаблон("%1%2%3", ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель) + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель); + + ЮТест.ОжидаетЧто(Результат) + .НачинаетсяС(ИсходнаяСтрока) + .Содержит(Разделитель) + .ЗаканчиваетсяНа(ДополнительнаяСтрока) + .Равно(ОжидаемыйРезультат) + ; + +КонецПроцедуры +``` + +## Предпочитайте вспомогательные методы для настройки и очистки + +Если вам требуется похожий объект или состояние для ваших тестов, используйте вспомогательные методы, а не обработчики событий `ПередХХХХХХ` и `ПослеХХХХХХ`. + +:::note Почему это важно? + +* Меньше путаницы при чтении тестов, так как весь код виден в каждом тесте. +* Снижается вероятность избыточной или недостаточной настройки для конкретного теста. +* Уменьшается вероятность совместного использования состояния между тестами, что создает нежелательные зависимости. +::: + +В метод `ПередКаждымТестом` вызывается перед каждым тестом в вашем наборе тестов. Хотя некоторые могут считать это полезным инструментом, на практике это часто приводит к раздуванию тестов и снижению их читаемости. Каждый тест обычно имеет разные требования для успешного выполнения. К сожалению, `ПередКаждымТестом` заставляет использовать одинаковые требования для всех тестов. + +Тоже самое касается методов `ПередТестовымНабором` и `ПередВсемиТестами`. + +```bsl title="Плохо" +Процедура ПередКаждымТестом() Экспорт + + // Создание номенклатуры + + // Установка цены + +КонецПроцедуры + +Процедура КонтрольОстатков_НаличиеОстатков_Успешно() Экспорт + + // Алгоритм проверки + +КонецПроцедуры + +Процедура КонтрольОстатков_ОтсутствиеОстатков_Ошибка() Экспорт + + // Алгоритм проверки + +КонецПроцедуры + +Процедура ПроверкаЗаполнения_НетЦены_Ошибка() Экспорт + + // Алгоритм проверки + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура КонтрольОстатков_НаличиеОстатков_Успешно() Экспорт + + Номенклатура = НоваяНоменклатура(); + УстановитьЦенуНоменклатуры(Номенклатура); + + // Алгоритм проверки + +КонецПроцедуры + +Процедура КонтрольОстатков_ОтсутствиеОстатков_Ошибка() Экспорт + + Номенклатура = НоваяНоменклатура(); + УстановитьЦенуНоменклатуры(Номенклатура); + + // Алгоритм проверки + +КонецПроцедуры + +Процедура ПроверкаЗаполнения_НетЦены_Ошибка() Экспорт + + Номенклатура = НоваяНоменклатура(); + // Алгоритм проверки + +КонецПроцедуры + +Функция НоваяНоменклатура() Экспорт + // Алгоритм создания +КонецФункции + +Процедура УстановитьЦенуНоменклатуры(Номенклатура, Цена = 10) Экспорт + // Алгоритм установки +КонецПроцедуры +``` + +## Избегайте нескольких действий + +При написании тестов старайтесь включать только одно действие на тест. Распространенные подходы для этого: + +* Создайте отдельный тест для каждого действия. +* Используйте параметризованные тесты. + +:::note Почему это важно? + +* При сбое теста ясно, какой сценарий завершается ошибкой +* Гарантирует, что тест сосредоточен только на одном случае. +* Позволяет получить полное представление о причинах неудач тестов. +::: + +Несколько действий требуют индивидуальной проверки, и не гарантируется, что все проверки будут выполнены. В большинстве платформ модульного тестирования сбой одного из проверочных утверждений в модульном тесте приводит к тому, что все последующие тесты автоматически считаются неудачными. Это может вызвать путаницу, так как работающая функциональность будет считаться сломанной. + +```bsl title="Плохо" +Процедура ДобавитьСтроку() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + РазделительПоУмолчанию = ";"; + + Варианты = ЮТест.Варианты("ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель, Результат") + .Добавить(ИсходнаяСтрока, "", Неопределено, ИсходнаяСтрока) + .Добавить(ИсходнаяСтрока, ДополнительнаяСтрока, Неопределено, ИсходнаяСтрока + РазделительПоУмолчанию + ДополнительнаяСтрока) + .Добавить(ИсходнаяСтрока, ДополнительнаяСтрока, ";", ИсходнаяСтрока + ";" + ДополнительнаяСтрока) + .Добавить("", ДополнительнаяСтрока, Неопределено, ДополнительнаяСтрока) + ; + + Для Каждого Вариант Из Варианты.СписокВариантов() Цикл + + Если Вариант.Разделитель = Неопределено Тогда + Результат = ЮТСтроки.ДобавитьСтроку(Вариант.ИсходнаяСтрока, Вариант.ДополнительнаяСтрока); + Иначе + Результат = ЮТСтроки.ДобавитьСтроку(Вариант.ИсходнаяСтрока, Вариант.ДополнительнаяСтрока, Вариант.Разделитель); + КонецЕсли; + + ЮТест.ОжидаетЧто(Результат) + .Равно(Вариант.Результат); + + КонецЦикла; + +КонецПроцедуры +``` + +```bsl title="Лучше" +Процедура ДобавитьСтроку_БезДополнения_ВернетТужеСтроку() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ""); + + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры + +Процедура ДобавитьСтроку_БезИсходной_ВернетТужеСтроку() Экспорт + + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку("", ДополнительнаяСтрока); + + ЮТест.ОжидаетЧто(Результат) + .Равно(ИсходнаяСтрока); + +КонецПроцедуры + +Процедура ДобавитьСтроку_СДополнением_ВернетОбъединениеСтрок() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ДополнительнаяСтрока); + + ЮТест.ОжидаетЧто(Результат) + .НачинаетсяС(ИсходнаяСтрока) + .ЗаканчиваетсяНа(ДополнительнаяСтрока) + ; + +КонецПроцедуры + +Процедура ДобавитьСтроку_СУказаннымРазделителем_ВернетОбъединениеСтрокИУказанногоРазделителя() Экспорт + + ИсходнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + ДополнительнаяСтрока = ЮТест.Данные().СлучайнаяСтрока(); + Разделитель = ЮТест.Данные().СлучайнаяСтрока(); + ОжидаемыйРезультат = СтрШаблон("%1%2%3", ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель) + + Результат = ЮТСтроки.ДобавитьСтроку(ИсходнаяСтрока, ДополнительнаяСтрока, Разделитель); + + ЮТест.ОжидаетЧто(Результат) + .НачинаетсяС(ИсходнаяСтрока) + .Содержит(Разделитель) + .ЗаканчиваетсяНа(ДополнительнаяСтрока) + .Равно(ОжидаемыйРезультат) + ; + +КонецПроцедуры +``` diff --git a/documentation/docs/recommendations/images/amongus.png b/documentation/docs/recommendations/images/amongus.png new file mode 100644 index 000000000..81fe33ef5 Binary files /dev/null and b/documentation/docs/recommendations/images/amongus.png differ diff --git a/documentation/docs/recommendations/index.md b/documentation/docs/recommendations/index.md new file mode 100644 index 000000000..bd0a4e0ae --- /dev/null +++ b/documentation/docs/recommendations/index.md @@ -0,0 +1,26 @@ +# Рекомендации + +Модульные тесты - это инструмент разработчика улучшающий качества работы. + +* Модульные тесты это код. +* Тесты идут совместно с доработками (при использовании git) +* Быстрый ответ +* Высокая скорость реализации и, соответственно, низкая стоимость. На проверку небольшой функции уходит всего несколько секунд. Изолированность юнитов позволяет проверять работоспособность нескольких модулей одновременно. +* Простота автоматизации. Unit тест исследует ответ кода на ввод данных и определенные действия. Он не требует проиграть сценарий взаимодействия конечного пользователя с новой функцией, поэтому автоматизация процесса не отнимает много сил и времени. + +На больших и сложных проектах стопроцентного покрытия кода тестами достичь сложно. К тому же, это нерационально. Показатель 70–90% считается хорошим. Он позволяет выявить максимальное количество ошибок. Мы собрали несколько практических советов по увеличению процента покрытия кода: + +* Пишите unit тест на каждый новый код сразу же. +* Используйте готовые решения – тестовые фреймворки. +* Создавайте тесты для проверки только одной функции. +* Используйте негативные тесты для проверки поведения программы в случае ввода неправильных данных. +* Используйте мутационные фреймворки с функцией изменения констант и условий для проверки качества unit тестов. +* Проверяйте тесты на стабильность. +* Следите за скоростью выполнения теста. + + +## Рекомендации по модульному тестированию с использованием YAxUnit + +Кроме [общих рекомендаций](common-recommendations.md) + +* Структура тестовых модулей: Модуль тестового набора должен соответствовать объекту решения, который он будет тестировать. Для этого мы предлагаем [схему наименования модулей](../getting-started/structure.md#схема-наименования-модулей) \ No newline at end of file diff --git a/documentation/docs/recommendations/links.md b/documentation/docs/recommendations/links.md new file mode 100644 index 000000000..0136e0300 --- /dev/null +++ b/documentation/docs/recommendations/links.md @@ -0,0 +1,5 @@ +# Полезные ссылки + +* [Код без тестов — легаси](https://habr.com/ru/companies/dododev/articles/544110/) + О легаси, о его изменении и покрытии тестами. +* https://less.works/ru/less/technical-excellence/unit-testing \ No newline at end of file diff --git a/documentation/docs/recommendations/what-to-test.md b/documentation/docs/recommendations/what-to-test.md new file mode 100644 index 000000000..8f18bca00 --- /dev/null +++ b/documentation/docs/recommendations/what-to-test.md @@ -0,0 +1,25 @@ +# Что тестировать + +:::warning +Это мой субъективный опыт, возможно он расходится с вашим. В этом случае вы можете или доработать данную статью или разместить свою рядом. +::: + +Ответ простой, тестируем то что дорабатываем. Начинайте с интеграционных (компонентных) тестов вашей задачи которые проверяют основные кейсы по задаче. + +В процессе написания тестов не требуется учитывать все возможные сценарии поведения программы. Рекомендуется сосредоточиться на ключевых задачах, а остальные вносить (дополнять) по мере необходимости. + +Идеальный подход: + +1. На основании технического задания необходимо выделить тест-кейсы. +2. Написать тесты реализующие эти кейсы, чаще всего это будут компонентные (интеграционные) тесты. +3. Реализовать функциональность задания. +4. При реализации добавляем новые тест-кейсы для упущенных и сложных моментов. +5. Добиваемся зеленого прохождения тестов. +6. Проверяем задачу вручную. +7. Задаем задачу. + +## Провокация: пишите компонентные тесты, а не unit тесты + +Заголовок выше противоречит основной мысли из многих современных книг и учебников. Компонентные тесты гораздо дольше выполняются и при этом не показывают четкое место поломки кода. Несмотря на это, мы говорим о них как об “оплоте стабильности”. Дело в том, что для качественного покрытия unit тестами требуется гораздо больше времени, чем для написания хорошего компонентного теста. Хорошее покрытие unit тестами не гарантирует вам правильность взаимодействия классов между собой. И это крайне дорогое удовольствие. На их разработку и поддержку требуется очень много времени. В реальном проекте программисту, как правило, не выделяют время на написание unit тестов. Получается, что если на проекте выбрана именно политика unit тестов, то эти тесты не отражают реальные сценарии использования приложения - проверяется “сферический конь в вакууме”, причем не во всех возможных состояниях системы. В итоге такая политика разработки тестов рано или поздно приводит к тому, что тесты перестают защищать от дефектов приложения. + +[Источник](https://habr.com/ru/companies/axenix/articles/724318/) \ No newline at end of file diff --git a/documentation/docs/recommendations/why-xunit.md b/documentation/docs/recommendations/why-xunit.md new file mode 100644 index 000000000..72bdf60b7 --- /dev/null +++ b/documentation/docs/recommendations/why-xunit.md @@ -0,0 +1,62 @@ +--- +tags: [Начало, Рекомендации] +sidebar_position: 0 +--- + +# Почему именно модульные тесты + +:::tip Перевод +Перевод (gpt) и адаптация статьи [Unit testing best practices with .NET Core and .NET Standard](https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices) by [John Reese](https://reese.dev/) +::: + +Существует несколько причин использования модульных тестов. + +