Как стать автором
Обновить
439.69

Неизвестные пробелы в тестовом покрытии

Уровень сложностиСредний
Время на прочтение16 мин
Количество просмотров1K

Привет! Я Наталья, QA в команде инкассации. Моя система умеет планировать маршруты для инкассаторов T-Банка. Поделюсь докладом моего коллеги — архитектора Boxy SDK Дмитрия Кузнецова, — который услышала на конференции Heisenbug. 

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

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

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

С чего все начиналось

Началось с того, что одна команда работала в сфере привлечения клиентов и за время своей работы сделала около 200 микрофронтендов, которые автоматически поставлялись в прод каждый день. И в них не было багов. 

Казалось бы, ребята собаку съели в микрофронтендах, пока однажды их не пригласили помочь с новым проектом Т-Банк PWA — личный кабинет. А в этом проекте были баги. Стало интересно, что же там происходит и идет не так. На проекте работало более 100 фронтендеров в 15 командах, они каждый день поставляли десятки микрофронтендов в прод.

T-банк PWA — это личный кабинет Т-Банка, основанный на PWA-версии — платформе с рекордной скоростью доставки в прод, лишенной санкционных рисков и имеющей:

  • 15+ продуктовых команд;

  • 100+ фронтовых разработчиков;

  • ежедневные релизы.

T-Банк PWA, личный кабинет Т-Банка
T-Банк PWA, личный кабинет Т-Банка

В результате анализа нашлись процессные проблемы, приводящие к неполному покрытию:

  • сложность стека; 

  • много новых людей пришли в компанию и перешли из других команд — они не были знакомы с процессами, технологиями, инструментами нашей компании;

  • пирамида тестирования состояла из двух десятков видов тестов;

  • опробованные решения, такие как Test case as code и выгрузка в Allure, не работали здесь так же хорошо, как в предыдущем проекте;

  • трудно посчитать тестовое покрытие;

  • тестов много, а баги в проде есть.

Из этих проблем вытекали выводы и действия:

  • написали много инструкций, провели обучение;

  • изменили процесс написания спецификаций;

  • решили писать тест-кейсы до разработки кода;

  • стали структурировать тест-кейсы в Allure.

Шаги оказались правильными: проблема действительно была в этом . Но после этого не получалось ответить на вопрос: а каково покрытие всего проекта и есть ли в нем пробелы? То есть поток багов в прод уменьшился, но все равно оставался значительным.

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

Несоответствие типов тестов уровням классической пирамиды
Несоответствие типов тестов уровням классической пирамиды

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

Пример 1. Клик по ссылке

Допустим, имеется функциональное требование: система должна переходить на url при клике на ссылку.

Здесь буква Т — требования, 1 — первое требование
Здесь буква Т — требования, 1 — первое требование
Так выглядит сама система, в которой предполагается переход в другой раздел приложения при клике на ссылку «Все предложения»
Так выглядит сама система, в которой предполагается переход в другой раздел приложения при клике на ссылку «Все предложения»

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

Т1 — это продуктовое требование к системе
Т1 — это продуктовое требование к системе

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

В примере показано системное требование и два элемента системы. Расщепляем требование на эти элементы, как бы проецируем, и получаем два производных требования: Т2 и Т3. Т2 — это требование к фронту, которое звучит как «при клике должен приводить к переходу на url, заданному в бэке». Т3 — это требование к бэку, который должен отдавать url в заданном формате.

Исходное требование Т1 осталось, но появились Т2 и Т3 — это производные требования, они зависят от Т1. Если исчезнет Т1, Т2 и Т3 тоже исчезнут. Если Т1 изменится, Т2 и Т3 тоже изменятся. То есть эти три требования существуют совместно. Они различаются: два из них — производные первого. Тут не придуманы новые требования, имеется одно продуктовое системное, которое было расщеплено на два.

Итого:

  • Т2 и Т3 — производные Т1;

  • Т2 и Т3 по отдельности проще реализовать и протестировать;

  • расщепление стало возможным благодаря архитектуре;

  • требования не переносятся, а существуют совместно!

Посмотрим еще раз на нашу систему.

Слева — фронт, он должен брать ссылку из cms, отображать ее и при клике переходить по ней на другую страницу. Справа — интерфейс cms, где эта ссылка задается. То есть
Слева — фронт, он должен брать ссылку из cms, отображать ее и при клике переходить по ней на другую страницу. Справа — интерфейс cms, где эта ссылка задается. То есть

