перевод Test Driven Development in Ionic 2: An Introduction to TDD

Концепция создания автоматизированных тестов во время разработки позволяет значительно улучшить качество кода, защитится от ухудшения кода при обновлениях и ускорить процесс тестирования и отладки.

Существует несколько типов тестов:

  • Юнит тесты (Unit test) которые тестируют отдельные небольшие куски кода
  • Интеграционные тесты которые тестируют связи между отдельными компонентами
  • End-to-end тесты которые проверяют функциональность приложений в различных реалистичных сценариях поведения

Существуют множество других типов тестов. Один из базовых подходов к тестирования заключается в добавлений тестов после того как код уже был создан, что бы убедиться что он делает то, что должен. Другой подход и возможно более оптимальный заключается в создание тестов, прежде чем писать код. Общий процесс заключается в том что сначала пишется тест который проверяет то что код должен делать, а затем пишется код, до тех пор пока не удовлетворится условия теста. Этот подход называется «Разработка через тестирование» Test Driven Development (TDD).

Некоторые преимущества подхода TDD:

  • ненужно отдельно создавать тесты
  • тестовое покрытие будет достаточно высоким так как не будет код без тестирования
  •  такой подход заставить прежде чем реализовывать планировать функционал который будет выполнять ваш код
  • поэтому проблемы логики выполнения могут быть решены еще прежде реализацией кода

