Определите, что вам необходимо проверить, а что можно исключить.
В предыдущей статье были рассмотрены основы тестовых случаев и то, что они должны содержать. В этой статье более подробно рассматривается создание тестовых случаев с технической точки зрения, подробно описывается, что должно быть включено в каждый тест и чего следует избегать. По сути, вы узнаете ответ на извечные вопросы «Что тестировать» или «Что не тестировать».
Общие рекомендации и шаблоны
Стоит отметить, что определенные шаблоны и точки имеют решающее значение, независимо от того, проводите ли вы модульные, интеграционные или сквозные тесты. Эти принципы могут и должны применяться к обоим типам тестирования, поэтому они являются хорошей отправной точкой.
Будьте проще
Когда дело доходит до написания тестов, одна из самых важных вещей, которую нужно помнить, — это простота. Важно учитывать возможности мозга. Основной производственный код занимает значительное место, оставляя мало места для дополнительной сложности. Это особенно актуально для тестирования.
Если свободного пространства меньше, вы можете расслабиться в своих усилиях по тестированию. Вот почему крайне важно отдавать приоритет простоте в тестировании. Фактически, лучшие практики тестирования JavaScript Йони Голдберга подчеркивают важность Золотого правила — ваш тест должен ощущаться как помощник, а не как сложная математическая формула. Другими словами, вы должны быть в состоянии понять цель вашего теста с первого взгляда.
Вы должны стремиться к простоте во всех типах тестов, независимо от их сложности. Фактически, чем сложнее тест, тем важнее его упростить. Один из способов добиться этого — использовать плоский дизайн теста, где тесты максимально просты и тестировать только то, что необходимо. Это означает, что каждый тест должен содержать только один тестовый случай, и тестовый случай должен быть сосредоточен на тестировании одной конкретной функциональности или функции.
Подумайте об этом с этой точки зрения: должно быть легко определить, что пошло не так, при чтении проваленного теста. Вот почему важно, чтобы тесты были простыми и понятными. Это позволит вам быстро выявлять и устранять проблемы, когда они возникают.
Проверьте, что того стоит
Плоский дизайн теста также поощряет фокусировку и помогает гарантировать, что ваши тесты осмысленны. Помните, вы не хотите создавать тесты только ради покрытия — у них всегда должна быть цель.
Не проверяйте детали реализации
Одной из распространенных проблем в тестировании является то, что тесты часто разрабатываются для проверки деталей реализации, таких как использование селекторов в компонентах или сквозных тестов. Детали реализации относятся к вещам, которые пользователи вашего кода обычно не будут использовать, видеть или даже знать. Это может привести к двум основным проблемам в тестах: ложным отрицательным и ложным положительным результатам.
Ложные отрицательные результаты возникают, когда тест не пройден, даже если тестируемый код корректен. Это может произойти, когда детали реализации меняются из-за рефакторинга кода приложения. С другой стороны, ложные положительные результаты возникают, когда тест пройден, даже если тестируемый код некорректен.
Одним из решений этой проблемы является рассмотрение различных типов пользователей. Конечные пользователи и разработчики могут различаться в подходах, и они могут взаимодействовать с кодом по-разному. При планировании тестов важно учитывать, что пользователи будут видеть или с чем будут взаимодействовать, и делать тесты зависимыми от этих вещей, а не от деталей реализации.
Например, выбор селекторов, которые менее подвержены изменениям, может сделать тесты более надежными: data-attributes вместо селекторов CSS. Для получения более подробной информации обратитесь к статье Кента С. Доддса на эту тему или следите за обновлениями — статья на эту тему появится позже.
Насмешка: Не теряй контроль
Mocking — это широкое понятие, используемое в модульном тестировании, а иногда и в интеграционном тестировании. Оно подразумевает создание поддельных данных или компонентов для имитации зависимостей, которые полностью контролируют приложение. Это позволяет проводить изолированное тестирование.
Использование макетов в тестах может улучшить предсказуемость, разделение проблем и производительность. И если вам нужно провести тест, требующий человеческого участия (например, проверку паспорта), вам придется скрыть его с помощью макета. По всем этим причинам макеты являются ценным инструментом, который стоит рассмотреть.
В то же время, фиктивные тесты могут повлиять на точность теста, поскольку это фиктивные тесты, а не реальный пользовательский опыт. Поэтому вам нужно быть внимательными при использовании фиктивных тестов и заглушек.
Стоит ли проводить имитационные тесты в сквозных тестах?
В целом, нет. Однако иногда насмешки могут спасти жизнь, поэтому не будем исключать их полностью.
Представьте себе такой сценарий: вы пишете тест для функции, включающей сторонний платежный сервис. Вы находитесь в среде песочницы, которую они предоставили, то есть никаких реальных транзакций не происходит. К сожалению, песочница работает со сбоями, из-за чего ваши тесты не проходят. Исправление должно быть выполнено платежным сервисом. Все, что вы можете сделать, это подождать, пока проблема будет решена поставщиком.
В этом случае может быть более полезным уменьшить зависимость от служб, которые вы не можете контролировать. По-прежнему рекомендуется осторожно использовать заглушки в интеграционных или сквозных тестах, поскольку это снижает уровень достоверности ваших тестов.
Особенности теста: что можно и чего нельзя делать
Итак, в целом, что содержит тест? И есть ли различия между типами тестирования? Давайте подробнее рассмотрим некоторые конкретные аспекты, соответствующие основным типам тестирования.
Что входит в хороший модульный тест?
Идеальный и эффективный модульный тест должен:
- Сосредоточьтесь на конкретных аспектах.
- Действуйте независимо.
- Охватывайте сценарии малого масштаба.
- Используйте описательные имена.
- Если применимо, следуйте шаблону AAA.
- Гарантия комплексного тестирования.
Делай ✅ | Не надо ❌ |
---|---|
Сохраняйте тесты как можно более короткими. Тестируйте одну вещь на каждый тестовый случай. | Пишите тесты для больших модулей. |
Всегда держите тесты изолированными и имитируйте то, что вам нужно, но находится за пределами вашего подразделения. | Включите другие компоненты или услуги. |
Сохраняйте независимость тестов. | Опирайтесь на предыдущие тесты или делитесь данными тестов. |
Охватывайте различные сценарии и пути . | Ограничьтесь счастливым путем или максимум отрицательными тестами. |
Используйте описательные названия тестов, чтобы вы сразу могли понять, о чем ваш тест. | Тест только по имени функции, в результате чего он недостаточно описателен: testBuildFoo() или testGetId() . |
Стремитесь к хорошему покрытию кода или более широкому диапазону тестовых случаев, особенно на этом этапе. | Тестирование от каждого класса до уровня базы данных (ввода-вывода). |
Что входит в хороший интеграционный тест?
Идеальный интеграционный тест также разделяет некоторые критерии с модульными тестами. Однако есть несколько дополнительных моментов, которые вам нужно учесть. Отличный интеграционный тест должен:
- Моделировать взаимодействие между компонентами.
- Охватывайте реальные сценарии и используйте макеты или заглушки.
- Подумайте о производительности.
Делай ✅ | Не надо ❌ |
---|---|
Проверьте точки интеграции: убедитесь, что все блоки корректно работают вместе при интеграции друг с другом. | Тестируйте каждый модуль по отдельности — именно для этого и предназначены модульные тесты. |
Тестируйте реальные сценарии: используйте тестовые данные, полученные из реальных данных. | Используйте повторяющиеся автоматически сгенерированные тестовые данные или другие данные, которые не отражают реальные варианты использования. |
Используйте заглушки и макеты для внешних зависимостей, чтобы сохранить контроль над всем тестом. | Создавать зависимости от сторонних служб, например, сетевые запросы к внешним службам. |
Используйте процедуру очистки до и после каждого теста. | Забудьте о необходимости использовать меры очистки внутри своих тестов, в противном случае это может привести к сбоям в тестах или ложным срабатываниям из-за отсутствия надлежащей изоляции тестов. |
Что входит в хороший сквозной тест?
Комплексное сквозное тестирование должно:
- Дублируйте взаимодействия с пользователем.
- Охватывайте жизненно важные сценарии.
- Охватывает несколько слоев.
- Управление асинхронными операциями.
- Проверьте результаты.
- Учет производительности.
Делай ✅ | Не надо ❌ |
---|---|
Используйте API-управляемые сочетания клавиш. Узнать больше . | Используйте взаимодействия с пользовательским интерфейсом на каждом этапе, включая хук beforeEach . |
Используйте процедуру очистки перед каждым тестом. Уделяйте больше внимания изоляции теста, чем в модульных и интеграционных тестах, поскольку здесь выше риск побочных эффектов. | Забывать убирать после каждого теста. Если не убирать оставшееся состояние, данные или побочные эффекты, они повлияют на другие тесты, выполняемые позже. |
Рассматривайте сквозные тесты как системные тесты. Это означает, что вам нужно тестировать весь стек приложений. | Тестируйте каждый модуль по отдельности — именно для этого и предназначены модульные тесты. |
Используйте минимальное или отсутствующее мокирование внутри теста. Тщательно обдумайте, хотите ли вы мокировать внешние зависимости. | В значительной степени полагайтесь на имитации. |
Учитывайте производительность и рабочую нагрузку, например, не тестируйте слишком много больших сценариев в одном тесте. | Охватывайте большие рабочие процессы без использования сочетаний клавиш. |
Определите, что вам необходимо проверить, а что можно исключить.
В предыдущей статье были рассмотрены основы тестовых случаев и то, что они должны содержать. В этой статье более подробно рассматривается создание тестовых случаев с технической точки зрения, подробно описывается, что должно быть включено в каждый тест и чего следует избегать. По сути, вы узнаете ответ на извечные вопросы «Что тестировать» или «Что не тестировать».
Общие рекомендации и шаблоны
Стоит отметить, что определенные шаблоны и точки имеют решающее значение, независимо от того, проводите ли вы модульные, интеграционные или сквозные тесты. Эти принципы могут и должны применяться к обоим типам тестирования, поэтому они являются хорошей отправной точкой.
Будьте проще
Когда дело доходит до написания тестов, одна из самых важных вещей, которую нужно помнить, — это простота. Важно учитывать возможности мозга. Основной производственный код занимает значительное место, оставляя мало места для дополнительной сложности. Это особенно актуально для тестирования.
Если свободного пространства меньше, вы можете расслабиться в своих усилиях по тестированию. Вот почему крайне важно отдавать приоритет простоте в тестировании. Фактически, лучшие практики тестирования JavaScript Йони Голдберга подчеркивают важность Золотого правила — ваш тест должен ощущаться как помощник, а не как сложная математическая формула. Другими словами, вы должны быть в состоянии понять цель вашего теста с первого взгляда.
Вы должны стремиться к простоте во всех типах тестов, независимо от их сложности. Фактически, чем сложнее тест, тем важнее его упростить. Один из способов добиться этого — использовать плоский дизайн теста, где тесты максимально просты и тестировать только то, что необходимо. Это означает, что каждый тест должен содержать только один тестовый случай, и тестовый случай должен быть сосредоточен на тестировании одной конкретной функциональности или функции.
Подумайте об этом с этой точки зрения: должно быть легко определить, что пошло не так, при чтении проваленного теста. Вот почему важно, чтобы тесты были простыми и понятными. Это позволит вам быстро выявлять и устранять проблемы, когда они возникают.
Проверьте, что того стоит
Плоский дизайн теста также поощряет фокусировку и помогает гарантировать, что ваши тесты осмысленны. Помните, вы не хотите создавать тесты только ради покрытия — у них всегда должна быть цель.
Не проверяйте детали реализации
Одной из распространенных проблем в тестировании является то, что тесты часто разрабатываются для проверки деталей реализации, таких как использование селекторов в компонентах или сквозных тестов. Детали реализации относятся к вещам, которые пользователи вашего кода обычно не будут использовать, видеть или даже знать. Это может привести к двум основным проблемам в тестах: ложным отрицательным и ложным положительным результатам.
Ложные отрицательные результаты возникают, когда тест не пройден, даже если тестируемый код корректен. Это может произойти, когда детали реализации меняются из-за рефакторинга кода приложения. С другой стороны, ложные положительные результаты возникают, когда тест пройден, даже если тестируемый код некорректен.
Одним из решений этой проблемы является рассмотрение различных типов пользователей. Конечные пользователи и разработчики могут различаться в подходах, и они могут взаимодействовать с кодом по-разному. При планировании тестов важно учитывать, что пользователи будут видеть или с чем будут взаимодействовать, и делать тесты зависимыми от этих вещей, а не от деталей реализации.
Например, выбор селекторов, которые менее подвержены изменениям, может сделать тесты более надежными: data-attributes вместо селекторов CSS. Для получения более подробной информации обратитесь к статье Кента С. Доддса на эту тему или следите за обновлениями — статья на эту тему появится позже.
Насмешка: Не теряй контроль
Mocking — это широкое понятие, используемое в модульном тестировании, а иногда и в интеграционном тестировании. Оно подразумевает создание поддельных данных или компонентов для имитации зависимостей, которые полностью контролируют приложение. Это позволяет проводить изолированное тестирование.
Использование макетов в тестах может улучшить предсказуемость, разделение проблем и производительность. И если вам нужно провести тест, требующий человеческого участия (например, проверку паспорта), вам придется скрыть его с помощью макета. По всем этим причинам макеты являются ценным инструментом, который стоит рассмотреть.
В то же время, фиктивные тесты могут повлиять на точность теста, поскольку это фиктивные тесты, а не реальный пользовательский опыт. Поэтому вам нужно быть внимательными при использовании фиктивных тестов и заглушек.
Стоит ли проводить имитационные тесты в сквозных тестах?
В целом, нет. Однако иногда насмешки могут спасти жизнь, поэтому не будем исключать их полностью.
Представьте себе такой сценарий: вы пишете тест для функции, включающей сторонний платежный сервис. Вы находитесь в среде песочницы, которую они предоставили, то есть никаких реальных транзакций не происходит. К сожалению, песочница работает со сбоями, из-за чего ваши тесты не проходят. Исправление должно быть выполнено платежным сервисом. Все, что вы можете сделать, это подождать, пока проблема будет решена поставщиком.
В этом случае может быть более полезным уменьшить зависимость от служб, которые вы не можете контролировать. По-прежнему рекомендуется осторожно использовать заглушки в интеграционных или сквозных тестах, поскольку это снижает уровень достоверности ваших тестов.
Особенности теста: что можно и чего нельзя делать
Итак, в целом, что содержит тест? И есть ли различия между типами тестирования? Давайте подробнее рассмотрим некоторые конкретные аспекты, соответствующие основным типам тестирования.
Что входит в хороший модульный тест?
Идеальный и эффективный модульный тест должен:
- Сосредоточьтесь на конкретных аспектах.
- Действуйте независимо.
- Охватывайте сценарии малого масштаба.
- Используйте описательные имена.
- Если применимо, следуйте шаблону AAA.
- Гарантия комплексного тестирования.
Делай ✅ | Не надо ❌ |
---|---|
Сохраняйте тесты как можно более короткими. Тестируйте одну вещь на каждый тестовый случай. | Пишите тесты для больших модулей. |
Всегда держите тесты изолированными и имитируйте то, что вам нужно, но находится за пределами вашего подразделения. | Включите другие компоненты или услуги. |
Сохраняйте независимость тестов. | Опирайтесь на предыдущие тесты или делитесь данными тестов. |
Охватывайте различные сценарии и пути . | Ограничьтесь счастливым путем или максимум отрицательными тестами. |
Используйте описательные названия тестов, чтобы вы сразу могли понять, о чем ваш тест. | Тест только по имени функции, в результате чего он недостаточно описателен: testBuildFoo() или testGetId() . |
Стремитесь к хорошему покрытию кода или более широкому диапазону тестовых случаев, особенно на этом этапе. | Тестирование от каждого класса до уровня базы данных (ввода-вывода). |
Что входит в хороший интеграционный тест?
Идеальный интеграционный тест также разделяет некоторые критерии с модульными тестами. Однако есть несколько дополнительных моментов, которые вам нужно учесть. Отличный интеграционный тест должен:
- Моделировать взаимодействие между компонентами.
- Охватывайте реальные сценарии и используйте макеты или заглушки.
- Подумайте о производительности.
Делай ✅ | Не надо ❌ |
---|---|
Проверьте точки интеграции: убедитесь, что все блоки корректно работают вместе при интеграции друг с другом. | Тестируйте каждый модуль по отдельности — именно для этого и предназначены модульные тесты. |
Тестируйте реальные сценарии: используйте тестовые данные, полученные из реальных данных. | Используйте повторяющиеся автоматически сгенерированные тестовые данные или другие данные, которые не отражают реальные варианты использования. |
Используйте заглушки и макеты для внешних зависимостей, чтобы сохранить контроль над всем тестом. | Создавать зависимости от сторонних служб, например, сетевые запросы к внешним службам. |
Используйте процедуру очистки до и после каждого теста. | Забудьте о необходимости использовать меры очистки внутри своих тестов, в противном случае это может привести к сбоям в тестах или ложным срабатываниям из-за отсутствия надлежащей изоляции тестов. |
Что входит в хороший сквозной тест?
Комплексное сквозное тестирование должно:
- Дублируйте взаимодействия с пользователем.
- Охватывайте жизненно важные сценарии.
- Охватывает несколько слоев.
- Управление асинхронными операциями.
- Проверьте результаты.
- Учет производительности.
Делай ✅ | Не надо ❌ |
---|---|
Используйте API-управляемые сочетания клавиш. Узнать больше . | Используйте взаимодействия с пользовательским интерфейсом на каждом этапе, включая хук beforeEach . |
Используйте процедуру очистки перед каждым тестом. Уделяйте больше внимания изоляции теста, чем в модульных и интеграционных тестах, поскольку здесь выше риск побочных эффектов. | Забывать убирать после каждого теста. Если не убирать оставшееся состояние, данные или побочные эффекты, они повлияют на другие тесты, выполняемые позже. |
Рассматривайте сквозные тесты как системные тесты. Это означает, что вам нужно тестировать весь стек приложений. | Тестируйте каждый модуль по отдельности — именно для этого и предназначены модульные тесты. |
Используйте минимальное или отсутствующее мокирование внутри теста. Тщательно обдумайте, хотите ли вы мокировать внешние зависимости. | В значительной степени полагайтесь на имитации. |
Учитывайте производительность и рабочую нагрузку, например, не тестируйте слишком много больших сценариев в одном тесте. | Охватывайте большие рабочие процессы без использования сочетаний клавиш. |