Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Рекомендации по написанию модульных тестов #414

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions documentation/docs/recommendations/avaliable-code.md
Original file line number Diff line number Diff line change
@@ -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). Они позволяют проще и комплексно проверить работу форм.
Если же в форме расположена сложная логика слабо связанная с отображением, то ее можно вынести в общий модуль, который будет вызываться из формы и тестировать уже методы этого общего модуля.
469 changes: 469 additions & 0 deletions documentation/docs/recommendations/common-recommendations.md

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions documentation/docs/recommendations/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Рекомендации

Модульные тесты - это инструмент разработчика улучшающий качества работы.

* Модульные тесты это код.
* Тесты идут совместно с доработками (при использовании git)
* Быстрый ответ
* Высокая скорость реализации и, соответственно, низкая стоимость. На проверку небольшой функции уходит всего несколько секунд. Изолированность юнитов позволяет проверять работоспособность нескольких модулей одновременно.
* Простота автоматизации. Unit тест исследует ответ кода на ввод данных и определенные действия. Он не требует проиграть сценарий взаимодействия конечного пользователя с новой функцией, поэтому автоматизация процесса не отнимает много сил и времени.

На больших и сложных проектах стопроцентного покрытия кода тестами достичь сложно. К тому же, это нерационально. Показатель 70–90% считается хорошим. Он позволяет выявить максимальное количество ошибок. Мы собрали несколько практических советов по увеличению процента покрытия кода:

* Пишите unit тест на каждый новый код сразу же.
* Используйте готовые решения – тестовые фреймворки.
* Создавайте тесты для проверки только одной функции.
* Используйте негативные тесты для проверки поведения программы в случае ввода неправильных данных.
* Используйте мутационные фреймворки с функцией изменения констант и условий для проверки качества unit тестов.
* Проверяйте тесты на стабильность.
* Следите за скоростью выполнения теста.


## Рекомендации по модульному тестированию с использованием YAxUnit

Кроме [общих рекомендаций](common-recommendations.md)

* Структура тестовых модулей: Модуль тестового набора должен соответствовать объекту решения, который он будет тестировать. Для этого мы предлагаем [схему наименования модулей](../getting-started/structure.md#схема-наименования-модулей)
5 changes: 5 additions & 0 deletions documentation/docs/recommendations/links.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Полезные ссылки

* [Код без тестов — легаси](https://habr.com/ru/companies/dododev/articles/544110/)
О легаси, о его изменении и покрытии тестами.
* https://less.works/ru/less/technical-excellence/unit-testing
25 changes: 25 additions & 0 deletions documentation/docs/recommendations/what-to-test.md
Original file line number Diff line number Diff line change
@@ -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/)
62 changes: 62 additions & 0 deletions documentation/docs/recommendations/why-xunit.md
Original file line number Diff line number Diff line change
@@ -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/)
:::

Существует несколько причин использования модульных тестов.

<div style={{textAlign: 'center'}}>
![image](images/amongus.png)
</div>

## Сокращение времени функционального тестирования

Функциональные (сценарные) тесты требуют значительных ресурсов. Обычно они включают запуск приложения и выполнение ряда шагов, которые вам (или другому сотруднику) необходимо пройти для проверки ожидаемого поведения. Тестировщик не всегда может знать все необходимые действия, и в таких случаях ему может понадобиться помощь более опытного коллеги. Время тестирования варьируется: оно может занять всего несколько секунд при проверке небольших изменений или растянуться на несколько минут при более крупных изменениях. Этот процесс нужно повторять при каждом внесении изменений в систему.

Модульные тесты, наоборот, выполняются за миллисекунды, запускаются одним нажатием кнопки и не требуют глубокого понимания всей системы.

## Защита от регрессии

Регрессионные дефекты — это дефекты, которые появляются при внесении изменений в приложение. Обычно тестировщики проверяют не только новую функциональность, но и уже существующие функции, чтобы убедиться, что ранее реализованные возможности работают корректно.

С модульными тестами можно запускать весь набор тестов после каждой сборки или даже после изменения одной строки кода. Это **дает уверенность** в том, что новый код не нарушает существующую функциональность.

## Исполняемая документация

Не всегда очевидно, что делает конкретный метод или как он себя ведет с определенными входными данными. Вы можете задаться вопросом: как метод работает, если передать ему пустую строку? А что если передать `Неопределено`?

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

## Меньшая связность кода

Когда код слишком тесно связан, его трудно тестировать модульно. Без написания тестов связи в коде могут быть не такими очевидными.

Создание тестов для вашего кода естественным образом уменьшает его связность, поскольку иначе его было бы сложнее тестировать.

## Характеристики хорошего юнит-теста

**Быстрый**: Не редкость, что у зрелых проектов есть тысячи юнит-тестов. Юнит-тесты должны выполняться за короткое время, в миллисекундах.

**Изолированный**: Модульные тесты являются автономными, могут выполняться в изоляции и не зависят от каких-либо внешних факторов, таких как файловая система, внешние сервисы или база данных.

**Повторяемый**: Выполнение модульного теста должно быть согласовано с результатами, то есть всегда возвращает тот же результат, если вы ничего не измените между выполнением.

**Самопроверяемый**: Тест должен автоматически определять, прошел он или провалился, без вмешательства человека.

**Соизмеримый**: Написание юнит-теста не должно занимать непропорционально много времени по сравнению с тестируемым кодом. Если написание тестов занимает значительно больше времени, чем написание самого кода, следует рассмотреть более удобный для тестирования дизайн решения.

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

**Простота поддержки**: Тесты должны быть просты в поддержке. Этот пункт выполняется, если выполняется предыдущий пункт. Должно быть легко добавлять новые тестовые сценарии - поддержка тестов в актуальном состоянии не должна стать тяжелым грузом для команды разработки.

## Кодовое покрытие

Высокий процент кодового покрытия часто ассоциируется с более высоким качеством кода. Однако само измерение не может определить качество кода. Установка слишком амбициозной цели по проценту кодового покрытия может оказаться контрпродуктивной. Представьте сложный проект с тысячами условных ветвлений и целью в 95% покрытия кода. Если в настоящее время проект поддерживает 90% покрытия, то затраты времени на учёт всех крайних случаев в оставшихся 5% могут оказаться огромными, а ценность этого может быстро снизиться.

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