Можно пойти дальше и вспомнить, что у нас микрофронтовая архитектура. 

Пример расщепления системного требования на производные
Пример расщепления системного требования на производные

Фронтенд тоже можно разделить на две части — микрофронт и хостовое приложение. Вот здесь начинается интересное. Потому что требование к микрофронтенду — не переходить по ссылке, а вызывать метод navigate, который нам поставляет хостовое приложение.

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

В примере внутренние ссылки — это спа-переходы, а внешние — хард-переходы. И о том, какие ссылки внешние, а какие внутренние, знает только хостовое приложение, а микрофронтенд — нет

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

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

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

Видим по Т4, что микрофронтенд не умеет ходить по ссылкам! Очевидно, что аналитики живут в Т1, они пишут требования для системы и говорят: «Хочу, чтобы клик приводил к переходу». А разработчики живут в Т4: они работают с микрофронтендами, разрабатывают их и куда-то встраивают. И это разные места в системе, которые приводят к тому, что разработчик берет спеку, в голове производит неявное расщепление и пытается спроецировать исходное требование на свой кусочек, что добавляет когнитивной нагрузки разработчику. 

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

Важный момент: производные требования могут быть совершенно непохожими на исходные системные требования.

Вызов микрофронтом метода navigate() из хостового приложения
Вызов микрофронтом метода navigate() из хостового приложения

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

Требования бывают атомарные и неатомарные: 

  • пример неатомарного требования — «Клик в ссылку»;

  • пример атомарного требования — «Клик в ссылку Х на странице Y». 

Дальше будем рассматривать только атомарные требования. То есть для 200 микрофронтов по 10 ссылок будет 2000 системных требований.

Дальше можно пойти все ниже и ниже, но как понять, до каких пор нужно расщеплять?

Группировка требований в рамки архитектурных границ
Группировка требований в рамки архитектурных границ

Можно уйти на 100 шагов вниз, пока не будут получены совсем примитивные элементы, которые раздадим стажерам и сделаем за пять минут. Получаем продукт за пять минут ресурсами стажеров. Но нет, конечно!

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

Примеры архитектурных границ
Примеры архитектурных границ

Граница между фронтендом и бэкендом — это http-протокол + swagger.

Граница между хостовым приложением и микрофронтендом — это microcontract, в данном случае интерфейс на typesript, который определяет их взаимодействие.

Микрофронтенд также разделен на два компонента — компонент самого микрофронтенда и компонент ссылки. Граница между ними — public interface.

Рассмотрим для примера требование к компоненту Link, которое покажет принадлежность требования к верхнеуровневым системным от разных микрофронтендов.

Пример принадлежности требования к компоненту Link (Т9) к разным микрофронтендам
Пример принадлежности требования к компоненту Link (Т9) к разным микрофронтендам

Допустим, дано 150 микрофронтендов (MF1..MF150), в каждом из которых есть ссылка Link. Опытный глаз разработчика сразу заметит, что ссылка одинаковая и можно ее выделить как абстракцию. В результате получаем требование к Link как результат выделения Т9 из разных микрофронтендов. Тогда при спуске уменьшается количество требований. Так спуск позволяет уменьшать количество требований и тестов!

Один тест для одного компонента, принадлежащего многим требованиям
Один тест для одного компонента, принадлежащего многим требованиям

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

Термины, которые понадобятся дальше:

Требование — информация о том, как должна работать программа. Они формулируются на языке человека, например «Клик по ссылке должен приводить к переходу на url» (атомарные требования).

Код — это информация о том, как должна работать программа, на языке компьютера. Лишь код существует объективно!

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

Тест-кейс — это инструкция на человеческом языке для проверки соответствия работы программы поставленному требованию. Например:

1. Кликаем по ссылке.

2. Ожидаем переход.

Автотест — это инструкция на языке компьютера для проверки соответствия работы программы поставленному требованию. Например:

await page.click('.link')

expect(page).toHaveUrl(url)

Выводы из примера 1:

Требования первичны:

  • код — производная от требования;

  • тест-кейс — производная от требования;

  • автотест — производная от тест-кейса.

Отношение кода, теста и автотеста к требованию
Отношение кода, теста и автотеста к требованию

