2015-03-07 03 Сергей Александрович. 50 оттенков красного
TRANSCRIPT
![Page 1: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/1.jpg)
50 оттенков красногоИли тестирование без боли
Сергей Александрович, @darth_sim
![Page 2: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/2.jpg)
Немного о себеМеня зовут СергейЯ разрабатываю backend у Злых МарсианЯ люблю писать тесты
![Page 3: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/3.jpg)
Сегодня мы:Поговорим о том, зачем мы пишем тесты;Уменьшим объем тестов без потери качества;Уменьшим время написания и цену тестов;Упростим поддержку.
![Page 4: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/4.jpg)
DisclaimerСпорить о тестах можно много и долго. Все сказанное
здесь - мое мнение, основанное на личном опыте
![Page 5: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/5.jpg)
Спонсор многих слайдов
![Page 6: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/6.jpg)
Почему нужно писатьтесты?
![Page 7: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/7.jpg)
Почему нужно писать тесты?Чтобы беречь свое время при разработке;
Факт от Капитана: автоматические тесты выполняются напорядок быстрее ручных.
![Page 8: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/8.jpg)
Почему нужно писать тесты?Чтобы беречь свое время при разработке;Чтобы не бояться что-то сломать;
Факт от Капитана: Все делают ошибки. Кто не делаетошибок, тот нагло врет.
![Page 9: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/9.jpg)
Почему нужно писать тесты?Чтобы беречь свое время при разработке;Чтобы не бояться что-то сломать;Чтобы держать архитектуру приложения в форме.(касается в основном unit-тестов)
![Page 10: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/10.jpg)
Почему нужно писать тесты?Тесты - это взгляд на код со стороны.
Код сложно тестировать? ⬇
Код сложен, запутан ⬇
Код нуждается в рефакторинге
![Page 11: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/11.jpg)
Почему иногда мы не пишемтесты?
Потому что часто тесты выглядят вот так:
![Page 12: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/12.jpg)
Пора навести порядок!
![Page 13: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/13.jpg)
Test coverage
![Page 14: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/14.jpg)
Test coverageОднажды программист спроcил Великого
Мастера: «Какого покрытия тестами я должендостичь?»
goo.gl/NH84c6
![Page 15: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/15.jpg)
Test coverageНе дает никакого представления о том, насколькохорошо протестирован код;Показывает, какие места точно не протестированы, ноне наоборот;Не дает никакого представления о качестве кода;Не та метрика, за которой стоит гнаться.
![Page 16: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/16.jpg)
Test coverage100% не стоит вашего времени;90% — это очень хорошее покрытие;70% вполне достаточно.
![Page 17: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/17.jpg)
Test coverage“Мне платят за код, который работает, а не затесты, поэтому моя философия заключается в
том, чтобы тестировать настолько мало,насколько это возможно для достижения
нужного уровня уверенности„(Кент Бек)
![Page 18: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/18.jpg)
Выбрасываем лишнее
![Page 19: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/19.jpg)
Выбрасываем лишнееТесты некритичного кода
Если ошибка в коде не повлечет за собой серьезныхпоследствий, то тестирование этого участка кода совсем
не обязательно.
![Page 20: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/20.jpg)
Выбрасываем лишнееТесты поведения сторонних библиотек
Большинство библиотек уже протестированыразработчиком;Если вас не устраивает, как они протестированы, лучшесделать контрибьют, чем держать тесты у себя.
![Page 21: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/21.jpg)
Выбрасываем лишнееКосвенно выполненные проверки
Проверка на наличие классов и методов;Проверка количества аргументов функций;Проверка на отсутствие исключений.Иногда такие проверки необходимы, но такие случаиредки.
![Page 22: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/22.jpg)
Выбрасываем лишнееТесты приватных методов
Приватные методы проверяются тестами открытыхметодов, в которых они вызываются
![Page 23: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/23.jpg)
Выбрасываем лишнееТесты тривиального кода
“Если я не делаю ошибок какого-то рода, я нетестирую код на их наличие„
(Кент Бек)
![Page 24: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/24.jpg)
Приводим оставшееся впорядок
![Page 25: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/25.jpg)
Приводим оставшееся в порядок“Пишите код так, как будто сопровождатьего будет склонный к насилию психопат,
который знает, где вы живёте„(Мартин Голдинг)
Верно и для тестов.
![Page 26: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/26.jpg)
Используйте говорящие именатестов
Тест — это спецификация с функцией самопроверки. Поназванию теста должно быть понятно, что конкретно он
проверяет.
![Page 27: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/27.jpg)
Используйте говорящие именатестов
Bad:
it 'works' do # ... end
Good:
it 'sends email to the user' do # ... end
![Page 28: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/28.jpg)
Используйте говорящие именатестов
Если фреймворк не позволяет в полной мере описать тестс помощью имени, напишите комментарий
# Sends email to the user def test_send_message # ... end
![Page 29: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/29.jpg)
Один тест - одна проверкаПо выводу тестового фреймворка должно быть понятно,
какие конкретно действия выполняются не так, какожидалось.
![Page 30: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/30.jpg)
Один тест - одна проверкаBad:
it 'creates message and sends it to the user via email' do # ... end
Good:
it 'creates message' do # ... end
it 'sends message to the user via email' do # ... end
![Page 31: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/31.jpg)
Один тест - одна проверкаАналогично для фреймворков без возможности подробно
описать тест
# Creates message def test_send_message__message_creation # ... end
# Sends message to user def test_send_message__message_sending # ... end
![Page 32: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/32.jpg)
Один тест - одна проверкаНекоторые фреймворки позволяют писать комментарии к
проверкам. В таком случае разделение не так важно.Пример для testify (go):
// Creates message func Test_sendMessage(t *testing.T) { // ... assert.Equal(t, expected, actual, "Should create message") // ... assert.Equal(t, expected, actual, "Should send message to user via email") // ... }
![Page 33: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/33.jpg)
Используйте контекстыЕсли фреймворк позволяет задавать контекст
тестирования — пользуйтесь этой возможностью
![Page 34: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/34.jpg)
Используйте контекстыBad:
it 'creates message when user is signed in' do sign_in(user) # ... end
Good:
context 'when user is signed in' do before { sign_in(user) }
it 'creates message' do # ... end end
![Page 35: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/35.jpg)
Используйте контекстыЕсли фреймворк не поддерживает контексты, можно опять
обратиться к комментариям
# = When user is signed in ============================== # Creates message def test_send_message__signed_in__message_creation # ... end # = end When user is signed in
![Page 36: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/36.jpg)
Правильные ожиданияПравильно подобраное ожидание - половина написанного
теста.
![Page 37: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/37.jpg)
Правильные ожиданияПримеры хороших ожиданий:
Возвращаемое значение;Изменения состояния класса, видимого извне;Внешнее воздействие a.k.a. side effect;Обращение к сторонним объектам.
![Page 38: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/38.jpg)
Правильные ожиданияПримеры плохих ожиданий:
Изменения внутренних переменных класса;Изменение состояния хранилища, используемого дляхранения состояния тестируемого объекта;Вызовы приватных методов.
![Page 39: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/39.jpg)
Правильные ожиданияBad:
it "puts provided value to redis" do subject.set("the value") expect(REDIS.get("the key")).to eq("the value") end
Good:
it "saves provided value" do subject.set("the value") expect(subject.get).to eq("the value") end
![Page 40: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/40.jpg)
Правильные ожиданияСтарайтесь максимально абстрагироваться от реализации
метода и сосредототочиться на результате
![Page 41: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/41.jpg)
Mocks & stubsПалка о двух концах:
Помогают достичь нужного уровня изоляции;При злоупотреблении могут сделать тест бесполезным.
![Page 42: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/42.jpg)
Mocks & stubsХорошие кандидаты:
Передаваемые на вход объекты;Сетевые службы;Функции с трудно прогнозируемым или трудновыводимым результатом, используемые в тестируемомметоде.
![Page 43: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/43.jpg)
Mocks & stubsНужно очень осторожно подходить к стабу БД.
Если не уверены на 100%, не делайте этого
![Page 44: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/44.jpg)
Работа с внешними связямиСитуация №1:
Функция foo объекта A (A.foo) проводит вычисления сосложной логикой, основываясь на результатах функцииbar объекта B (B.bar);B.bar в свою очередь тоже проводит вычисления сосложной логикой.
Необходимо протестировать метод A.foo
![Page 45: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/45.jpg)
Работа с внешними связямиВариант решения №1:
Написать тест, учитывающий логику функции B.bar.
Нарушение DRY, повторное тестирование B.bar,тестирование логики, не относящейся к тестируемому
методу
![Page 46: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/46.jpg)
Работа с внешними связямиВариант решения №2:
Создать условия для получения заранее известногорезультата B.bar, использовать этот результат для
тестирования A.foo.
Тест становится зависимым от логики B.bar.Изменение логики стороннего метода сломает тест.
![Page 47: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/47.jpg)
Работа с внешними связямиВариант решения №3:
Сделать stub B.bar с известным результатом,использовать этот результат для тестирования A.foo.
Тест не зависит от логики B.bar
![Page 48: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/48.jpg)
Работа с внешними связямиПроблема варианта №3: Изменение интерфейсафункции B.bar сломает код, но оставит тест ложно
положительным.
Решение: Это тот самый случай, когда чистый прогонфункции с проверкой на отсутствие исключений имеет
место быть.
![Page 49: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/49.jpg)
Работа с внешними связямиСитуация №2:
Метод foo объекта A (A.foo) проводит вычисления сосложной логикой и затем вызывает метод bar объекта B(B.bar);B.bar в свою очередь тоже реализует сложную логику.
Необходимо протестировать метод A.foo
![Page 50: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/50.jpg)
Работа с внешними связямиВариант решения №1:
Проверить side effect метода B.bar, учитывая его логику.
Нарушение DRY, повторное тестирование B.bar,тестирование логики, не относящейся к тестируемому
методу
![Page 51: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/51.jpg)
Работа с внешними связямиВариант решения №2:
Проверить некоторую неизменную часть side effect'аметода B.bar, не зависящую от его логики. Пример: mailer
отправляет письмо с неизменным заголовком.
Тест не зависит от логики B.bar. Изменениеинтерфейса B.bar будет обнаружено сразу.
![Page 52: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/52.jpg)
Работа с внешними связямиВариант решения №3:
Сделать stub B.bar, проверить факт его вызова послевыполнения A.foo.
Тест не зависит от логики B.bar
Имеет ту же проблему и аналогичное решение, что ивариант решения №3 предыдущей ситуации.
![Page 53: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/53.jpg)
Гораздо лучше!
![Page 54: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/54.jpg)
Поддерживаем порядок
![Page 55: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/55.jpg)
Составьте договоренностиЕсли работаете в команде, составьте styleguide для тестов,
хотя бы на словах. Это существенно снизит порогвхождения в чужие тесты.
![Page 56: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/56.jpg)
Test first!“Не доверяй тесту, который ты не видел
упавшим„(народная мудрость)
![Page 57: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/57.jpg)
Почему test first?Если строить код на основе тестов, то у вас практическине возникнет проблем с тестируемостью;Хорошо организованные тесты позволяют продумать иописать структуру кода до реализации.
![Page 58: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/58.jpg)
Почему test first?Главный аргумент
Не зная точной реализации, вы будете вынужденытестировать только интерфейс, что и требуется
![Page 59: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/59.jpg)
Test firstПеред написанием тестов, постройте дерево с помощью
контекстов. Постарайтесь отобразить все возможныеварианты развития событий.
![Page 60: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/60.jpg)
ИтогиНе гонитесь за test coverage;Не будьте параноиком, определите для себя, что нужнотестировать;Описывайте тесты так, чтобы другой человек мог понятьтестируемый функционал;Тестируйте интерфейс, а не реализацию;Делайте unit-тесты независимыми от функционаладругих классов/методов;Используйте тесты как спецификацию для вашего кода;
![Page 61: 2015-03-07 03 Сергей Александрович. 50 оттенков красного](https://reader034.vdocuments.site/reader034/viewer/2022051315/55a7b3c21a28abcd168b4624/html5/thumbnails/61.jpg)
СпасибоВопросы?