2.29M
Категория: ПрограммированиеПрограммирование

Тестирование astondevs.ru

1.

Тестирование
astondevs.ru

2.

Пирамида тестирования
Уровни тестирования:
Unit/module тестирование – тестируется
минимально-атомарный модуль программы, чаще
всего это одна функция или метод. Таких тестов
должно быть больше всего;
Интеграционное тестирование – несколько модулей
программы тестируются вместе;
Системное тестирование – Тестирование
выделенных ресурсов(системы);
Приемочное тестирование/Е2Е – Тестирование
соответствия системы ТЗ.

3.

Unit тесты
На этом уровне тестируют атомарные части кода. Это могут быть классы, функции или методы
классов.
Юнит тесты находят ошибки на фундаментальных уровнях, их легче разрабатывать и
поддерживать. Важное преимущество модульных тестов в том, что они быстрые и при изменении
кода позволяют быстро провести регресс (убедиться, что новый код не сломал старые части кода).
Тест на модульном уровне:
1.
Всегда автоматизируют.
2.
Модульных тестов всегда больше, чем тестов с других уровней.
3.
Юнит тесты выполняются быстрее всех и требуют меньше ресурсов.
4.
Практически всегда компонентные тесты не зависят от других модулей

4.

Интеграционные тесты
Проверят взаимосвязь модулей, которые проверяли на модульном уровне, с другой или другими
компонентами, а также интеграцию модулей с системой (проверка работы с ОС, сервисами и службами,
базами данных, железом и т.д.).
Интеграционное тестирование отличается от других видов тестирования тем, что он сосредоточен в
основном на интерфейсах и потоке данных (между модулями). Здесь приоритет проверки
присваивается интегрирующим ссылкам, а не функциям блока, которые уже проверены.

5.

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

6.

E2E/Приемочное тестирование
На этом уровне происходит валидация требований (проверка работы ПО в целом, не только по
прописанным требованиям, что проверили на системном уровне).
Проверка требований производится на наборе приемочных тестов. Они разрабатываются на
основе требований и возможных способах использования ПО.
Приемочные тесты проводят, когда (1) продукт достиг необходимо уровня качества и (2) заказчик
ПО ознакомлен с планом приемки (в нем описан набор сценариев и тестов, дата проведения и
т.п.).
Приемку проводит либо внутреннее тестирование (необязательно тестировщики) или внешнее
тестирование (сам заказчик и необязательно тестировщик).
Важно помнить, что E2E тесты автоматизируются сложнее, дольше, стоят дороже, сложнее
поддерживаются и трудно выполняются при регрессе. Значит таких тестов должно быть меньше.

7.

FIRST
F.I.R.S.T. — методология описания требованиий, которым должны отвечать тесты. Прежде всего,
модульные, но в принципе эти характеристики можно экстраполировать и на автоматические тесты.
Ее создатель — известный дядюшка Боб — автор многих практик программирования.
1.
Быстрота (Fast). Тесты должны быть быстрыми, медленные тесты никто не станет запускать. На их
проведение не хватит времени даже у команды из 30 тестировщиков.
2.
Независимость (Independent). Тесты должны быть независимы: ни один элемент не может
зависеть от исполнения предыдущего.
3.
Повторяемость (Repeatable). Вы должны иметь возможность запустить любой тест в любой
момент, и его поведение должно быть предсказуемо.
4.
Self-Validating Тесты сами себя проверяют, не надо руками ничего делать.
5.
Своевременность (Timely). Тесты должны быть написаны тогда, когда они действительно нужны.

8.

Философский вопрос на 1 балл
Зачем нужны юнит и интеграционные тесты?

9.

Зачем нам это брат?
Доказательство корректности кода
Автоматические тесты дают уверенность, что ваша программа работает как задумано. Такие тесты можно запускать многократно.
Успешное выполнение тестов покажет разработчику, что его изменения не сломали ничего, что ломать не планировалось.
Провалившийся тест позволит обнаружить, что в коде сделаны изменения, которые меняют или ломают его поведение.
Тесты как документация
Юнит-тесты могут служить в качестве документации к коду. Грамотный набор тестов, который покрывает возможные способы
использования, ограничения и потенциальные ошибки, ничуть не хуже специально написанных примеров, и, кроме того, его можно
скомпилировать и убедиться в корректности реализации.
Разработка через тестирование
При разработке через тестирование (test-driven development, TDD) вы сначала пишете тесты, которые проверяют поведение вашего кода.
При запуске они, конечно, провалятся (или даже не скомпилируются), поэтому ваша задача — написать код, который проходит эти
тесты.
Основа философии разработки через тестирование — вы пишете только тот код, который нужен для прохождения тестов, ничего
лишнего. Когда все тесты проходят, код нужно отрефакторить и почистить, а затем приступить к следующему участку.
Возможность лучше разобраться в коде
Когда вы разбираетесь в плохо документированном сложном старом коде, попробуйте написать для него тесты. Это может быть
непросто, но достаточно полезно, так как:
• они позволят вам убедиться, что вы правильно понимаете, как работает код;
• они будут служить документацией для тех, кто будет читать код после вас;
• если вы планируете рефакторинг, тесты помогут вам убедиться в корректности изменений.