Пространство требований, кейсов, автотестов и кода — это четыре пространства, в которых элементы соотносятся как 1:1, то есть взаимно однозначное преобразование.

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

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

Однозначное преобразование из требований в тест-кейсы порождает девять тест-кейсов на ссылку. Выглядит многовато для одной ссылки
Однозначное преобразование из требований в тест-кейсы порождает девять тест-кейсов на ссылку. Выглядит многовато для одной ссылки

Возникает вопрос: какие тесты выбрать, чтобы у нас не было пробела в тестовом покрытии?

Девять тестов на ссылку — какие выбрать?
Девять тестов на ссылку — какие выбрать?

При выборе тестов будем опираться на такие факторы:

  • время регресса — влияет на скорость релизов. Стоит вопрос о его оптимизации или даже об отказе от регресса; 

  • недостаточное тестовое покрытие — решаем, сколько тестов создать, чтобы нивелировать риски для прода;

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

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

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

Будут ли пробелы, если в дереве только конечные узлы покрыли тестами? 

Покрытие тестами только конечных узлов дерева требований
Покрытие тестами только конечных узлов дерева требований

Давайте еще больше упростим, сфокусируемся только на системном требовании. 

Вариант покрытия тестами только вспомогательных требований
Вариант покрытия тестами только вспомогательных требований

Будут ли пробелы, если взять только фронт и бэк, покрыть их тестами, а системную проверку перехода по ссылке не делать? Правильный ответ: мы не знаем (но, скорее всего, будут).

Пробел в тестировании
Пробел в тестировании

Причина появления пробелов в том, что тестирование — это наука не о том, чтобы доказать, что программа работает корректно. А о том, чтобы доказать, что она работает НЕкорректно. И если доказать это не удалось, то с какой-то вероятностью программа работает корректно. То есть остается некоторый пробел.

Этот пробел состоит из двух частей: первая — известная, вторая — неизвестная. Чем выше грейд, обширнее опыт и чем больше контекст в рамках конкретного проекта, тем больше известная зона пробела и тем меньше неизвестная.

Две части пробела — известная и неизвестная
Две части пробела — известная и неизвестная

Примеры известных пробелов — проблемы интеграции и интерференция требований.

Проблема интеграции:

  1. нарушен контракт между фронтом и бэком. Например, url не в том формате и в результате нарушена совместная работа;

  2. отсутствуют сетевые доступы.

Интерференция требований:

  1. залез прозрачный .popover и мешает клику по ссылке;

  2. недоступность по причине CSP, фронт не может ходить в бэкенд;

  3. асинхронность: фронт ходит в бэкенд, но там бешеные лаги. Пользователь кликает на ссылку, но она не работает;

  4. сторонний скрипт аналитики вмешивается и делает свойство default на всех ссылках или еще что-нибудь нехорошее.

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

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

Домашнее задание, если интересно копнуть тему поглубже:
  1. Возьмите unit-тест на проекте.

  2. Выведите одно или несколько требований, которые он покрывает. 

  3. Найдите предков этого требования до системного уровня.

  4. Попробуйте найти тесты на предков.

  5. При этом попытайтесь ответить на вопросы:

    к чему относится unit-тест;

    полезен ли этот unit-тест;

    какую часть в вашей архитектуре он закрывает.

  6. Задача со звездочкой: сделать то же для случайного места в коде.

Пример 2. Снежинка

Имеется требование: лик по кнопке «Заморозить» замораживает карту, и вместо номера счета появляется снежинка.

Так выглядит функция Заморозить/Разморозить в приложении
Так выглядит функция Заморозить/Разморозить в приложении

Расщепим системное требование на фронтенд и бэкенд:

Пример расщепления системного требования
Пример расщепления системного требования

Фронтенд должен вызывать метод freeze и проверять получение данных карты методом details, а затем обновлять снежинку по флагу «Заморожен». Бэкенд должен замораживать карту. Дальше покупки по ней невозможны

Личный кабинет с отображением открытого номера счета и доступной опцией «Заморозить»
Личный кабинет с отображением открытого номера счета и доступной опцией «Заморозить»

Расщепим Т2.

Расщепление требования «клик на снежинку» на производные
Расщепление требования «клик на снежинку» на производные

