> For the complete documentation index, see [llms.txt](https://superqa.gitbook.io/qa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://superqa.gitbook.io/qa/teoriya-testirovaniya/struktura-soderzhanie-i-process-napisaniya-proverok.md).

# Структура, содержание и процесс написания проверок

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

Меня зовут Мария Лещинская, я QA-специалист в Surf. Наша компания разрабатывает мобильные приложения с 2011 года. За это время мы создали структуру и содержание проверок, которые помогли улучшить процесс тестирования приложений.

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

![](https://pocket-image-cache.com//filters:format\(jpg\):extract_focal\(\)/https%3A%2F%2Fhabrastorage.org%2Fgetpro%2Fhabr%2Fupload_files%2F8fa%2Fcb5%2F329%2F8facb53293b19c657b2b2dd5c6044e34.png)

### Польза собственной структуры проверок

Очень важный инструмент при тестировании — тест-кейсы и чек-листы (*далее — проверки*), покрывающие приложение. Без них невозможно поддерживать качество на необходимом уровне.

Хорошая проверка:

**1. Понятна и информативна**

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

**2. Единообразна для любого проекта: имеет общую структуру внутри одной компании**

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

**3. Покрывает необходимый процент фич**

Чтобы обеспечивать определенный процент покрытия фичи, нужно:

* знать, как посчитать этот процент,
* понимать, как количественно вычислять, что было покрыто.

При хаотичном написании проверок это ресурсозатратно и сложно.

**4. Обеспечивает прозрачность работы QA**

Разработчики имеют доступ к проверкам, могут заранее просмотреть фичу на этапе разработки: очевидные баги не попадут в сборку.

**5. Обеспечивает возможность быстро и удобно модифицировать проверки**

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

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

Эти критерии побудили нас организовать одну общую структуру, чтобы писать в прямом смысле одинаково. Но, что важно, одинаково только в рамках общей структуры: свобода «творчества» внутри каждой проверки остаётся.

### Почему важно делать проверки одинаковыми по структуре

Осталось ответить на вопрос: почему писать «одинаково» настолько важно?

**1. Большое количество проектов**

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

Бывает и наоборот: один тестировщик находится на нескольких проектах одновременно. Может быть тяжело, если на одном проекте проверки написаны по структуре Х, а на другом — Y. На переключение между разными структурами уйдут время и силы: ведь нужно актуализировать старые проверки, писать новые...

**2. Мы разные**

У каждого своё мировоззрение, опыт и видение «как правильно»: это делает нас сильнее, но придаёт свои особенности в работе. Каждый из нас говорит на своем языке. Чтобы успешно взаимодействовать, нужно знать ещё один — общий.

**3. Высокий темп разработки**

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

**4. Стремление делать качественно**

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

Всё это делает необходимым переход к единообразному написанию проверок с долей свободы.

### Содержание структуры

Приложения состоят из экранов, шторок, попапов, полей ввода, кнопок, чек-боксов, свитчеров и так далее…

Мы решили разбить все составляющие на элементы и места, где они находятся. А далее — углубиться в клиент-серверную архитектуру приложения (без неё сегодня никуда). Данные на экране почти всегда берутся из запроса: он может отдать корректный и некорректный ответы. Поэтому стоит проверять и экран отдельно, и в прямом взаимодействии с запросом. Аналогично работает и с элементом.

Выделили группы:

**1. Проверки, связанные с экраном (в том числе шторка/popup и так далее)**

> → Инициализация\
> → PTR/КЭШ\
> → Навигация: Закрытие/Возврат\
> → Логика взаимодействия между экранами в стеке и МП\
> → Компоновка\
> → Работа с запросами

**2. Проверки, относящиеся к элементу (поле, карусель, чек-бокс, радиобаттон и так далее)**

> → Позитивные проверки\
> → Негативные проверки\
> → Логика работы элемента\
> → Работа с запросами

**3. Проверки, относящиеся целиком к фиче**

> → Точки входа в тестируемую фичу\
> → Взаимодействие текущей тестируемой фичи с другими

**4. Чек-листы, помогающие в регрессионном тестировании**

![Визуализация написания проверок по фиче](https://pocket-image-cache.com//filters:format\(jpg\):extract_focal\(\)/https%3A%2F%2Fhabrastorage.org%2Fgetpro%2Fhabr%2Fupload_files%2F86a%2Fd46%2Fab6%2F86ad46ab6079632642075646e736f62e.png)Визуализация написания проверок по фиче

#### Экран (в том числе шторка/popup)

![Визуализация написания проверок по экрану](https://pocket-image-cache.com//filters:format\(jpg\):extract_focal\(\)/https%3A%2F%2Fhabrastorage.org%2Fgetpro%2Fhabr%2Fupload_files%2F064%2Fb12%2F9fb%2F064b129fb770cb0a0c615465b615b2d1.png)Визуализация написания проверок по экрану

#### → Инициализация или Отправка данных

<details>

<summary>Примеры наименований</summary>

</details>

* Данные на экране отображаются в соответствии с полученным ответом на запрос
  * Данные из ответа запроса для формирования экрана берутся из нужных параметров
  * Отображение Empty State (если данные не пришли).\
    *Непосредственно данный экран рассматривается отдельно: компоновка, работа элементов и запросов.*
* Корректный запрос сформирован и отправлен
  * Данные в запросе отправляются в нужных параметрах (согласно сваггеру и ТЗ)

> Позитивный по бизнесу кейс: запрос возвращает в ответе ошибку на неверно-введённый пароль. Результат легко воспроизводимый и часто ожидаемый.
>
> Негативный по бизнесу кейс: запрос возвращает в ответе ошибку 502. Редко встречается, сложно воспроизводить (по крайней мере, так ожидается).

Такое разделение поможет при выборе кейсов для тестирования в ограниченном времени.

#### → Инициализация или Отправка данных — ошибка на запрос

<details>

<summary>Примеры наименований</summary>

</details>

* Ответ на запрос получен с ошибкой
  * Таймаут (проверить ограничение ожидания ответа на запрос в МП)
  * Основные ошибки от сервера (индивидуально для проектов)
    * 500
    * 401
    * 400
    * и так далее
* Отображение Error State\
  *Непосредственно данный экран рассматривается отдельно: компоновка, работа элементов и запросов.*

#### → Инициализация или Отправка данных — отсутствие интернета

<details>

<summary>Примеры наименований</summary>

</details>

* Отображение соответствующего уведомления (например, snackbar на экране)
* Отображение экрана (индивидуально для проектов)

  *Возможные варианты:*

  * Отображение Error State в случае отсутствия сети (актуально при инициализации экрана)
  * Отображение состояния load-state (актуально при инициализации экрана)
  * Отсутствие изменений на UI или наоборот явное изменение в состоянии отсутствия сети (актуально при PTR или изменении фильтра/сортировки, выбора значений с запросами)
* Обновление Error State (PTR или кнопка)

#### → PTR и КЭШ, если есть

**→ PTR, если есть**

<details>

<summary>Примеры наименований</summary>

</details>

*В этом случае аналогично текущей структуре лучше создать три разных проверки:*

* *Фича. Название экрана — PTR*
* *Фича. Название экрана — PTR, ошибка на запрос*
* *Фича. Название экрана — PTR, без интернета*

**→ КЭШ, если есть (работы с ним/без него)**

<details>

<summary>Примеры наименований</summary>

</details>

*В этом случае аналогично текущей структуре лучше создать несколько разных проверок:*

* *Фича. Название экрана - инициализация, с/без кэша*
* *Фича. Название экрана - инициализация, с/без кэша, ошибка на запрос*
* *Фича. Название экрана - инициализация, с/без кэша, без интернета*

**→ PTR и кэш, если есть (и используются на одном экране)**

*В этом случае, согласно текущей структуре, лучше создать несколько разных проверок:*

* Фича. Название экрана — PTR, с/без кэша
* Фича. Название экрана — PTR, с/без кэша, ошибка на запрос
* Фича. Название экрана — PTR, с/без кэша, без интернета

#### Навигация: Закрытие экрана / Возврат назад на предыдущий экран

<details>

<summary>Примеры наименований</summary>

</details>

*Если запроса нет, достаточно одной проверки по закрытию экрана. Если запрос используется, лучше создать три разных проверки:*

* *Фича. Название экрана — закрытие*
* *Фича. Название экрана — закрытие, ошибка на запрос*
* *Фича. Название экрана — закрытие, без интернета*
* *Фича. Название экрана — назад на предыдущий экран*
* *Фича. Название экрана — назад на предыдущий экран, ошибка на запрос*
* *Фича. Название экрана — назад на предыдущий экран, без интернета*

Со следующими шагами:

* Назад по кнопке, если есть
* Физическая кнопка «Назад» на Android
* Бэксвайп на iOS

#### → Логика взаимодействия между экранами в стеке и МП

*Такая логика может быть описана в возврате (предыдущий пункт)*

<details>

<summary>Примеры наименований</summary>

</details>

* Сохранение данных в стеке экранов одной фичи — если предусмотрено / Очистка данных при переходе и возврате на экраны — если сохранение не предусмотрено

  Частный случай: сохранение/очистка в кэше — свернуть и запустить приложение -> отображение данных как и до сворачивания
* Сворачивание приложения во время флоу — сохранение положения МП

#### → Компоновка

<details>

<summary>Примеры наименований</summary>

</details>

* Описание элементов: их наименования + дизайн (скриншот, ссылка на фигму). Если это кнопка, то здесь же проверяется её пресс-стейт

### Элемент (поле, карусель, чек-бокс, радиобаттон и тп)

![Визуализация написания проверок по элементу](https://pocket-image-cache.com//filters:format\(jpg\):extract_focal\(\)/https%3A%2F%2Fhabrastorage.org%2Fgetpro%2Fhabr%2Fupload_files%2F1e6%2Fa51%2Ff80%2F1e6a51f808a8567ae8890364a221aaf3.png)Визуализация написания проверок по элементу

#### → Позитивные проверки

<details>

<summary>Примеры наименований</summary>

</details>

* Заполнение поля корректными значениями
* Вставка в поле корректных значений

> Для текстового поля без ограничений вставка или заполнение поля смайликами — позитивная проверка: она очевидно возможная.
>
> Для поля ввода суммы с цифровой клавиатурой вставка смайликов — негативная проверка: она очевидно неожиданная для текущей логики поля.

* Ограничение на размер поля
  * *Техника классов эквивалентности и граничных значений (позитивные проверки)*
* Заполнение поля максимально возможной длиной, если длина большая и текст может зайти на границу экрана (проверка на корректное расширение/скролл поля и отображение в нём значения)
* Пустое поле (если заполнять его необязательно)

#### → Негативные проверки

<details>

<summary>Примеры наименований</summary>

</details>

* Заполнение поля некорректными значениями

  *Не стоит забывать о проверке на подскролл к невалидным полям, если:*

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

#### → Логика работы элемента

<details>

<summary>Примеры наименований</summary>

</details>

* Общие действия с элементом и его реакция на них

> Примеры:
>
> → Открытие определенного вида клавиатуры при активации поля
>
> → Расширение поля при заполнении
>
> → Выставление курсора в конец заполненной строки при активации поля
>
> → Валидация поля при снятии фокуса
>
> → Валидация поля при нажатии кнопки
>
> → Маска (для номера телефона, например)
>
> → Корректная активация/деактивация чек-бокса/радиобаттона
>
> → Зацикленная карусель / Незацикленная карусель

### Фича

#### → Точки входа в тестируемую фичу

<details>

<summary>Примеры наименований таких проверок</summary>

</details>

* Указываются проверки покрывающие все места, откуда можно попасть к тестируемой фиче с других экранов

#### → Взаимодействие текущей тестируемой фичи с другими

<details>

<summary>Примеры наименований таких проверок</summary>

</details>

> Примеры:
>
> → Темная тема (если поддерживается)\
> *Смена темы и работа с тестируемой фичей*
>
> → Пуш-уведомления + диплинки (если поддерживаются)\
> *Переход по диплинку во флоу тестируемой фичи*
>
> → Планшет (если поддерживается)\
> *Компоновка, режим сплит-вью (если поддерживается)*
>
> \- Huawei (если поддерживается)\
> *Специфичные проверки (см.* [*Особенности тестирования Android без Google-сервисов*](https://habr.com/ru/company/surfstudio/blog/559106/)*)*

### Готовые чек-листы

#### → Обязательный чек-лист проверок

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

* Изменение размера шрифтов из настроек устройства
* Смена темы из настроек устройства
* Изменение языка из настроек устройства
* Смена времени из настроек устройства
* Использование кастомной клавиатуры Android (в частности, для полей и поисковой строки)
* Входящий звонок/смс во время прохождения флоу фичи
* Поворот устройства
* Выход из приложения двойным «Назад» на Android
* Свернуть приложение и запустить снова
* Свернуть приложение во время ожидания ответа на запрос
* Отключить интернет во время ожидания ответа на запрос

#### → Дополнительный чек-лист проверок

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

* Запустить приложение без доступа к интернету вообще
* Нажатие кнопки блокирования при отображении сплеша
* Запуск и сразу же сворачивание приложения
* Сворачивание приложения во время отображения системного окна оплаты Apple/Google/Samsung/Huawei Pay
* Отображение на планшетах (в режиме совместимости, если нет поддержки планшетов)
* Автоподстановка кода из смс (иногда идет по-умолчанию в iOS проектах)
* Работа приложения при пуш-уведомлении другого стороннего приложения (сообщение ВКонтакте, Twitter и так далее)
* Работа приложения после срабатывания будильника/таймера/смс/другого системного приложения
* Работа открытого приложения после разблокировки приложения
* Работа свернутого приложения после разблокировки приложения
* Работа приложения при сообщении о нехватке заряда
* Работа приложения при зарядке
* Работа приложения после отключения от зарядки
* Работа приложения при воспроизведении музыки
* Работа приложения с мобильным интернетом 3G/4G/слабым интернет-соединением
* Работа с фичей «картинка в картинке» (если поддерживается)

### Что даёт структура проверок

* Понятность,
* прозрачность,
* единообразие
* возможность обеспечить необходимое покрытие,
* возможность быстрой модификации.

Один из существенных дополнительных плюсов — использование этого подхода в автотестировании. Например, это мастхэв при работе с Flutter внутри widget-тестов. Каждый элемент во Flutter — это виджет (будь то эĸран или элемент): виджет-тесты отлично маппятся с нашими проверками, которые детально покрывают ĸаждый элемент или эĸран.

***

В статье описаны только компонентные проверки — по каждому элементу. Они пригодятся в начале тестирования: такая структура покрывает больше элементов, обеспечивает уверенность в качестве продукта.

Когда QA работает с sanity или smoke тестированием, нет смысла тратить время на детальную проверку каждого элемента. Нужны сценарные проверки, которые покроют целиком путь пользователя. О том, как работать со сценарными проверками, поговорим в следующей статье.

А как вы решаете вопрос с организацией проверок? Придерживаетесь хаотичного или системного подхода? Поделитесь в комментариях!