10.

Вопрос на 1 балл
Мы определились, что unit тесты позволяют протестировать один
отдельный модуль(класс), что делать, если у класса есть
зависимость на другой класс?

11.

Test doubles/стабы/моки/фальшивки
Классы редко являются обособленными, чаще всего у классов есть зависимости на другие
компоненты (сервису нужен репозиторий и тд).
Как же в таком случае писать unit тесты? На помощь приходят test doubles.
Согласно Martin Fowler's article, существуют следующие фальшивки:
1.
Dummy объекты используются для заполнения списка параметров.
2.
Fake объекты имеют “рабочую” имплементацию, но не достаточную для использования в проде
(на пример in memory бд).
3.
Stubs объекты обеспечивают жестко зашитый ответ на вызовы во время тестирования, т.е.
в таком объекте мы хард кодим ответ для методов, которые нам нужны для теста.
4.
Spies те же stubs*, но могут сохранять информацию о том, когда и как были вызваны.
5.
Mocks объекты, которые настраиваются (например специфично каждому тесту) и позволяют
задать ожидания в виде своего рода спецификации вызовов, которые мы планируем получить.
* В контексте Mockito, spy это реальный бизнес объект, т.е. Spy по сути прокся над реальным
объектом.

12.

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

13.

JUnit
Итак, официальный сайт начинает с того, что сообщает нам о новом строении JUnit:
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage (← офф.сайт).
JUnit Platform — фундаментальная основа для запуска на JVM фреймворков для тестирования.
Платформа предоставляет TestEngine API, для разработки фреймворков (для тестирования), которые
могут быть запущены на платформе. Кроме этого, в платформе имеется Console Launcher для запуска
платформы из коммандной строки а также для запуска любого JUnit 4 Runner'а на платформе. Уже,
кстати, есть плагины для Gradle и Maven.
JUnit Jupiter — сердце JUnit 5. Этот проект предоставляет новые возможности для написания тестов и
создания собственных расширений. В проекте реализован специальный TestEngine для запуска тестов
на ранее описанной платформе.
JUnit Vintage — поддержка легаси. Определяется TestEngine для запуска тестов ориентированных на
JUnit 3 и JUnit 4.

14.

Аннотации
@Before обозначает методы, которые будут вызваны до исполнения теста, методы должны быть public void. Здесь обычно
размещаются предустановки для теста, в нашем случае это генерация тестовых данных (метод setUpToHexStringData).
@BeforeClass обозначает методы, которые будут вызваны до создания экземпляра тест-класса, методы должны быть public static
void. Имеет смысл размещать предустановки для теста в случае, когда класс содержит несколько тестов использующих
различные предустановки, либо когда несколько тестов используют одни и те же данные, чтобы не тратить время на их создание
для каждого теста.
@After обозначает методы, которые будут вызваны после выполнения теста, методы должны быть public void. Здесь размещаются
операции освобождения ресурсов после теста, в нашем случае — очистка тестовых данных (метод tearDownToHexStringData).
@AfterClass связана по смыслу с @BeforeClass, но выполняет методы после теста, как и в случае с @BeforeClass, методы должны
быть public static void.
@Test обозначает тестовые методы. Как и ранее, эти методы должны быть public void. Здесь размещаются сами проверки. Кроме
того, у данной аннотации есть два параметра, expected — задает ожидаемое исключение и timeout — задает время, по истечению
которого тест считается провалившимся.
@Ignore. Также, если поместить эту аннотацию на класс, то все тесты в этом классе будут отключены.

15.

Mockito
Mockito — фреймворк для тестирования приложений, который позволяет легко и быстро подменять
реальные объекты программы на МОКи.
Инструмент упрощает разработку юнит-тестов для классов с внешними зависимостями. Фиктивная
реализация интерфейса, статического метода или класса, которую производит Mockito, позволяет
определить вывод конкретных вызовов методов: фиктивные классы записывают взаимодействие с
системой, а тесты могут его проверить и подтвердить.

16.

17.

Что почитать
https://www.vogella.com/tutorials/JUnit/article.html - JUnit
https://dzone.com/articles/7-popular-unit-test-naming - Конвенции по именованию тестов
https://www.vogella.com/tutorials/Mockito/article.html - Mockito
https://www.baeldung.com/mockito-behavior - Как задавать поведение в Mockito
https://www.baeldung.com/mockito-verify - Что можно проверять в Mockito
English     Русский Правила