Пример со снежинкой сложнее, потому что здесь два микрофронтенда: один — кнопки, второй — сама карта. Требования к первому микрофронтенду — вызов методов freeze и details по клику. Требования ко второму микрофронтенду — реактивное обновление данных. И тут еще появляется хостовое приложение (Т6), которое обеспечивает взаимодействие между двумя микрофронтендами. В итоге получаем три производных требования фронтенда.

Можно пойти ниже и расщепить требования Т4, Т5, Т6, но не будем этого делать, так как, поверьте, и там будут конкретные сущности с производными требованиями.

Расщепление дерева требований
Расщепление дерева требований

Является ли дерево требований пирамидой тестирования? Нет, конечно.

Пирамида — это производная архитектуры. Любое разложение на производные возможно благодаря архитектурным границам, помогающим изолировать элементы системы. Как же можно совместить слои пирамиды с деревом требований? Никак :)

Почти каждый узел может быть в каждом слое.

Совместимость пирамиды с деревом требований: почти каждый узел может быть в каждом слое
Совместимость пирамиды с деревом требований: почти каждый узел может быть в каждом слое

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

Элементарные элементы
Элементарные элементы

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

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

Альтернативные сущности, которые можно проверить, но в основе — изоляция, то есть то, как система будет разбита на элементы
Альтернативные сущности, которые можно проверить, но в основе — изоляция, то есть то, как система будет разбита на элементы

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

Домашнее задание для тех, кто хочет копнуть тему глубже.

Установите связь пирамиды с архитектурой:

  1. Возьмите системное требование.

  2. Разложите требование по архитектуре приложения.

  3. Найдите тесты, связанные с производными требованиями.

  4. Установите связь видов тестов с узлами архитектуры.

Пример 3. Логирование ошибок

Дано функциональное требование: если падает запрос к API из браузера, это должно логироваться.

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

Дерево требований по логированию ошибок
Дерево требований по логированию ошибок

Системное требование (Т1) говорит о том, что нужно логировать ошибки падения запросов к API. Требования к фронту (Т2) — чтобы дергался некий метод log с этими ошибками. Требования к микрофронтенду (Т4) — чтобы дергалась некая сущность в стороннем приложении, которая под капотом дернет бэкенд. В свою очередь, микрофронтенд состоит из двух частей: API-клиента (Т6) и http-клиента (Т7) 

Две части микрофронтенда взаимодействуют, и это взаимодействие было нарушено. Что же пошло не так?

Область понятности
Область понятности

Введем термин «область понятности». В общем случае разработчики-бэкендеры лучше понимают, что происходит в бэкенде (Т3), разработчки-фронтендеры — во фронтенде (Т2, Т4, Т5), а продукт-менеджеры, скорее всего, обитают в районе Т1 и ниже спускаются редко. 

Продуктовый разработчик, который должен был это учесть, обитает в зоне понятности в районе микрофронтенда. При этом со своей стороны он не спускается до уровня платформы (Т6 и Т7), потому что считает, что доверяет тому, что поставляет платформа. Наверх он тоже не движется в силу того, что видит своей задачей только поставку микрофронтенда.

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


Два выхода из ситуации
Два выхода из ситуации

Есть два варианта выхода из ситуации. С одной стороны, можно отказаться разбираться в архитектуре и том, что и как устроено. Достаточно знать, как работает фронтенд и микрофронтенд. Это рабочий и при этом дешевый вариант. Но тогда нужно скукожиться в области понятности на соответствующих уровнях, а остальные забыть и не учитывать при оценке тестового покрытия. В нашем примере это значит забыть про тесты на уровнях 6 и 7 и продублировать их на понятных нам уровнях 2 и 4.

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

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

Эффективность дерева

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

В первую очередь эти факторы такие:

  • время жизни проекта и его критичность;

  • требования к скорости доставки и частоте релизов;

  • архитектура проекта и гранулярность поставки;

  • уровень и размер команды.

Здесь встает вопрос: можно ли написать только системные тесты и дальше не ходить, потому что непонятно, зачем покрывать новые узлы?

Ответ такой: это нужно для снижения затрат на обеспечение качества при его сохранении.

Плюсы и минусы добавления нового узла

+ Ускоряет фидбэк от тестов

+ Улучшает проработку требований

+ Ускоряет поиск проблем

— Больше тестов писать и поддерживать

— Сложнее анализировать тестовое покрытие

— Выше порог входа (больше технологий)

— Больше тестовых обвязок

