Автоматизация тестирования
Цели автоматизация тестирования
Пирамида тестирования
Уровень 1: Unit-тесты (основание пирамиды)
Уровень 2: Интеграционные тесты (средина пирамиды)
Уровень 3: E2E / UI-тесты (вершина пирамиды)
Антипаттерн: Перевёрнутая пирамида (Мороженое)
Postman
Определится с API
Arrange–Act–Assert
Arrange-Act-Assert (AAA)
Избегание множественных секций arrange, act и assert
Насколько большой должна быть каждая секция?
Пример. Клиент совершает покупку в интернет-магазине
Решение
Сколько проверок должна содержать секция проверки?
Переиспользование тестовых данных между тестами
Первый способ
Второй способ
Именование юнит-тестов
2.63M
Категория: ПрограммированиеПрограммирование

Лекция №7 Автоматизация тестирования

1. Автоматизация тестирования

1

2.

2
Автоматизация тестирования — процесс создания и использования кода
для проверки ПО с помощью специализированных инструментов
(например, Selenium, JUnit, Postman) для выполнения проверок
программного обеспечения. Её цель — повысить эффективность
тестирования, снизить количество рутинных задач и обеспечить более
стабильную, быструю и воспроизводимую проверку качества на разных
этапах разработки.

3. Цели автоматизация тестирования

3
Цели автоматизация тестирования
Применение современных технологий помогает QA и QC командам
быстрее находить ошибки, проверять важные функции без лишних усилий
и выпускать продукт с большей уверенностью в его стабильности,
корректности и безопасности. Это осознанный подход, который позволяет
системно улучшать качество, снизить ручные трудозатраты и
сосредоточиться на проверке действительно важных сценариев.
Однако есть частая ошибка — попытка автоматизировать всё подряд, без
приоритизации и понимания итоговой ценности. Это приводит к росту
времени на поддержку тестов, накоплению нестабильных проверок и
задержкам в релизах. Поэтому важно заранее определить, какие уровни
тестов действительно нужны проекту и как выстроить стратегию
автоматизации с учётом контекста.

4. Пирамида тестирования

4
Пирамида тестирования

5. Уровень 1: Unit-тесты (основание пирамиды)

5
Уровень 1: Unit-тесты (основание
пирамиды)
Unit-тесты проверяют отдельные функции, методы или классы в изоляции от
остальной системы.
Кто пишет: Разработчики
Скорость: Миллисекунды (тысячи тестов за секунды)
Стоимость: Дёшево писать и запускать
Что находят: Ошибки в логике отдельных функций
Количество: Должно быть больше всего — 70-80% от всех тестов
Пример: Функция calculateDiscount(price, percent) — unit-тест проверяет,
что для 100 и 10% возвращается 90.

6. Уровень 2: Интеграционные тесты (средина пирамиды)

6
Уровень 2: Интеграционные тесты
(средина пирамиды)
Интеграционные тесты проверяют взаимодействие между несколькими
компонентами: модулями, сервисами, базой данных.
Кто пишет: Разработчики и тестировщики
Скорость: Секунды
Стоимость: Дороже unit-тестов
Что находят: Ошибки в стыках между компонентами
Количество: Меньше, чем unit-тестов — около 20%
Пример: Тест API-эндпоинта /api/orders — проверяет, что сервис заказов
корректно взаимодействует с базой данных.

7. Уровень 3: E2E / UI-тесты (вершина пирамиды)

7
Уровень 3: E2E / UI-тесты (вершина
пирамиды)
End-to-End (E2E) тесты имитируют действия реального пользователя в
браузере от начала до конца.
Кто пишет: QA-инженеры по автоматизации
Скорость: Минуты
Стоимость: Дорого писать, запускать и поддерживать
Что находят: Ошибки в полных пользовательских сценариях
Количество: Минимум — 5-10% от всех тестов
Пример: Тест «Пользователь регистрируется → входит → создаёт заказ →
оплачивает».

8. Антипаттерн: Перевёрнутая пирамида (Мороженое)

8
Антипаттерн: Перевёрнутая
пирамида (Мороженое)
Где находится ручное тестирование в пирамиде
Ручное тестирование дополняет пирамиду, но не является её частью.
Ручной тестировщик работает преимущественно:
На уровне E2E — проверяет полные пользовательские сценарии
За пределами пирамиды — исследовательское тестирование, UX, edge
cases
Исследовательское тестирование — это то, что автоматика никогда не
заменит: тестировщик исследует систему без заранее написанных
сценариев, пытается её «сломать» творческим способом.

9. Postman

9
Postman
Postman — это не фреймворк, а платформа (инструмент) для работы
с API (Application Programming Interface), то есть с интерфейсами
взаимодействия между программами. Она позволяет отправлять HTTPзапросы к серверу, получать и анализировать ответы, автоматизировать
проверки и документировать интерфейсы.

10.

10

11.

11

12.

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

13.

13

14.

14
(1) - вкладки с запросами
(2) - метод
(3) - URL
(4) - отправка запроса
(5) - параметры запроса
(6) - параметры ответа

15. Определится с API

15
Можем использовать свой API, API своей компании или API с открытой документацией.
Самое главное, чтобы у вас была под рукой документация, ведь без нее ничего не получится.
Если на вашем продукте ее нет, то попросите backend разработчиков помочь вам и
написать ее.
Вот несколько примеров public API, которые можно использовать для практики:
reqres
httpbin.org
Petstore
Cat facts
Bored API
agify.io
nationalize.io
Random dog images

