Лично для меня, довольно тертого разработчика, процесс внедрения TDD был непростым и местами тернистым.
Вкратце законспектирую, поскольку порог входа в тестирование действительно выше, чем просто сесть и писать код. Сделаю несколько, как написали бы пиндосы, highlights.
Теоретически процесс TDD должен выглядеть так:
1. Написали падающий тест, прогнали rspec, убедились что тест не проходит (красный)
2. Написали кусок кода, прогнали rspec, убедились что тест проходит (зеленый)
3. Отрефакторили, убедились что все хорошо и тесты не падают.
4. Отправили код в продакшн
Тестирование довольно медленно запускается само по себе, поэтому люди делают ухищрения: ставят spork, который держит инстанс приложения в памяти и экономит время при каждом запуске рельс. Уменьшение времени тестов на время запуска (у меня секунд 7-10) гарантировано.
Далее. То, что раньше делал autotest, сейчас модно делать с guard. Суть в том, что бы мониторить изменения файлов и запускать только те тесты, которых это изменение касалось. Довольно удобно, только не всегда ловит эти самые изменения. Так, например, изменение в factory не приведет к тестам, для этого я лишний раз дергаю измененный файл спека модели и, вроде как, поехало.
Раньше тестовые наборы данных хранились в YAML файлах и назывались фикстурами (fixtures). Каждый тест загружал фикстуры из файлов в базу, и, хотя, их можно было загружать выборочно, такая процедура была довольно медленной и ресурсоемкой. Ребята из thoughtbot решили данную проблему тем, что фикстуры стали генерить программно и назвали фабриками (factories). Фабрики действительно ощутимо быстрее и позволяют без проблем создавать связанные ассоциативные инстансы, изменяемые наборы данных (sequence), например, разные emailы пользователей и другие прикольные штуки. Сейчас все еще модно использовать FactoryGirl.
Все эти технологии также требуют наличия хорошего напильника. При чем, порой, если бы не стековерфлоу, я бы отчаялся применять TDD:
например: http://stackoverflow.com/questions/8303491/how-do-i-make-sure-the-helpers-and-models-reload-in-rspec-when-im-using-spork
=================================================
Само тестирование
Сейчас модно использовать RSpec, поскольку он лаконичнее и описательнее чем Test::Unit, который идет в комплекте с рельсами. Тесты в rspec называются спеками (от слова спецификация). Вроде само тестирование рельс сейчас тоже переехало на rspec, не знаю. Самый писк моды – приблизиться к человеческому языку, так что бы тесты были как бы метаописаниями, как бы объясняли на примерах как должен работать код. Чем меньше сам текст теста и чем он выразительнее, тем лучше. Мне в этом плане был очень близок cucumber (огурец). Сейчас rspec научился собой заменять cucumber чуть менее чем полностью.
Как сейчас водится, люди тестируют в трех направлениях.
1. Тесты моделей, или юнит-тесты
Здесь мы проверяем корректность методов в моделях, корректность валидаций.
validate_presence_of(:model) не идет в комплекте бойца с rspec, поэтому приходится ставить и подключать shoulda
gem "shoulda-matchers"
и далее в spec_helper.rb
require 'shoulda-matchers'
2. Тесты контроллеров, или как их еще называют, функциональные
Проверяются вещи, что бы create действительно создавал объект или рендерил 'new' и такое прочее
типовой тест будет включать в себя вызов контроллера
post :create, mymodel: param1
и проверку результатов. Например в assigns идет то, что должно присвоиться в методе контроллера
assigns(:mymodel){ should == MyModel.last }
проверяем, что отрендерится темплейт new. Это очевидно, но не интуитивно.
response.should render_template('new')
3. Интеграционные тесты, bdd истории
Это больше парафия Cucumber, однако, rspec в базе создает request/ папку, куда и помещаются интеграционные тесты
Мне очень нравится подход Cucumber тем, что происходит осмысление "зачем нужна эта фича" при каждом взгляде на тест, поскольку там собственно и написано "зачем". Но мы же знаем, что фичу можно сделать разными способами, главное, чтобы "зачем" осталось тем же самым.
Так вот, в базе интеграционный тест прогоняет цепочку действий при помощи эмуляции браузера.
Чаще всего что бы работала такая хрень подключаются gem capybara или webrat, которые собственно и делают эмуляцию браузера
Тестирование обычно выглядит так:
- заполнить поле 1 данными 1
- нажать княпу сабмит
- проверить, что на странице появились записи с данными 1
примерно такой код
visit services_path
page.should have_content("Сервис антивирусных")
visit и have_content нам достается из гема капибары.
Немного про то, что и как тестировать. Следует проверять пограничные случаи, например, если код должен создавать юзера, то проверьте это двумя тестами:
1. Юзер создается корректно, проверяем что в базке запись появилась.
2. Что мы действительно получаем ошибку, если юзер не создается корректно.
Комментариев нет:
Отправить комментарий