Как и обещал, я начинаю цикл статей, на тему RSpec.
В этой статье, я постараюсь, подробно рассказать, как писать тесты для моделей в Ruby on Rails. Если вы уже знакомы с rspec_on_rails, поправьте и дополните меня, если что то не так. Помните, что я изучаю Rspec вместе с вами и могу где то ошибаться.
Будем считать, что прочитав мою предыдущую статью, вы уже создали тестовый проект, сконфигурировали его и создали для него схему в базе, а так же установили gem rspec. Если нет, быстро делаем:
Теперь, давайте перейдем в каталог нашего проекта и выполним команду:
Теперь в корне нашего проекта, у нас есть директория spec. Можно создавать непосредственно тест для нашей модели, выполним:
Rspec автоматом создаст саму модель, fixtures и migrates для нее, а так же файл теста, следующего содержания:
Ну что, можно попробовать в первый раз прогнать все тесты, выполним:
Ой ой ой, не прошло. Rspec говорит:
Ну что же, выполним то что нас просят, но до этого, давайте немного подправим файл миграции, до такого состояния:
Теперь прогоним мигрейты и снова запустим тест:
и вуаля, наш тест успешно пройден(если у вас не так, пишите в комментариях, постараюсь помочь):
Точка в начале означает что тест пройден успешно, буква F означает что тест не пройден. Давайте теперь немного усложним наш пример. Изменим немного код:
После выполнения мы получим:
Ок, пока все правильно, нужно добавить в нашу модель валидацию:
Прогоняем еще раз, теперь все ОК. Тест прошел успешно.
Давайте отредактируем файл ~/spec/fixtures/post.yml:
Теперь изменим наш тест, до такого вида:
Таким образом мы подгрузили все фикстуры(fixtures :posts) и работаем с ними уже напрямую, вызывая их по символам(posts(:one)), указанным в posts.yml
На сегодня все, этого должно быть достаточно, что бы начать писать свои тесты для моделей.
В следующих статьях, я рассмотрю создание тестов для Контроллеров и Представлений.
В этой статье, я постараюсь, подробно рассказать, как писать тесты для моделей в Ruby on Rails. Если вы уже знакомы с rspec_on_rails, поправьте и дополните меня, если что то не так. Помните, что я изучаю Rspec вместе с вами и могу где то ошибаться.
Подготовка
Будем считать, что прочитав мою предыдущую статью, вы уже создали тестовый проект, сконфигурировали его и создали для него схему в базе, а так же установили gem rspec. Если нет, быстро делаем:
[sudo] gem install rspec
rails ./test -d mysql
nano ./test/config/database.yml
rake db:create
Теперь, давайте перейдем в каталог нашего проекта и выполним команду:
./script/generate rspec
Теперь в корне нашего проекта, у нас есть директория spec. Можно создавать непосредственно тест для нашей модели, выполним:
./script/generate rspec_model Post
Rspec автоматом создаст саму модель, fixtures и migrates для нее, а так же файл теста, следующего содержания:
require File.dirname(__FILE__) + '/../spec_helper' describe Post do before(:each) do @post = Post.new end it "should be valid" do @post.should be_valid end end
Пример простого теста
Ну что, можно попробовать в первый раз прогнать все тесты, выполним:
rake spec:models
Ой ой ой, не прошло. Rspec говорит:
You have 1 pending migrations: 20090302064129 CreatePosts Run "rake db:migrate" to update your database then try again.
Ну что же, выполним то что нас просят, но до этого, давайте немного подправим файл миграции, до такого состояния:
class CreatePosts < ActiveRecord::Migration def self.up create_table :posts do |t| t.string :name, :limit => 50, :null => false t.text :content t.timestamps end end def self.down drop_table :posts end end
Теперь прогоним мигрейты и снова запустим тест:
rake db:migrate
rake spec:models
и вуаля, наш тест успешно пройден(если у вас не так, пишите в комментариях, постараюсь помочь):
.
Finished in 0.040821 seconds
1 example, 0 failures
Точка в начале означает что тест пройден успешно, буква F означает что тест не пройден. Давайте теперь немного усложним наш пример. Изменим немного код:
it "should require name" do @post.name = nil @post.should_not be_valid @post.errors.on(:name).should_not be_nil end
После выполнения мы получим:
F
1)
'Post «should require name»' FAILED
expected valid? to return false, got true
./spec/models/post_spec.rb:10:
Finished in 0.045391 seconds
1 examples, 1 failure
rake aborted!
Ок, пока все правильно, нужно добавить в нашу модель валидацию:
validates_presence_of :name
validates_length_of :name, :within => 3..50
Прогоняем еще раз, теперь все ОК. Тест прошел успешно.
Использование Fixtures
Давайте отредактируем файл ~/spec/fixtures/post.yml:
one: id: 1 name: "this is ferst post" content: "tru la la, tra la la" two: id: 2 name: "this is second post" content: "tran tan tan, tra ta ta"
Теперь изменим наш тест, до такого вида:
require File.dirname(__FILE__) + '/../spec_helper' describe Post do fixtures :posts before(:each) do @post = Post.new end it "should require name" do @post.name = nil @post.should_not be_valid @post.errors.on(:name).should_not be_nil end it "clears post" do posts(:one).destroy lambda { posts(:one).reload }.should raise_error(ActiveRecord::RecordNotFound) end end
Таким образом мы подгрузили все фикстуры(fixtures :posts) и работаем с ними уже напрямую, вызывая их по символам(posts(:one)), указанным в posts.yml
На сегодня все, этого должно быть достаточно, что бы начать писать свои тесты для моделей.
В следующих статьях, я рассмотрю создание тестов для Контроллеров и Представлений.