Мне нравится идея разработки через тестирования , но мне пришлось потратить какое то время прежде чем я смог понять как его реально использовать. Каким должен быть мой первый тест? Какие тесты мне понадобятся дальше? Сколько тестов мне нужно будет прежде чем начинать писать приложение? Мне помог разобраться со всем этим Adam Wathan (https://adamwathan.me/) и видео Misko Hevery (https://www.youtube.com/watch?v=XcT4yYu_TTs) Их контент не связан напрямую с Ionic и Angular но базовые концепции помогли мне применить на практике подход к разработки через тестирование (TDD).

Далее я расскажу о примерах использования подхода TDD. Мои примеры будут достаточно простые так как мне еще самому много придется о TDD.

Тестирование является одной из таких вещей, где нет одного «верного» пути. Конечно же есть некоторые советы и рекомендации о тестирование но их так много и они настолько разные а иногда даже противоречащие друг другу, что не всегда следует слепо следовать всем советам.

Если вы новичок в тестирование то просто следуйте тому что я буду описывать далее. Так как ваши тесты все таки отделены от приложения то не нужно бояться что они что то сломают и все такие любой вид тестирования лучше чем отсутствия любых тестов вообще.

До того как начать создавать приложение на Ionic 2 я расскажу о некоторых базовых концепциях.

Введение в модульное тестирование

Перед тем как создавать приложение с использование TDD вы должны знать как писать модульные тесты для Angular 2 или Ionic 2 приложений. Если вы не знаете как это делать почитайте мои предыдущие заметки:

How to Unit Test an Ionic 2 Application (Basic)

Introduction to Testing Ionic 2 Applications with TestBed (Advanced)
перевод Введение в тестирование приложений Ionic 2 с помощью TestBed

Разработка через тестирование (TDD) против разработки на основе поведения (BDD)

Я не буду строго придерживаться только TDD, я буду использовать смесь TDD и BDD. Разница между этими двумя подходами достаточно тонка и не очевидна.

Оба эти подхода основывается на идеи что вначале пишутся тесты а затем код. В общем последовательность процесса заключается в следующем:

  1. Пишутся тесты
  2. Проверяется запуск тестов (естественно все они должны быть fail)
  3. Пишется код удовлетворяющий эти тесты, далее снова запускаются тесты (в этом случае они должны вернуть pass).
  4. Рефакторится код, если не обходимо

Я не буду описывать более подробно разницу между TDD и BDD. Если сказать в общем, то тесты с использованием TDD более изоляционны и более сосредоточены на внутренней работе кода (подразумевается что создатель тестов знает как устроен код). Тесты на основе BDD рассматривают код как черный ящик и только концентрируются на результатах работы кода а не как этот результат достигается.

Пример теста на основе TDD может выглядеть так:

в то время как на BDD этот тест будет примерно так:

Оба эти теста делают одно и тоже, но при подходе TDD подразумевается знание внутренней структуры кода, в то время как при BDD тестируется только поведение.

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

1. Генерируем новое приложение Ionic 2

Создадим новое приложение командой:

2. Настройка тестирования

Команда Ionic планирует добавить модульное тестирование по умолчанию, но пока этого нет нам будет нужно настроить тестирование.

Я уже описывал необходимые настройки модульного тестирования для Ionic 2 Введение в тестирование приложений Ionic 2 с помощью TestBed, вам не обязательно читать руководство целиком, вам нужна секция 2. Set up Testing

3. Приложение

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

4. Первый тест

Так как мы используем TDD подход то нам надо начать с написание первого теста.
Выбор первого теста достаточно сложный процесс. Одним из вариантов может быть определение базового функционала приложения.

В нашем случае хорошим началом может стать создания теста на проверку списка продуктов. Это достаточно простой тест и он сразу будет проверять базовый функционал нашего приложения. В Ionic 2 так же хорошим началом может быть тест для корневого компонента который является точкой входа в приложение.

5. Тестирование корневого компонента

Как я заметил раннее корневой компонент является точкой входа в программу, поэтому нам надо убедится что это функционирует как подразумевается. Поэтому первым делом проверим отображение страницы Product

Создайте файл src/app/app.spec.ts со следующем содержанием:

Если вам не понятно что этот код делает вам нужно почитать эту статью Введение в тестирование приложений Ionic 2 с помощью TestBed

В первом тесте «is created» мы проверяем успешно ли создан компонент (мы будем тестировать это в каждом тесте).
Во втором мы проверяем что переменная rootPage имеет значение ProductPage. Если вы сейчас запустите тест командой:

вы увидите следующую ошибку:

Так и должно быть! Так как мы следующем методике TDD то мы с начало делаем тест а уже потом функционал.

Прямо сейчас тест не прошел так как компонента ProductPage еще не существует.

Запустите следующую команду для генерации страницы Product:

Измените файл src/app/app.module.ts следующим образом:

И снова запустите тест:

Результат будет другой:

 

Страница Product теперь импортируется, но тест не проходит потому что переменная rootPage не имеет значения ProductPage. Сейчас он имеет значение по умолчанию HomePage. Изменим корневой компонент.

Измените src/app/app.component.ts следующим образом:

И если сейчас запустить тест то результат будет такой:

Ура! Мы прошли тест. То что мы сделали это продемонстрировали принцип TDD. С начало мы создали провальный тест, в котором проверяли функционал которого еще не было. А потом реализовали этот функционал, так что бы тест был успешным.

6. Тестируем страницу Product

Теперь перейдем к более интересному тесту. Будем проверять отображаются ли продукты пользователю.

Создайте файл src/pages/product/product.spec.ts со следующим содержанием:

Настройки у этого теста точно такие же как у предыдущего теста но сам тест более интересный. Мы получаем ссылку на первый элемент с классом ‘.ion-item’ в нашем шаблоне и проверяем содержит ли он соотвествующие данные из первого элемента списка продуктов (которых еще не существует)

Если мы запустим тест то увидем нечто похожее:

Что бы продолжит далее нам нужно создать сервис возвращающий продукты.

7. Тестируем сервис продуктов

Создайте провайдера следующей командой:

Изменитие  src/app/app.module.ts:

Создайте src/providers/products.spec.ts со следующим содержанием:

Этот тест позволит проверить, существует ли массив продуктов в качестве переменной и содержит ли он данные. Если сейчас запустим тест то увидем следующее:

Мы пытаемся получить доступ к свойству length но его еще не существует. Изменим наш сервис.

Измените файл src/providers/products.ts:

Если сейчас запустить тест то увидем следующее:

8. Снова тестироуем страницу Product

Так как мы создали сервис Products вернемся к странице Product. Ошибку которую мы сейчас исправим выглядить так:

Тест не проходит потому что у нас в тестах нет провайдера NavParams, он он нам и не нужен он подключается по умолчанию при герерации страницы. Давай те удалим его.

Изменим файл src/pages/product/product.ts:

и если снова запустить тест то увидем следующее:

Теперь ошибку будет в том что мы не можем получить доступ к свойству nativeElement. Это из-за следующего кода:

de = fixture.debugElement.query(By.css(‘ion-list ion-item’));
el = de.nativeElement;
Мы пытемся получить доступ к переменной из шаблона, но мы еще не реализовали эти переменные в шаблоне страницы.

Измените файл src/pages/product/product.html:

Теперь наш тест должен показать что то типа такого:

Теперь наша ошибка заключается в том что свойство products не определенно.

Измените файл src/pages/product/product.ts:

теперь тест должен вернуть:

Это интересная ошибка. В тесте мы проверяем существование переменных title, price, and description для первого продукта из списка продуктов products. Но мы забыли включить description в шаблон! Естественно я сделал то специально, что бы показать что если вы что то забудете то тест сам подскажет это.

Измените файл src/pages/product/product.html:

Теперь результат тестов будет:

 

Теперь все тесты проходят. Это означает что мы добавили новые функционал в наше приложение и наш код работает как ожидается. Если в будущем мы что то изменим из функционала и что то сломается то мы сразу сможем это увидеть через тесты.

Заключение

Использование подхода TDD может показать утомительным, и очевидно трубует больше времени для кодирование. Но очевидно у вас будет меньше ошибок и после завершиния проекта у вас уже будут все необходимые тест. И вслучае необходимости вернутся к проекта через какое время у уже будет инструмент контроля за функционалом проекта. Что может значительно сэкономит на данном этапе.

 

 

It's only fair to share...Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedInShare on VK

2 thoughts on “Разработка через тестирование в Ionic 2: Рассказ о TDD

  1. Great post. I was checking constantly this blog and I’m impressed!
    Very helpful information specially the last part :
    ) I care for such info much. I was looking for this certain information for a very long time.

    Thank you and good luck.

Comments are closed.