Принципы создания
тестируемого кода
Илья Шишков
старший разработчик компании Яндекс
Что такое автотесты?
▌ Юнит-тесты
▌ Интеграционные тесты
▌ Функциональные тесты
▌ Нагрузочные тесты
и другие виды тестов, которые выполняются регулярно и
автоматически
4
Зачем нужны автотесты
Без использования автотестов
▌ Новый код тестируется вручную
▌ Нет регулярного контроля
регрессии
▌ Многие баги проявляют себя
только в продакшене
▌ Любой релиз может стать
большим стрессом
6
При использовании автотестов
▌ Большинство багов выявляется
во время разработки
▌ Регрессия выявляется сразу
после заливки кода в
репозиторий
▌ Значительно возрастает
надёжность кода
▌ Работать гораздо комфортнее
7
Отдельно про юнит-
тесты
│Юнит-тест – тест одной
функции или класса
отдельно от остальных
частей системы
Преимущества юнит-тестов
▌ Контролируют корректность нового и существующего кода
▌ Сокращают время между допущением ошибки и её
обнаружением
Преимущества юнит-тестов
▌ Являются примером применения кода
Преимущества юнит-тестов
▌ Документируют поведение
Преимущества юнит-тестов
▌ Упрощают поиск ошибок
Не все юнит-тесты
одинаково полезны
Хороший юнит-тест
▌ Короткий, простой и понятный
▌ Проверяет что-то одно
▌ Обладает минимумом внешних зависимостей
▌ Тестирует контракт без предположений о его реализации
› Контракт – публичный интерфейс, задекларированное
поведение, гарантия безопасности исключений, предусловия,
постусловия и т.д.
15
Не все пишут автотесты
Я не пишу тесты, потому что
▌ Мне некогда, у меня полно
важных задач
▌ Я пишу код без багов
▌ Код слишком запутан
▌ Мне лень
17
▌ Закон Деметры
▌ Внедрение зависимости
▌ Принцип одной ответственности
Закон Деметры
Закон Деметры Внедрение зависимости Принцип одной
ответственности
Закон Деметры
▌ Don’t look for things. Ask directly
what you need!
19
Название взято из проекта 80-х гг
«Деметра», который использовал
идеи аспектно-ориентированного и
адаптивного программирования.
Проект был назван в честь
Деметры, греческой богини
земледелия.
Википедия
Закон Деметры
▌ Разработать класс для логирования сообщений
▌ Сообщения должны сохраняться в файл
▌ Сообщения должны накапливаться в буфере и сохраняться в
файл, только когда он заполнился
▌ Кроме того, запись в файл должна производиться после
логирования каждого K-го сообщения
20
Закон Деметры
21
Закон Деметры
22
Закон Деметры
23
Закон Деметры
24
Закон Деметры
25
Закон Деметры
▌ Хороший юнит-тест тестирует контракт без предположений о его
реализации
› Контракт – публичный интерфейс, задекларированное поведение,
гарантия безопасности исключений, предусловия, постусловия и т.д.
26
Закон Деметры
27
Закон Деметры
28
▌ Don’t look for things. Ask directly what you need!
Закон Деметры
29
Закон Деметры
30
Закон Деметры
Преимущества:
▌ Явное декларирование
зависимостей
▌ Отсутствие лишних
зависимостей
▌ Упрощение повторного
использования кода
▌ Упрощение тестирования
31
Недостатки:
▌ Увеличение числа параметров
▌ Вызовы становятся более
громоздкими
Внедрение зависимости
Закон Деметры Внедрение зависимости Принцип одной
ответственности
Внедрение зависимости
Внедрение зависимости (англ. Dependency injection, DI) —
процесс предоставления внешней зависимости программному
компоненту. Является специфичной формой «инверсии
управления» (англ. Inversion of control, IoC), когда она
применяется к управлению зависимостями.
Википедия
33
Внедрение зависимости
34
Внедрение зависимости
35
Внедрение зависимости
36
Внедрение зависимости
37
Внедрение зависимости
38
Внедрение зависимости
39
Внедрение зависимости
40
Внедрение зависимости
Преимущества
▌ Зависимость от интерфейса, а
не от реализации
▌ Гибкость
▌ Высокая комбинируемость кода
▌ Упрощение повторного
использования кода
▌ Упрощение тестирования
41
Недостатки
▌ Перенос деталей реализации в
интерфейс
▌ Код разбивается на два слоя:
отдельные блоки и слой их
«склейки»
▌ Становится сложнее понять, как
работает программа целиком
Принцип одной
ответственности
Закон Деметры Внедрение зависимости Принцип одной
ответственности
Robert C. Martin
│A class should have only
one reason to change
Принцип одной ответственности
43
Принцип одной ответственности
44
Принцип одной ответственности
45
Принцип одной ответственности
46
Принцип одной ответственности
47
Принцип одной ответственности
48
Принцип одной ответственности
49
Принцип одной ответственности
50
Принцип одной ответственности
51
Принцип одной ответственности
Преимущества
▌ Код разбивается на простые для
понимания блоки
▌ Высокая комбинируемость кода
▌ Упрощение повторного
использования кода
▌ Упрощение тестирования
52
Недостатки
▌ Появление большого
количества блоков
▌ Становится сложнее понять, как
работает программа целиком
Итоги
Преимущества применения
автотестов и описанных принципов
▌ Повышение стабильности кода
▌ Уменьшение числа
зависимостей
▌ Упрощение рефакторинга
▌ Ускорение разработки
▌ Спокойный сон после релиза 53
Ссылки
› Guide:WritingTestable Code (http://misko.hevery.com/code-
reviewers-guide/)
› The Clean CodeTalks
(http://www.youtube.com/playlist?list=PLBDAB2BA83BB6588E)
› AllYourTests areTerrible...
(https://www.youtube.com/watch?t=2285&v=u5senBJUkPc)
54
Контакты
vk.com/ishfb
ishfb@yandex-team.ru linkedin.com/in/ishfb
Илья Шишков
Старший разработчик компании Яндекс

Илья Шишков, Принципы создания тестируемого кода

Editor's Notes

  • #3 Представиться О чём поговорим Вопросы в конце
  • #4 Регулярно и Автоматически CI Писать тесты тяжело Уходит много времени
  • #5 Хочу поделиться своим опытом
  • #6 Работал в разных командах Как работать без автотестов
  • #7 Сейчас есть CI Польза автотестов
  • #8 Доп. преим-ва
  • #9 Нет единого определения
  • #10 Контроль корректности Время обнаруж-я ошибки Проще и дешевле исправить ошибку Регулярно гонять тесты
  • #11 Актуально для шаблонов. Другой пример – большой класс
  • #15 Документир-е – легко понять Сложный тест никто не будет читать Ошибки в тестах Понятные имена Проще искать ошибки Тест падает, когда ломается SUT Иначе тратим время впустую Новая реал-ция вып-ет контракт – тесты не падают
  • #17  Опишу принцип Покажу пример Цель – покрыть тестами Неидеальный код
  • #21 Описать класс
  • #22 Реал-ция конструктора Почему передаём конфиг Большой конфиг У кого в проекте такой конфиг? BigBinaryData
  • #24 Большая настройка Суть теста не видна
  • #25 Мало что поменялось Зависимость от TConfig Зависимость от TBigBinaryData
  • #27 Забыли задать парам-ры конфига Исп-ем знание о реал-ции Перечислить все проблемы
  • #33 Сложная формулир-ка Вопрос, что такое DI
  • #35 Проговорить реал-цию ф-и
  • #36 Цель – протестировать контракт Когда не можем получить новости Звонок в Яндекс Не знаю, как сделать тест
  • #37 GetUrlHtml - зависимость
  • #39 Описать тест Без DI не могли С DI смогли Ф-я стала громоздкой
  • #42 Значение интуитивно
  • #45 Не видите кода - нестрашно
  • #47 Проблема – много кода
  • #49 У ф-и много ответств-тей Получили три ф-и У каждой 1 ответств-ть
  • #51 Каждую ф-ю тестируем отдельно Тесты короче Тесты гранулярнее
  • #53 Теперь вы знаете принципы Вам проще писать тесты Пишите тесты Преим-ва Повышение зарплаты