[{"data":1,"prerenderedAt":58},["ShallowReactive",2],{"wiki-test-automation-automation-levels-and-test-pyramid-ru":3},{"meta":4,"html":8,"headings":9,"words":57},{"title":5,"description":6,"published":7,"updated":7,"sourceUpdated":7},"Уровни автоматизации и пирамида тестов","Модульные, интеграционные и сквозные тесты: стоимость и скорость каждого уровня, пирамида тестов и анти-паттерн «рожок мороженого».","2026-11-03","\u003Cp>\u003Cstrong>Уровни автоматизации\u003C/strong> (test automation levels) - группы автотестов, которые различаются тем, насколько большую часть системы задействует один тест: \u003Cstrong>модульный тест\u003C/strong> (unit test) проверяет один компонент в изоляции, \u003Cstrong>интеграционный тест\u003C/strong> (integration test) проверяет взаимодействие компонентов или систем, \u003Cstrong>сквозной тест\u003C/strong> (end-to-end test) проверяет всю развёрнутую систему через её внешние интерфейсы. \u003Cstrong>Пирамида тестов\u003C/strong> (test pyramid) - модель распределения автотестов по этим уровням: много маленьких быстрых тестов внизу и мало больших медленных тестов наверху.\u003C/p>\n\u003Cp>Пирамиду предложил Майк Кон (Mike Cohn). По словам Мартина Фаулера, Кон нарисовал её в разговорах с Лизой Криспин в 2003-2004 годах. Опубликовал он её под названием «пирамида автоматизации тестирования» (test automation pyramid) в книге Succeeding with Agile (Addison-Wesley, 2009). Дальше модель распространили заметка Фаулера TestPyramid в его bliki (2012) и статья Хэма Фокке (Ham Vocke) «The Practical Test Pyramid» (2018). Силлабус ISTQB Foundation Level (версия 4.0.1) описывает пирамиду тестов в разделе 5.1.6, а уровни тестирования - в разделе 2.2.1.\u003C/p>\n\u003Ch2 id=\"какую-задачу-решает-пирамида-тестов\" class=\"wiki-heading\">Какую задачу решает пирамида тестов\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"какую-задачу-решает-пирамида-тестов\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Одно и то же поведение можно проверить тестами разного размера. Правило, по которому просроченная платёжная карта отклоняется, проверяется вызовом одной функции, запросом к платёжному сервису или оплатой просроченной картой в браузере. Все три теста могут найти один и тот же \u003Cspan class=\"wiki-term\" tabindex=\"0\" data-wiki-term=\"defect\">дефект\u003C/span>. Они различаются временем выполнения, стоимостью поддержки и тем, насколько точно падение указывает на причину.\u003C/p>\n\u003Cp>У \u003Cspan class=\"wiki-term\" tabindex=\"0\" data-wiki-term=\"test-suite\">набора тестов\u003C/span>, собранного в основном из тестов через пользовательский интерфейс, известные проблемы. Фаулер перечисляет их: такие тесты хрупкие, дорогие в написании и медленные; одно изменение интерфейса может сломать многие из них сразу; они чаще дают недетерминированный результат.\u003C/p>\n\u003Cp>Пирамида тестов отвечает на два вопроса: какие тесты писать и в какой пропорции. Фокке сводит её к двум практическим правилам: писать тесты разной детализации и чем выше уровень, тем меньше на нём тестов.\u003C/p>\n\u003Ch2 id=\"история\" class=\"wiki-heading\">История\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"история\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>В таблице - основные вехи модели.\u003C/p>\n\u003Cdiv class=\"wiki-table wiki-table--cols-2\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Дата\u003C/th>\n\u003Cth>Событие\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>2003-2004\u003C/td>\n\u003Ctd>Майк Кон рисует пирамиду в разговорах с Лизой Криспин (по словам Фаулера)\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>2006\u003C/td>\n\u003Ctd>Джейсон Хаггинс (Jason Huggins) независимо приходит к той же идее (по словам Фаулера)\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>20 октября 2009\u003C/td>\n\u003Ctd>Выходит книга Майка Кона Succeeding with Agile с пирамидой из модульных, сервисных и UI-тестов\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Январь 2012\u003C/td>\n\u003Ctd>Алистер Скотт описывает анти-паттерн «рожок мороженого» в тестировании\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>1 мая 2012\u003C/td>\n\u003Ctd>Мартин Фаулер публикует заметку TestPyramid\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>6 февраля 2018\u003C/td>\n\u003Ctd>Кент Доддс (Kent C. Dodds) показывает трофей тестирования\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>26 февраля 2018\u003C/td>\n\u003Ctd>Хэм Фокке публикует «The Practical Test Pyramid» на martinfowler.com\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>9 мая 2023\u003C/td>\n\u003Ctd>ISTQB выпускает CTFL v4.0\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>2024\u003C/td>\n\u003Ctd>CTFL v4.0.1, пирамида тестов в разделе 5.1.6\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Ch2 id=\"уровни-тестирования-и-уровни-автоматизации\" class=\"wiki-heading\">Уровни тестирования и уровни автоматизации\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"уровни-тестирования-и-уровни-автоматизации\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Силлабус ISTQB определяет пять уровней тестирования. Уровни тестирования - это группы активностей тестирования, которые организуются и управляются вместе. В таблице - пять уровней и уровень автоматизации, который обычно им соответствует.\u003C/p>\n\u003Cdiv class=\"wiki-table wiki-table--cols-3\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Уровень тестирования ISTQB\u003C/th>\n\u003Cth>Фокус\u003C/th>\n\u003Cth>Обычный уровень автоматизации\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Компонентное тестирование (модульное)\u003C/td>\n\u003Ctd>Компоненты в изоляции\u003C/td>\n\u003Ctd>Модульные тесты\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Тестирование интеграции компонентов\u003C/td>\n\u003Ctd>Интерфейсы и взаимодействие компонентов\u003C/td>\n\u003Ctd>Интеграционные тесты\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Системное тестирование\u003C/td>\n\u003Ctd>Поведение и возможности всей системы\u003C/td>\n\u003Ctd>Сквозные тесты\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Тестирование системной интеграции\u003C/td>\n\u003Ctd>Интерфейсы с другими системами и внешними сервисами\u003C/td>\n\u003Ctd>Интеграционные или сквозные тесты\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Приёмочное тестирование\u003C/td>\n\u003Ctd>Валидация и готовность к развёртыванию\u003C/td>\n\u003Ctd>Любой уровень\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Cp>Уровень тестирования описывает активность процесса тестирования: кто её выполняет, по какому базису, с какими целями. Уровень автоматизации описывает техническое свойство одного автотеста: что он запускает и что заменяет тестовыми двойниками (test doubles). Компонентное тестирование прямо соответствует модульным тестам. Приёмочный тест можно автоматизировать на любом уровне: Фокке отмечает, что проверка функции с точки зрения пользователя не обязана идти через пользовательский интерфейс.\u003C/p>\n\u003Ch3 id=\"модульные-тесты\" class=\"wiki-heading\">Модульные тесты\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"модульные-тесты\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h3>\n\u003Cp>Модульный тест вызывает функцию, класс или модуль напрямую, в процессе тестового фреймворка. Медленные или неуправляемые зависимости - база данных, сеть, часы - заменяются тестовыми двойниками. Силлабус отмечает, что для компонентного тестирования часто нужны тестовые обвязки (test harnesses) или фреймворки модульного тестирования и что его обычно выполняют разработчики в своём окружении разработки.\u003C/p>\n\u003Cp>Модульный тест правила «просроченная карта отклоняется» передаёт функции проверки карту с прошедшим сроком действия и проверяет возвращённую ошибку. Ему не нужны ни сервер, ни база данных, ни браузер. Его падение указывает на одну функцию.\u003C/p>\n\u003Ch3 id=\"интеграционные-тесты\" class=\"wiki-heading\">Интеграционные тесты\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"интеграционные-тесты\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h3>\n\u003Cp>У термина «интеграционный тест» есть как минимум два значения, как отмечает Фаулер. \u003Cstrong>Узкий интеграционный тест\u003C/strong> (narrow integration test) задействует только ту часть сервиса, которая общается с другим компонентом: базой данных, брокером сообщений, другим сервисом. По охвату он близок к модульному тесту. \u003Cstrong>Широкий интеграционный тест\u003C/strong> (broad integration test) требует работающих версий всех сервисов и \u003Cspan class=\"wiki-term\" tabindex=\"0\" data-wiki-term=\"test-environment\">тестового окружения\u003C/span> с доступом к сети.\u003C/p>\n\u003Cp>Уровни ISTQB делятся похожим образом. Тестирование интеграции компонентов сильно зависит от стратегии интеграции: снизу вверх, сверху вниз или «большим взрывом» (big-bang). Тестированию системной интеграции нужно тестовое окружение, по возможности похожее на эксплуатационное.\u003C/p>\n\u003Cp>Интеграционный тест платёжного правила отправляет запрос с просроченной картой платёжному сервису, который работает с настоящей базой данных, и проверяет HTTP-статус и код ошибки в ответе. Падение указывает на сервис, схему его базы данных или отображение между ними.\u003C/p>\n\u003Ch3 id=\"сквозные-тесты\" class=\"wiki-heading\">Сквозные тесты\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"сквозные-тесты\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h3>\n\u003Cp>Сквозной тест работает с развёрнутой системой и идёт через внешний интерфейс: пользовательский интерфейс или публичный API. В примере с оплатой тест открывает магазин в браузере, входит в систему, кладёт товары в корзину, платит просроченной картой и проверяет сообщение на экране.\u003C/p>\n\u003Cp>Такой тест ближе всех к тому, как продуктом пользуются. Он же зависит от наибольшего числа вещей сразу: сборки, конфигурации, тестового окружения, тестовых данных, сети и браузера. Как сквозные тесты находят элементы на странице, описано в статье \u003Ca href=\"/ru/wiki/test-automation/ui-test-locators\" class=\"wiki-link wiki-link--article\">Локаторы в UI-автотестах\u003C/a>.\u003C/p>\n\u003Ch2 id=\"стоимость-и-скорость-уровней\" class=\"wiki-heading\">Стоимость и скорость уровней\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"стоимость-и-скорость-уровней\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Силлабус формулирует общее правило: чем выше слой, тем ниже детализация, изоляция и время выполнения теста. Тесты нижнего слоя маленькие, изолированные и быстрые. Тесты верхнего слоя, как правило, медленнее. Таблица сравнивает уровни по факторам, из которых складывается стоимость теста.\u003C/p>\n\u003Cdiv class=\"wiki-table wiki-table--cols-4\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Фактор\u003C/th>\n\u003Cth>Модульный тест\u003C/th>\n\u003Cth>Интеграционный тест\u003C/th>\n\u003Cth>Сквозной тест\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Что работает\u003C/td>\n\u003Ctd>Код в процессе теста\u003C/td>\n\u003Ctd>Сервис с настоящими зависимостями\u003C/td>\n\u003Ctd>Вся развёрнутая система\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Самая медленная операция\u003C/td>\n\u003Ctd>Вызовы функций в памяти\u003C/td>\n\u003Ctd>Запросы к базе данных, сетевые вызовы\u003C/td>\n\u003Ctd>Загрузка страниц, отрисовка, все сервисы\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Нужное окружение\u003C/td>\n\u003Ctd>Никакого\u003C/td>\n\u003Ctd>База данных, брокер, контейнеры сервисов\u003C/td>\n\u003Ctd>Полное тестовое окружение\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Локализация падения\u003C/td>\n\u003Ctd>Одна функция или класс\u003C/td>\n\u003Ctd>Один сервис или интерфейс\u003C/td>\n\u003Ctd>Где угодно в системе\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Причины падения без дефекта\u003C/td>\n\u003Ctd>Немного\u003C/td>\n\u003Ctd>Окружение, тестовые данные\u003C/td>\n\u003Ctd>Окружение, данные, тайминги, изменения интерфейса\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Чего не может найти\u003C/td>\n\u003Ctd>Дефекты взаимодействия\u003C/td>\n\u003Ctd>Дефекты полного пользовательского сценария\u003C/td>\n\u003Ctd>Немногое; он ближе всех к реальному использованию\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Cp>Точные числа зависят от продукта и инфраструктуры; универсальных значений нет. Разница вытекает из самих операций. Вызов функции в памяти занимает намного меньше времени, чем запрос к базе данных по сети, а запрос - меньше, чем загрузка страницы, которая порождает много запросов.\u003C/p>\n\u003Cp>Некоторые инструменты сборки фиксируют эту разницу явно. В Bazel у тестовой цели есть атрибут \u003Ccode>size\u003C/code> со значениями \u003Ccode>small\u003C/code>, \u003Ccode>medium\u003C/code>, \u003Ccode>large\u003C/code> и \u003Ccode>enormous\u003C/code>. Размер задаёт тайм-аут по умолчанию: 1 минута, 5 минут, 15 минут и 60 минут соответственно, а также ресурсы, которые резервируются для локального запуска.\u003C/p>\n\u003Cp>Время выполнения - только часть стоимости. Падение сквозного теста требует разбора: виноваты могут быть продукт, окружение, данные или сам тест. Тесты, которые падают без дефекта в продукте, описаны в статье \u003Ca href=\"/ru/wiki/test-automation/flaky-tests\" class=\"wiki-link wiki-link--article\">Нестабильные (flaky) тесты\u003C/a>.\u003C/p>\n\u003Ch2 id=\"пирамида-тестов\" class=\"wiki-heading\">Пирамида тестов\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"пирамида-тестов\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Силлабус описывает пирамиду как модель, которая показывает, что тесты могут иметь разную детализацию. Слои представляют группы тестов. Каждый тест нижнего слоя проверяет небольшой фрагмент функциональности, поэтому для разумного покрытия их нужно много. Каждый тест верхнего слоя проверяет большой фрагмент функциональности, поэтому их достаточно немного.\u003C/p>\n\u003Cdiv class=\"wiki-code wiki-code--plain\">\u003Cpre>\u003Ccode>            /\\\n           /  \\        End-to-end tests: few, slow, broad\n          /----\\\n         /      \\      Integration tests\n        /--------\\\n       /          \\    Unit tests: many, fast, isolated\n      +------------+\u003C/code>\u003C/pre>\u003C/div>\n\u003Cp>Силлабус отмечает, что число и названия слоёв бывают разными. В исходной пирамиде Кона три слоя: модульные тесты, сервисные тесты и UI-тесты. Другой распространённый вариант - модульные (компонентные) тесты, интеграционные тесты (интеграции компонентов) и сквозные тесты.\u003C/p>\n\u003Cp>Средний слой - наименее очевидный. Кон определяет сервис как то, что приложение делает в ответ на входные данные, и сервисные тесты проверяют эти сервисы без пользовательского интерфейса. Фаулер называет такие тесты подкожными (subcutaneous): они действуют через сервисный слой или API приложения непосредственно под пользовательским интерфейсом. Они дают многие преимущества сквозных тестов без сложности пользовательского интерфейса.\u003C/p>\n\u003Cp>Фокке предостерегает от буквального понимания названий слоёв: пирамида упрощена и может вводить в заблуждение. Точных пропорций форма не задаёт.\u003C/p>\n\u003Ch3 id=\"анти-паттерн-рожок-мороженого\" class=\"wiki-heading\">Анти-паттерн «рожок мороженого»\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"анти-паттерн-рожок-мороженого\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h3>\n\u003Cp>\u003Cstrong>Рожок мороженого\u003C/strong> (ice cream cone) - перевёрнутая пирамида тестов: большая часть проверок - ручные тесты и тесты через пользовательский интерфейс, модульных тестов мало. Алистер Скотт (Alister Scott) описал его в своём блоге WatirMelon в январе 2012 года. Он писал, что организации часто строят перевёрнутые пирамиды тестирования. В его собственной пирамиде наверху облако ручных сессионных тестов, и если её перевернуть, получается рожок мороженого.\u003C/p>\n\u003Cp>Заметка Фаулера TestPyramid описывает, как появляется такой набор. Команда автоматизирует тесты инструментами записи и воспроизведения: тестировщик записывает действия в пользовательском интерфейсе, а инструмент воспроизводит их и сравнивает результаты. Фаулер отмечает, что поначалу это работает хорошо. Затем набор растёт на верхнем уровне и ломается при изменениях интерфейса. Результат Фаулер называет рожком мороженого.\u003C/p>\n\u003Cp>Анти-паттерн описывает пропорцию, а не само наличие сквозных тестов. Набор, где поверх множества тестов нижних уровней есть несколько сквозных тестов основных пользовательских сценариев, остаётся пирамидой.\u003C/p>\n\u003Ch2 id=\"другие-формы\" class=\"wiki-heading\">Другие формы\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"другие-формы\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>\u003Cstrong>Трофей тестирования\u003C/strong> (testing trophy) Кент Доддс показал 6 февраля 2018 года и подробно описал в статье от 3 июня 2021 года. В нём четыре слоя снизу вверх: статические проверки (проверка типов и линтеры), модульные тесты, интеграционные тесты и сквозные тесты. Самый широкий слой - интеграционный. Доддс взял идею из совета Гильермо Рауха (Guillermo Rauch) от 10 декабря 2016 года: «Write tests. Not too many. Mostly integration.»\u003C/p>\n\u003Cp>Таблица сравнивает две формы.\u003C/p>\n\u003Cdiv class=\"wiki-table wiki-table--cols-3\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>\u003C/th>\n\u003Cth>Пирамида тестов\u003C/th>\n\u003Cth>Трофей тестирования\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Автор, год\u003C/td>\n\u003Ctd>Майк Кон, 2009\u003C/td>\n\u003Ctd>Кент Доддс, 2018\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Слои\u003C/td>\n\u003Ctd>Модульные, сервисные, UI (исходная)\u003C/td>\n\u003Ctd>Статические, модульные, интеграционные, сквозные\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Самый широкий слой\u003C/td>\n\u003Ctd>Модульные тесты\u003C/td>\n\u003Ctd>Интеграционные тесты\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Довод\u003C/td>\n\u003Ctd>Нижние тесты быстрее и дешевле\u003C/td>\n\u003Ctd>Отдача от вложений: уверенность за потраченное время\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Заявленная область\u003C/td>\n\u003Ctd>Общая\u003C/td>\n\u003Ctd>Одна кодовая база; Доддс применял её к монолитам\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Cp>Обе формы ставят наверх немного сквозных тестов, и обе связывают число тестов с их стоимостью. Различаются они тем, куда уходит основная часть усилий. Доддс объясняет своё согласие с советом Рауха опытом инженера пользовательских интерфейсов и пишет, что сама классификация важна меньше, чем цель.\u003C/p>\n\u003Cp>В обеих моделях значение слова «интеграционный» нужно согласовать внутри команды. Доддс определяет интеграционные тесты как тесты нескольких модулей, работающих вместе, и это ближе к узким интеграционным тестам Фаулера, чем к широким.\u003C/p>\n\u003Ch2 id=\"как-выбрать-уровень-для-проверки\" class=\"wiki-heading\">Как выбрать уровень для проверки\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"как-выбрать-уровень-для-проверки\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Обычное правило следует из пирамиды: проверка относится к самому низкому уровню, на котором она может найти свой дефект. Фокке выводит из него два следствия. Если тест верхнего уровня нашёл ошибку, а ни один тест нижнего уровня не упал, не хватает теста нижнего уровня, и его нужно написать. А тест верхнего уровня, который только повторяет проверки нижних уровней, добавляет стоимость, не добавляя уверенности.\u003C/p>\n\u003Cp>Проверке нужен более высокий уровень, когда её дефект существует только там. Связи компонентов, конфигурацию, схему базы данных и поведение настоящего браузера модульный тест проверить не может: именно эти части он заменяет тестовыми двойниками.\u003C/p>\n\u003Cp>Таблица распределяет по уровням проверки одной функции - промокода при оформлении заказа.\u003C/p>\n\u003Cdiv class=\"wiki-table wiki-table--cols-3\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Проверка\u003C/th>\n\u003Cth>Уровень\u003C/th>\n\u003Cth>Почему этот уровень\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Проверяется формат промокода\u003C/td>\n\u003Ctd>Модульный\u003C/td>\n\u003Ctd>Чистая функция от входных данных\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Скидка на границах суммы заказа\u003C/td>\n\u003Ctd>Модульный\u003C/td>\n\u003Ctd>Много входных значений, каждый тест дешёвый\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Просроченный промокод отклоняется\u003C/td>\n\u003Ctd>Модульный\u003C/td>\n\u003Ctd>Часы заменены тестовым двойником\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Заказ со скидкой сохраняется и читается\u003C/td>\n\u003Ctd>Интеграционный\u003C/td>\n\u003Ctd>Зависит от настоящей схемы базы данных\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Запрос скидки соответствует согласованному API\u003C/td>\n\u003Ctd>Контрактный тест\u003C/td>\n\u003Ctd>Два сервиса, каждый проверяется отдельно\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Пользователь вводит код и видит новую сумму\u003C/td>\n\u003Ctd>Сквозной\u003C/td>\n\u003Ctd>Весь сценарий через браузер, один тест\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Cp>Значения для второй строки выбирает проектирование тестов, описанное в статье \u003Ca href=\"/ru/wiki/test-design/equivalence-partitioning-and-boundary-values\" class=\"wiki-link wiki-link--article\">Классы эквивалентности и граничные значения\u003C/a>. Пирамида говорит только, что такие многочисленные проверки должны быть дешёвыми.\u003C/p>\n\u003Ch2 id=\"контрактные-тесты-между-сервисами\" class=\"wiki-heading\">Контрактные тесты между сервисами\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"контрактные-тесты-между-сервисами\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Взаимодействие двух сервисов можно проверить, не разворачивая их вместе. \u003Cstrong>Контрактный тест\u003C/strong> (contract test) проверяет каждую сторону интерфейса отдельно на соответствие общему описанию запросов и ответов. В \u003Cstrong>контрактах, задаваемых потребителями\u003C/strong> (consumer-driven contracts) - шаблоне, который Иэн Робинсон (Ian Robinson) описал в 2006 году, - потребители формулируют свои ожидания от провайдера, а обязательства провайдера складываются из этих ожиданий.\u003C/p>\n\u003Cp>Pact реализует этот шаблон. Тесты потребителя отправляют настоящие запросы имитации провайдера (mock provider), которую создаёт Pact. Имитация проверяет каждый запрос и возвращает ожидаемый ответ. Когда тесты потребителя проходят, Pact записывает pact-файл с описанием каждого взаимодействия. При проверке провайдера (provider verification) Pact повторяет каждый записанный запрос к настоящему провайдеру и сравнивает его ответ с минимальным ожидаемым ответом.\u003C/p>\n\u003Cdiv class=\"wiki-code wiki-code--plain\">\u003Cpre>\u003Ccode>Consumer tests                        Provider verification\n |                                     |\n +-- request --&gt; Pact mock provider    +-- recorded request --&gt; real provider\n |               |                     |                         |\n |               +-- expected response |                         +-- actual response\n |                                     |                               |\n +--&gt; pact file -----------------------+--&gt; compared with expected &lt;---+\u003C/code>\u003C/pre>\u003C/div>\n\u003Cp>Проверяются только те части провайдера, которыми пользуются потребители, поэтому неиспользуемое поведение провайдер может менять свободно. Контрактные тесты берут на себя часть работы широких интеграционных тестов без полного тестового окружения. Развёрнутую систему они не проверяют, поэтому несколько сквозных тестов остаются.\u003C/p>\n\u003Ch2 id=\"уровни-покрытие-и-непрерывная-интеграция\" class=\"wiki-heading\">Уровни, покрытие и непрерывная интеграция\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"уровни-покрытие-и-непрерывная-интеграция\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cp>Покрытие кода измеряют в основном для модульных и интеграционных тестов: их процесс можно инструментировать. \u003Cspan class=\"wiki-term\" tabindex=\"0\" data-wiki-term=\"requirements-coverage\">Покрытие требований\u003C/span> вычисляется по связям требований с тестами и характерно для системных и приёмочных тестов. Эти две меры сравниваются в статье \u003Ca href=\"/ru/wiki/test-management/requirements-traceability\" class=\"wiki-link wiki-link--article\">Трассируемость и покрытие требований\u003C/a>.\u003C/p>\n\u003Cp>Уровень теста определяет и то, где он может выполняться в конвейере \u003Cspan class=\"wiki-term\" tabindex=\"0\" data-wiki-term=\"continuous-integration\">непрерывной интеграции\u003C/span> (CI). Модульным тестам окружение не нужно, их можно запускать при каждом изменении. Интеграционным тестам нужны их зависимости, например запущенные в контейнерах на время задания. Сквозным тестам нужна развёрнутая система. Как тесты запускаются по событиям конвейера, выполняются параллельно и попадают в отчёты, описано в статье \u003Ca href=\"/ru/wiki/test-automation/automated-tests-in-ci\" class=\"wiki-link wiki-link--article\">Автотесты в CI\u003C/a>.\u003C/p>\n\u003Ch2 id=\"термины\" class=\"wiki-heading\">Термины\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"термины\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cdiv class=\"wiki-table wiki-table--cols-2\">\u003Ctable>\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Термин\u003C/th>\n\u003Cth>Значение\u003C/th>\n\u003C/tr>\n\u003C/thead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>Уровень автоматизации (test automation level)\u003C/td>\n\u003Ctd>Группа автотестов, которые задействуют часть системы сходного размера\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Модульный тест (unit test)\u003C/td>\n\u003Ctd>Автотест, который проверяет один компонент в изоляции, в процессе теста\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Интеграционный тест (integration test)\u003C/td>\n\u003Ctd>Автотест, который проверяет взаимодействие компонентов или системы с другими системами\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Сквозной тест (end-to-end test)\u003C/td>\n\u003Ctd>Автотест, который проверяет всю развёрнутую систему через пользовательский интерфейс или публичный API\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Пирамида тестов (test pyramid)\u003C/td>\n\u003Ctd>Модель: много маленьких быстрых тестов внизу и мало больших медленных тестов наверху\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Рожок мороженого (ice cream cone)\u003C/td>\n\u003Ctd>Анти-паттерн перевёрнутой пирамиды: в основном ручные и UI-тесты, мало модульных\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Трофей тестирования (testing trophy)\u003C/td>\n\u003Ctd>Модель Кента Доддса со слоями статических, модульных, интеграционных и сквозных проверок, самый широкий - интеграционный\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Контрактный тест (contract test)\u003C/td>\n\u003Ctd>Тест, который проверяет каждую сторону интерфейса отдельно на соответствие общему описанию запросов и ответов\u003C/td>\n\u003C/tr>\n\u003Ctr>\n\u003Ctd>Контракт, задаваемый потребителями (consumer-driven contract)\u003C/td>\n\u003Ctd>Контракт провайдера, сформированный из ожиданий его потребителей\u003C/td>\n\u003C/tr>\n\u003C/tbody>\n\u003C/table>\u003C/div>\n\u003Ch2 id=\"источники\" class=\"wiki-heading\">Источники\u003Cbutton type=\"button\" class=\"wiki-heading__anchor\" data-wiki-anchor=\"источники\" aria-label=\"Скопировать ссылку на раздел\" data-copied-label=\"Ссылка на раздел скопирована\">\u003Csvg class=\"wiki-heading__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M117.18,188.74a12,12,0,0,1,0,17l-5.12,5.12A58.26,58.26,0,0,1,70.6,228h0A58.62,58.62,0,0,1,29.14,127.92L63.89,93.17a58.64,58.64,0,0,1,98.56,28.11,12,12,0,1,1-23.37,5.44,34.65,34.65,0,0,0-58.22-16.58L46.11,144.89A34.62,34.62,0,0,0,70.57,204h0a34.41,34.41,0,0,0,24.49-10.14l5.11-5.12A12,12,0,0,1,117.18,188.74ZM226.83,45.17a58.65,58.65,0,0,0-82.93,0l-5.11,5.11a12,12,0,0,0,17,17l5.12-5.12a34.63,34.63,0,1,1,49,49L175.1,145.86A34.39,34.39,0,0,1,150.61,156h0a34.63,34.63,0,0,1-33.69-26.72,12,12,0,0,0-23.38,5.44A58.64,58.64,0,0,0,150.56,180h.05a58.28,58.28,0,0,0,41.47-17.17l34.75-34.75a58.62,58.62,0,0,0,0-82.91Z\"/>\u003C/svg>\u003Csvg class=\"wiki-heading__icon wiki-heading__icon--done\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M232.49,80.49l-128,128a12,12,0,0,1-17,0l-56-56a12,12,0,1,1,17-17L96,183,215.51,63.51a12,12,0,0,1,17,17Z\"/>\u003C/svg>\u003C/button>\u003C/h2>\n\u003Cul>\n\u003Cli>\u003Ca href=\"https://www.istqb.org/wp-content/uploads/2024/11/ISTQB_CTFL_Syllabus_v4.0.1.pdf\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">ISTQB Certified Tester Foundation Level Syllabus v4.0.1, ISTQB, 2024\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://istqb.org/istqb-releases-certified-tester-foundation-level-v4-0-ctfl/\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">ISTQB releases Certified Tester Foundation Level v4.0, ISTQB, 2023\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.pearson.com/en-us/subject-catalog/p/succeeding-with-agile-software-development-using-scrum/P200000009360/9780321660565\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">Succeeding with Agile: Software Development Using Scrum, Mike Cohn, Addison-Wesley, 2009\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://www.mountaingoatsoftware.com/blog/the-forgotten-layer-of-the-test-automation-pyramid\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">The Forgotten Layer of the Test Automation Pyramid, Mike Cohn\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://martinfowler.com/bliki/TestPyramid.html\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">TestPyramid, Martin Fowler, 2012\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://martinfowler.com/bliki/IntegrationTest.html\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">IntegrationTest, Martin Fowler, 2018\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://martinfowler.com/articles/practical-test-pyramid.html\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">The Practical Test Pyramid, Ham Vocke, 2018\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://watirmelon.blog/2012/01/31/introducing-the-software-testing-ice-cream-cone/\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">Introducing the software testing ice-cream cone (anti-pattern), Alister Scott, 2012\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">The Testing Trophy and Testing Classifications, Kent C. Dodds, 2021\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://martinfowler.com/articles/consumerDrivenContracts.html\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">Consumer-Driven Contracts: A Service Evolution Pattern, Ian Robinson, 2006\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://docs.pact.io/\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">Introduction to Pact, Pact documentation\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://docs.pact.io/getting_started/how_pact_works\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">How Pact works, Pact documentation\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003Cli>\u003Ca href=\"https://bazel.build/reference/be/common-definitions\" target=\"_blank\" rel=\"noopener\" class=\"wiki-link wiki-link--external\">Common definitions: attributes common to all test rules, Bazel documentation\u003Csvg class=\"wiki-link__icon\" viewBox=\"0 0 256 256\" width=\"16\" height=\"16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\u003Cpath d=\"M228,104a12,12,0,0,1-24,0V69l-59.51,59.51a12,12,0,0,1-17-17L187,52H152a12,12,0,0,1,0-24h64a12,12,0,0,1,12,12Zm-44,24a12,12,0,0,0-12,12v64H52V84h64a12,12,0,0,0,0-24H48A20,20,0,0,0,28,80V208a20,20,0,0,0,20,20H176a20,20,0,0,0,20-20V140A12,12,0,0,0,184,128Z\"/>\u003C/svg>\u003Cspan class=\"wiki-visually-hidden\">(откроется в новой вкладке)\u003C/span>\u003C/a> (на английском)\u003C/li>\n\u003C/ul>\n",[10,14,17,20,24,27,30,33,36,39,42,45,48,51,54],{"id":11,"level":12,"text":13},"какую-задачу-решает-пирамида-тестов",2,"Какую задачу решает пирамида тестов",{"id":15,"level":12,"text":16},"история","История",{"id":18,"level":12,"text":19},"уровни-тестирования-и-уровни-автоматизации","Уровни тестирования и уровни автоматизации",{"id":21,"level":22,"text":23},"модульные-тесты",3,"Модульные тесты",{"id":25,"level":22,"text":26},"интеграционные-тесты","Интеграционные тесты",{"id":28,"level":22,"text":29},"сквозные-тесты","Сквозные тесты",{"id":31,"level":12,"text":32},"стоимость-и-скорость-уровней","Стоимость и скорость уровней",{"id":34,"level":12,"text":35},"пирамида-тестов","Пирамида тестов",{"id":37,"level":22,"text":38},"анти-паттерн-рожок-мороженого","Анти-паттерн «рожок мороженого»",{"id":40,"level":12,"text":41},"другие-формы","Другие формы",{"id":43,"level":12,"text":44},"как-выбрать-уровень-для-проверки","Как выбрать уровень для проверки",{"id":46,"level":12,"text":47},"контрактные-тесты-между-сервисами","Контрактные тесты между сервисами",{"id":49,"level":12,"text":50},"уровни-покрытие-и-непрерывная-интеграция","Уровни, покрытие и непрерывная интеграция",{"id":52,"level":12,"text":53},"термины","Термины",{"id":55,"level":12,"text":56},"источники","Источники",2306,1793718893316]