16. Arrange–Act–Assert

16
Arrange–Act–Assert
Arrange–Act–Assert (AAA) — это распространённый паттерн
структурирования тестов, который делит тест на три последовательных
блока: подготовка данных, выполнение действия и проверка результата.
Такой подход повышает читаемость и предсказуемость тестов, упрощает
их написание и диагностику при падении.

17. Arrange-Act-Assert (AAA)

17
Arrange: подготовка среды, в которой выполняется код
Act: тестирование кода (обычно представляет одну строку кода)
Assert: убеждаемся, что результат теста именно тот, что мы и ожидали
class CalculatorTests
{
public void Sum_2Plus5_7Returned()
{
var calc = new Calculator(); // arrange
var res = calc.Sum(2,5); // act
Assert.AreEqual(7, res); // assert
}
}
class CalculatorTests
{
public void Sum_2Plus5_7Returned()
{
Assert.AreEqual(7, new Calculator().sum(2,5));
}
}

18. Избегание множественных секций arrange, act и assert

18
Избегание множественных секций
arrange, act и assert
Иногда встречаются тесты с несколькими секциями arrange (подготовка),
act (действие) или assert (проверка).

19.

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

20. Насколько большой должна быть каждая секция?

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

21. Пример. Клиент совершает покупку в интернет-магазине

21
Пример. Клиент совершает покупку
в интернет-магазине
public void
Purchase_succeeds_when_enough_inventory()
{
// Arrange
var store = new Store();
store.AddInventory(Product.Shampoo, 10);
var customer = new Customer();
// Act
bool success = customer.Purchase(store,
Product.Shampoo, 5);
// Assert
Assert.True(success);
Assert.Equal(5,
store.GetInventory(Product.Shampoo));
}

22. Решение

22
public void Purchase_succeeds_when_enough_inventory()
{
// Arrange
var store = new Store();
store.AddInventory(Product.Shampoo, 10);
var customer = new Customer();
// Act
bool success = customer.Purchase(store, Product.Shampoo, 5);
store.RemoveInventory(success, Product.Shampoo, 5);
}
// Assert
Assert.True(success);
Assert.Equal(5, store.GetInventory(Product.Shampoo));

23. Сколько проверок должна содержать секция проверки?

23
Сколько проверок должна
содержать секция проверки?
Так как под «юнитом» в юнит-тестировании понимается единица
поведения, а не единица кода, то одна единица поведения может
приводить к нескольким результатам. Проверять все эти результаты в
одном тесте вполне нормально.
Тем не менее, если секция проверки получается слишком большой: это
может быть признаком того, что в коде недостает какой-то абстракции.
Например, вместо того чтобы по отдельности проверять все свойства
объекта, возвращенного тестируемой системой, возможно, будет лучше
добавить методы проверки равенства в класс такого объекта. После этого
объект можно будет сравнивать с ожидаемым значением всего одной
командой.

24. Переиспользование тестовых данных между тестами

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

25. Первый способ

25
Первый способ
Первый способ переиспользования тестовых данных — инициализация
их в конструкторе теста. Такой подход позволяет значительно сократить
объем кода в тестах — вы можете избавиться от большинства (или даже от
всех) конфигураций в тестах. Однако у этого подхода есть два серьезных
недостатка.
1. Он создает сильную связность между тестами. Изменение логики
подготовки одного теста повлияет на все тесты в классе.
2. Другой недостаток выделения кода подготовки в конструктор —
ухудшение читаемости теста.

26. Второй способ

26
Второй способ
public class CustomerTests
{
public void Purchase_succeeds_when_enough_inventory()
{
Store store = CreateStoreWithInventory(Product.Shampoo, 10);
Customer sut = CreateCustomer();
bool success = sut.Purchase(store, Product.Shampoo, 5);
}
Assert.True(success);
Assert.Equal(5, store.GetInventory(Product.Shampoo));
public void Purchase_fails_when_not_enough_inventory()
{
Store store = CreateStoreWithInventory(Product.Shampoo, 10);
Customer sut = CreateCustomer();
bool success = sut.Purchase(store, Product.Shampoo, 15);
}
Assert.False(success);
Assert.Equal(10, store.GetInventory(Product.Shampoo));
private Store CreateStoreWithInventory(Product product, int
quantity)
{
Store store = new Store();
store.AddInventory(product, quantity);
return store;
}
}
private static Customer CreateCustomer()
{
return new Customer();
}

27. Именование юнит-тестов

27
Именование юнит-тестов
Правильное именование помогает понять, что проверяет тест и как работает
система. Есть много рекомендаций на эту тему. Одна из самых
распространенных рекомендаций выглядит так:
[ТестируемыйМетод]_[Сценарий]_[ОжидаемыйРезультат]
Такая схема неоптимальная, так как она заставляет сосредоточиться на
деталях имплементации вместо поведения системы. Простые фразы гораздо
лучше подходят для этой задачи. Простыми фразами можно описать
поведение системы в формулировках, которые будут понятны всем, в том
числе заказчику или аналитику:

28.

28
public class CalculatorTests
{
[Fact]
public void Sum_of_two_numbers()
{
double first = 10;
double second = 20;
var sut = new Calculator();
double result = sut.Sum(first, second);
}
}
Assert.Equal(30, result);
English     Русский Правила