Виды автоматизированного тестирования

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

На предыдущих страницах были примеры как модульных , так и компонентных тестов (в нашем примере речь идет о компоненте React). Мы можем разместить оба этих теста в самом низу нашей пирамиды тестирования (или другой формы!), поскольку они имеют низкую сложность и быстро выполняются, но могут оказаться не столь полезными, как более сложные интеграционные тесты .

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

Распространенные виды тестов

Модульные тесты

Модульные тесты имеют наименьший объем. Они, как правило, используются для тестирования небольших частей кода или чисто кода без сохранения состояния почти математическим способом: если я предоставляю вашему коду входные данные X, Y и Z, его выходные данные должны быть A, B и C.

Код с модульными тестами обычно не имеет внешних зависимостей, таких как получение из сети или неявное использование каких-либо других функций или библиотек. Это узел дерева вашего кода, который вы можете «вырезать» и протестировать самостоятельно.

Хотя модульные тесты обычно пишутся и выполняются быстро, всегда возможно, что тестирование небольших модулей кода не даст полезной информации. Часто отсутствие взаимодействия модуля кода с другим кодом означает, что вам лучше провести тестирование на более высоком уровне, чтобы снизить риск.

Тесты компонентов

Для веб-разработчиков имя «компонент» перегружено и часто означает компонент, видимый пользователю, например компонент React или веб-компонент. Его более общее определение — это тестируемый фрагмент работы, например класс с внешними зависимостями. Для эффективного тестирования зависимости этого компонента должны быть макетированы или пропущены.

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

Интеграционные тесты

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

Это может даже включать «реальные» зависимости, такие как внешняя база данных в тестовом режиме, а не чистый макет. Например, вместо того, чтобы говорить, что query() всегда будет возвращать одни и те же две записи, ваш интеграционный тест может подтвердить, что в тестовой базе данных что-то есть. Сами данные менее важны, но сейчас вы проверяете возможность подключения к базе данных и успешного выполнения запросов.

Можно написать относительно простые интеграционные тесты с широким спектром последствий, которые можно проверить с помощью утверждений, поскольку одно действие, связанное с различными компонентами, может вызвать серию измеримых эффектов. Благодаря этому интеграционные тесты могут эффективно продемонстрировать, что ваша сложная система будет работать так, как задумано. Однако их может быть сложно писать и поддерживать, и они могут привести к ненужной сложности. Например, при написании FakeUserService для интеграционного теста добавляется требование, чтобы и он, и RealUserService реализовывали UserService .

Дымовые испытания

Это тесты, которые должны завершиться очень быстро и определить, находится ли ваша кодовая база в разумном состоянии. На практике это в основном означает выполнение простых тестов кода, которые оказывают широкое влияние на ваш опыт.

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

Дымовые тесты могут быть хорошим кандидатом для запуска test сценария package.json в большой базе кода. Ручное тестирование также может служить своего рода дымовым тестом.

Регрессионные тесты

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

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

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

Визуальные тесты

Визуальное тестирование включает в себя создание снимков экрана или видео состояния веб-сайта, чтобы сравнить заведомо хорошее состояние (например, предыдущий снимок экрана) с текущим запуском теста. По своей природе он требует, чтобы был запущен настоящий браузер, чтобы он мог отображать HTML, CSS и другие части веб-сайта.

Вместо визуального тестирования сквозных тестов , которые запускают всю вашу кодовую базу, может быть полезно создать «обвязки» HTML, которые отображают только определенные компоненты, особенно на экранах разных размеров, для запуска адаптивных пользовательских интерфейсов. Это сложнее, чем простое использование JSDOM или подобных фреймворков.

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

Сквозные тесты

Сквозные тесты часто находятся на вершине пирамиды тестирования. Они описывают комплексное взаимодействие с вашим веб-приложением или веб-сайтом, возможно, сосредоточенное на определенной функции, и обычно запускаются внутри браузера, управляемого таким агентом, как WebdriverIO, Selenium или Puppeteer, который может запускать вашу кодовую базу более или менее так, как она есть. будут развернуты в производстве (хотя они часто обслуживаются на локальном хосте).

В зависимости от вашего сайта это может включать вход в систему в качестве тестового пользователя, выполнение основных действий и подтверждение того, что ваш сайт или система находится в правильном состоянии. В следующих разделах мы рассмотрим больше примеров такого типа тестирования, поскольку они могут быть очень мощными, но иногда их сложно поддерживать.

Некоторые тактики их упрощения могут включать сокращение их объема или макетирование конкретных компонентов, где это необходимо. Например, если пользователям необходимо войти на ваш сайт, но вход в систему не является функцией, которую вы тестируете, вы можете установить флаг для тестовых сред, который позволит контроллеру тестирования действовать как пользователь без входа в систему или создание связанных файлов cookie.

Хотя сквозные тесты могут быть очень эффективным способом одновременного тестирования огромных участков вашей кодовой базы, такие крупномасштабные тесты рискуют оказаться нестабильными или ненадежными из-за их зависимости от внешних систем. Они также часто могут оставлять в вашей базе данных много тестовых данных, если, например, каждый тест создает или изменяет запись. Накопление оставшихся данных, подобных этому, может затруднить определение причины неудачного теста.

API-тестирование

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

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

Другие типы

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

  • Ручное тестирование.
  • Приемочное тестирование, разновидность ручного тестирования, популяризированного Agile, подтверждает, что продукт «соответствует потребностям пользователя».
  • Хаос-тестирование подразумевает ввод случайных данных, чтобы увидеть, что произойдет, чтобы убедиться, что сайт не выйдет из строя, если будут введены неверные данные.
  • Тестирование отказов намеренно имитирует сбои в сложных системах, например сбои сети, чтобы убедиться, что тестируемый код реагирует контролируемым образом.
  • Тестирование сборки подтверждает возможность создания артефактов сборки кодовой базы путем проверки их существования и их содержимого. Этот тип теста может быть полезен для проверки выходных данных сложной CMS.

Покрытие кода

Можно измерить, какой процент вашего кода проверяется автоматическими тестами, и сообщить об этом в виде статистики с течением времени. Мы не рекомендуем стремиться к 100-процентному покрытию кода, поскольку это может привести к ненужным накладным расходам, а также к упрощенным или плохо спроектированным тестам, которые не охватывают подробно основные варианты использования.

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

Ресурсы

Проверьте свое понимание

Какие из следующих типов тестов являются известными?

Визуальные тесты
Хаос-тестирование
Огневые испытания
Возможно, если вы создаете программное обеспечение для пожарной охраны.
Дифференциальные тесты
Нагрузочное тестирование
Мы не упоминали об этом здесь, но стресс-тестирование или нагрузочное тестирование — это тип тестирования производственных систем, позволяющий убедиться, что они могут принимать большой объем трафика. Это больше связано с проектированием большой системы, чем с тестированием более типичных баз кода.