Выгоды, которые могут быть при добавлении тестов на уровень фронтенда, если раньше были написаны только системные тесты:

  • это ускоряет фидбэк от тестов за счет повышения локальности;

  • это улучшает проработку требований, так как появляется явная архитектурная граница, в которой легче ориентироваться;

  • это ускоряет поиск проблем из-за локальности тестов. 

С другой стороны:

  • придется писать больше тестов;

  • придется разбираться в большем количестве технологий и фреймворков;

  • будет выше порог входа;

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

Поэтому эффективность узла — это следующее выражение в процентах:


Оценка эффективности узла на проекте без автоматизации, узел - система
Оценка эффективности узла на проекте без автоматизации, узел - система

100 — количество релизов за время жизни проекта, 4 — количество часов на регресс, 8 — количество часов на настройку автоматизации, 2 — количество часов экономии на регрессе. Экономия составляет не все четыре часа. Во-первых, потому, что ручные тесты остаются. А во-вторых, из-за нестабильного бэкенда придется разбирать причины падений, перезапускать тесты, часть проходить вручную. И это потеря времени

Получается, что если бы на проекте, где нет автоматизации, взялись за системный узел дерева, то получили бы эффективность такого узла 50%, то есть в два раза уменьшили бы количество ресурсов на обеспечение качества.

Рассмотрим другой вариант, когда фокус не на системном узле, а на узле фронтенда с мокированными тестами.

Для той же фронтовой команды:

  • с хорошим опытом автоматизации;

  • с нестабильным бэкендом;

  • с еженедельными релизами в течение двух лет, то есть примерно 100 релизов; 

  • узел — фронт.

Тогда оценка эффективности узла будет выглядеть так:

Оценка эффективности узла для проекта с моками, узел - фронт
Оценка эффективности узла для проекта с моками, узел - фронт

Здесь тратится больше времени на автоматизацию (50 часов), потому что надо собрать и настроить моки и процесс. При этом регресс также сокращается на час. И в итоге получаем эффективность уже 63%

Цифры условные, суть не в них, а в том, что разные узлы имеют разную эффективность. И это сильно зависит от команды, проекта и всего остального.

Вывод: эффективность узлов разная.

Возьмем другую фронтовую команду:

  • без опыта автоматизации;

  • со стабильным бэкендом;

  • с ежемесячными релизами в течение двух лет, то есть примерно 24 релиза; 

  • узел — система.

Тогда оценка эффективности узла будет выглядеть так:

Оценка эффективности узла для команды без опыта автоматизации, узел - система
Оценка эффективности узла для команды без опыта автоматизации, узел - система

Фронтовая команда без опыта автоматизации, но с хорошим тестовым контуром. При этом количество ежемесячных релизов около 24, время жизни продукта — два года. Затрат на автоматизацию здесь больше (60 часов), и меньше профита от экономии на регрессе. В итоге эффективность будет 12%

Но самое интересное дальше. Рассмотрим ту же команду, но для узла фронт. Тогда оценка эффективности узла будет выглядеть так:

Оценка эффективности узла для команды без опыта автоматизации, которая решила делать моки, узел - фронт
Оценка эффективности узла для команды без опыта автоматизации, которая решила делать моки, узел - фронт

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

Вывод: эффективность узлов может быть отрицательной. Когда делать больше видов тестов:

  1. Мотивированная команда.

  2. Долгий срок жизни проекта.

  3. Высокая частота релизов.

  4. Высокая критичность проекта. 

  5. Большой масштаб проекта.

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

Домашнее задание для тех, кто хочет больше изучить тему.

Оцените эффективность ваших видов тестов:

  1. Какие тесты приносят больше пользы и позволяют найти больше багов?

  2. Какие тесты малополезны и почему?

  3. Есть ли тесты, которые вас замедляют?

  4. Какие компетенции надо прокачать команде, чтобы все тесты приносили много пользы?

Выводы

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

Пирамида = дерево, определяемое архитектурой. В наше время, где все сложно, где много элементов в диаграмме, где элементы не элементарны, где они составные и сами делятся на подэлементы, пирамида уже не пирамида, а дерево.

Спуск по этой пирамиде или дереву и зона непонятности являются источником пробелов. Узлы дерева (слои пирамиды, виды тестов) имеют разную эффективность. 

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

Теги:
Хабы:
+16
Комментарии0

Публикации

Информация

Сайт
l.tbank.ru
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия