Открыть список
Как стать автором
Обновить

Комментарии 38

все указанное работает с rails 3?
Да, на вторых давно ничего не пишу.
Вместо девочек лучше юзать fabrication — там есть генераторы, да и интерфейсы красивее. И не вижу Faker/Forgery — куда без них.
Ммм, fabrication и Forgery интересно, до этого пробовали машиниста, но откатились к девочкам, уж больно он тупой (мужлан:)
Ух ты, и правда, fabrication прикольный, спасибо за наводку!
Плюс про Faker как то забыли
Ага, и ещё Faker, конечно же. )
Почитал только что про fabrication. Сколь-нибудь заметных отличий от последних девочек не нашел. :-)
Еще autotest вместе с autotest-growl забыли, хотя это, конечно, по вкусу
Ребята, ну не все же сразу вываливать) Делитесь своими рецептами, очень интересно!
Ребята, ну не все же сразу) Делитесь своими рецептами, очень интересно!
то, что вы разобрались в таком количестве инструментов — заслуживает уважения. Думаю, можно было бы еще упомянуть faker (http://faker.rubyforge.org/rdoc/).
Только FFaker, на родителя забили уже давно.
Отличный материал, спасибо!
Пост в котором рельсовики делятся bdd-гемами [x]
Спасибо за статью. Обязательно прочитаю от начала и до конца!
(Немного самовнушения в этом деле не помешает :D)
Скажите, кто-то большой боевой проект реализовывал по всем правилам?
А то, почему-то обычно требуется делать Code Fast, а не Code Well.
Автоматизированное тестирование — это код фаст как раз. Просто научиться надо.
Интересно, сколько времени в процентах уходит на написание тестов при оптимальном покрытии, если научиться и делать быстро. Там ведь много кейсов)
Не засекал. Но могу сказать точно — однозначно быстрее, чем тестирование руками.
У нас большой боевой проект с покрытием около 80%, Code Fast без тестов заканчивается на первом же рефакторинге. Вообще нужно брать за правило, что чем больше взаимосвязей между сущностями приложения — тем больше должно быть покрытие (в данном проекте ERD-диаграмма похожа на карту метро Лондона)
И действительно, всё так просто.
НЛО прилетело и опубликовало эту надпись здесь
Спасибо за статью, сразу в избранное кинул.

Не хватает только инфы как тестировать что-то при условии что юзер залогинился в систему

Правда я в то время пользовался restful_authentication — и не смог прикрутить его к тестам, а сейчас перешел на authlogic.
Для того же Devise или Authlogic есть вспомогательные хелперы, которые можно отыскать на гитхабе. В общем случае можно просто зайти на страничку логина и ввести все данные, например, я использую следующий шаг в features/step_definitions/user_steps.rb:

Given /^I am signed in$/ do
  user = Factory(:user)
  visit new_user_session_path
  fill_in 'user[email]', :with => user.email
  fill_in 'user[password]', :with => user.password
  click_button I18n.t('formtastic.actions.enter')
  Then %{I should be on the home page}
  Then %{I should see "#{ I18n.t 'devise.sessions.user.signed_in' }"}
end
Про самое приятное забыл написать, всегда отрадно видеть нечто подобное:

$ rspec spec
...
Finished in 20.92 seconds
45 examples, 0 failures

$ cucumber
...
102 scenarios (102 passed)
986 steps (986 passed)
3m24.668s
«Иногда бывает так, что тест валится (бывает же)». Вообще философия BDD как раз и заключается в том, чтобы тест сначала валился, а уже потом все работало. То есть сначала описываем систему, ничего не работает, тесты все фейл и уже потом начинаем добавлять нужный функционал. Надо так же отметить, что нужно добавлять именно столько функционала, сколько нужно чтобы прошел тест. Улучшение кода, добавление, допиливание идет уже на фазе рефакторинга.
То есть получается триада:
— Тест фейл
— Тест пасс
— Рефакторинг
Да, совершенно верно, на этом BDD и основывается. Разработку я начинаю с написания фичи, которая, естественно, не проходит.

В данном случае подразумевается, что вроде и написал код, который должен удовлетворять какому-либо шагу фичи, но все равно что-то не так, и хочется посмотреть, что именно. Просто в начале я постоянно натыкался на что-то вроде «permission denied…» из-за того, что фича тестируется от «чистого» юзера, у которого нет ничего лишнего. В результате, если постоянно не проверяешь на какой странице находишься, то не понимаешь, почему же Capybara не видит поля для ввода, например.

Кстати, упрощенная версия шага "WTF?</>":

Then 'WTF?' do
  puts page.body
end
Согласен, отлично иллюстрирует процесс разработки на оснвое BDD, да и вся книжка, на мой взгляд, неплохая, всем советую почитать.
спасибо за ссылочку!
Спасибо за статью!
Правда у меня проблемка возникла, cucumber падает с сообщением:

superclass mismatch for class SQLite3Adapter

Хотя использую mysql и database_cleaner 0.6.0

Не сталкивались?
Накоецто обширная статья о разработке через тестирование, а то все говорят что это такое и как круто но никто не говорит как с этим делом работать, а до The RSpec Book руки пока не дошли.
Спасибо Вам и комментирующим за подборку гемов, с ними все понятно они все специализированны (Email, Mock'и, проверка структуры DOM и тд), но мне как еще только начинающему BDD'ить не очень понятна с точки зрения разработчика отличие между огруцом и RSpec. Я понимаю что на огурец поидеи смотрит заказчик и он написан на нативном языке а RSpec более программный, но поидеи то тестировать они могут одно и тоже? или должны одно и тоже? и если разное то что именно?
Да, тоже долго смущало. Но для себя я определил, что все дело в языке, в том, как описывается поведение системы. Конечно, что можно проверить на Cucumber, то же самое можно проверить и на RSpec, и наоборот. На самом деле каждый шаг огурца в конечном счете описывается на том же Ruby should'ами RSpec (в данном окружении).

В статье написал, что RSpec подходит больше для внутренностей, чего-то более приближенного к коду, что собственно рисунок выше и иллюстрирует. Слабо себе представляю фичу огурца «Функция foo должна возвращать bar при передаче ей baz», а вот сценарий поведения пользователя совсем другое дело.
Cucumber — для приемочного тестирования, RSpec – для модульного.
у меня story на русском были написаны, сейчас пример вытащу

Функционал: Админ может добавлять, удалять и изменять статьи
Что бы админ мог управлять статьями
Как администратор сайта
Я должен иметь возможность удалять, добавлять и изменять статьи
Как пользователь
Я должен видеть отредактированные статьи

Предыстория:
Допустим админ существует
И админ авторизован

Сценарий: добавление новой статьи
И видит список статей в админзоне
Если создать новую статью с заголовком "bbb" url "my-new-article" и телом "bla-bla-bla"
То увидим в списке статей заголовок "bbb"

Сценарий: редактирование существующей статьи
И существует статья с заголовком "bbb" url "my-new-article" и телом "bla-bla-bla"
Если admin редактирует статью "bbb" и сохраняет тело "no-blabla"
То пользователь должен увидить тело статьи "no-blabla" по адресу "/articles/my-new-article"

Сценарий: удалить существующую статью foo
И существует статья foo с url foo
И статья с url foo опубликована
Если админ удаляет статью с урл foo
То юзер в списке статей не видит статью "foo"


When /^admin edit article (.*) and save content (.*)$/ do |url, content|
visit edit_admin_article_url(Article.find_by_url(url))
fill_in 'article[body]', :with=>content
click_button "Сохранить статью"
response.should be_success
end

Given /^статья с url (.*) опубликована$/ do |url|
@article = Article.find_by_url(url)
@article.published.should be_true
visit "/articles/#{url}"
response.should be_success
end

When /^админ удаляет статью с урл (.*)$/ do |url|
delete admin_article_url(Article.find_by_url(url))
end

Then /^юзер в списке статей не видит статью "(.*)"$/ do |article|
visit "/articles"
assert_not_contain article
end

Given /^посетитель открывает страницу "([^\"]*)"$/ do |page|
visit page
end

When /^посетитель нажмет на ссылку "([^\"]*)"$/ do |link|
click_link link
end

Then /^посетитель нажмет на ссылку (.*)$/ do |link|
assert_contain link
click_link link
end
Then /^перейдет на страницу статьи (.*)$/ do |title|
@article = Article.find_by_title(title)
visit article_url(@article.url)
end
Given /^посетитель открывает страницу статей$/ do
visit articles_path
end
Then /^увидит полный текст "(.*)" статьи с названием (.*)$/ do |body, title|
assert_contain(body)
assert_contain(title)
end

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.