Разделы портала

Онлайн-тренинги

.
Настрой – действуй – проверь: паттерн для хороших автотестов
10.02.2021 00:00

Автор: Энди Найт (AndyKnight)
Оригинал статьи
Перевод: Ольга Алифанова

Тест – это процедура, которая проверяет поведение с целью определить, правильно ли оно функционирует. У тестов много видов – юнит, интеграционные, end-to-end, но все функциональные тесты по сути делают одно и то же: пробуют что-то и сообщают PASS или FAIL.

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

Как же нам написать хорошие тесты, если мы планируем потратить время на создание тестов? Существует простой, но мощный паттерн, которому следую я: "Настрой – действуй – проверь" (Arrange-Act-Assert).

Паттерн

"Настрой – действуй – проверь" – отличный способ структуризации тест-кейсов. Он задает порядок операций.

  1. "Настрой" данные и цели. Эти шаги должны подготовить тест-кейс. Требует ли он объектов или особых настроек? Нужно ли подготовить базу данных? Нужен ли логин в веб-приложение? Разберитесь с этими операциями в начале теста.
  2. "Действуй" согласно целевому поведению. Эти шаги покрывают основную задачу теста. Это может быть вызов функции или метода, вызов RESTAPI или взаимодействие с веб-страницей. Действия должны быть сфокусированы на целевом поведении.
  3. "Проверь" ожидаемые результаты. Эти шаги должны получать какую-то разновидность ответа. Они убеждаются в правильности или ложности этого ответа. Иногда эти проверки просты – например, сверка числовых или строковых значений. В других случаях они требуют проверки множества аспектов системы. Проверка определяет, упал тест или прошел.
  4. Шаг "Настрой" создает переменную с именем "negative".
  5. Шаг "Действуй" вызывает функцию "abc" с использованием переменной "negative" и хранит возвращенное значение в переменной с именем "answer".
  6. Шаг "Проверь" убеждается, что "answer" – положительное число.
  7. Шаг "Настрой" формирует URL конечной точки для поиска "PythonProgramming". Обратите внимание на основной URL и параметры запроса.
  8. Шаг "Действуй" вызывает API, используя URLи "requests", а затем интерпретирует тело ответа из JSON в словарь Python.
  9. Шаг "Проверь" убеждается, что код HTTP-ответа – 200, что означает "ОК" или "успешно", и что слово "Python" появляется где-то в абстрактном тексте ответа.

В BDD паттерн "Настрой –Действуй – Проверь" называется иначе – Если – Когда – Тогда. Язык Gherkin использует шаги Если – Когда – Тогда для описания поведенческих сценариев. По сути это та же самая формула, что и в "Настрой – Действуй – Проверь".

Каждый крупный язык программирования имеет как минимум один тест-фреймворк. Фреймворки вроде JUnit, NUnit, Cucumber, и моего любимого pytestпозволяют вам как разработчику автоматизировать тесты, запускать наборы тестов и отчитываться о результатах. Однако фреймворк сам по себе не делает тест хорошим или плохим. Знать, как создавать хорошие тесты – это ваша задача как тестировщика!

Давайте посмотрим, как применить паттерн "Настрой – Действуй – Проверь" к коду Python. Для демонстрации я буду использовать pytest.

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

Вот базовый юнит-тест для функции абсолютного значения в Python:

1

2

3

4

5

6

7

8

9

10

def test_abs_for_a_negative_number():

  # Настрой

  negative = -5

   

  # Действуй

  answer = abs(negative)

   

  # Проверь

  assert answer == 5

Этот тест может показаться тривиальным, но его можно использовать для иллюстрации паттерна. Я люблю писать комментарии, отделяющие каждую фазу тест-кейса.

Тестирование фичи

Усложним задачу с более заковыристым тестом. Следующий пример проверяет DuckDuckGoInstantAnswerAPIс использованием библиотеки requests:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

import requests

def test_duckduckgo_instant_answer_api_search():

  # Настрой

  url = 'https://api.duckduckgo.com/?q=python+programming&format=json'

   

  # Действуй

  response = requests.get(url)

  body = response.json()

   

  # Проверь

  assert response.status_code == 200

  assert 'Python' in body['AbstractText']

Можно увидеть, что паттерн "Настрой – Действуй – Проверь" работает тут не хуже, чем в юнит-тестах:

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

Советы

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

Обсудить в форуме