Заполнение базы данных тестовыми данными при помощи seed-fu

декабря 24, 2011  |  Published in Ruby on Rails, Тестирование  |  6 Comments

Я отношусь к тойкасте людей, что не воспринимают интеграционные тесты. Программа не может оценить внешний вид приложения так, как то может сделать человек. По этой причине я предпочитаю сам смотреть на то, как выглядит приложение. Для того, чтобы это изучение приложения было максимально приближена к реальности — необходимо заполнять базу тестовыми данными, кроме того, тестовые данные необходимы для тестирования производительности приложения на «реальных» данных. В Rails имеется встроенный механизм seed-ирования базы данных, однако он мне не очень нравится и в этой статье я рассказывать о нем не буду. Вместо встроенного функционала я предпочитаю использовать seed-fu — отличное решение поставляемое в виде совсем обыкновенного gem’а, которое делает заполнение БД тестовыми данными более удобным.

Установка seed-fu

Rails 3.1:

#Gemfile
gem 'seed-fu', '~> 2.1.0'

Поддержка Rails 3.x начиная с версии 2.0.

$ bundle install

Использование

По умолчанию файлы с фикстурами seed-fu хранятся в директории  db/fixtures/. Файлы фикстур seed-fu являются файлами с обыкновенным Ruby кодом, вместо YAML используемого в стандартных Rails фикстурах. Соглашения по именованию файлов нет, по этому можете назвать их, например pechenka.rb, но я предпочитаю хранить фикстуры для каждой модели в отдельных файлах с именами моделей к которым те относятся, например vacancies_fixture.rb.

Для того, чтобы описанные фикстуры загрузились в БД достаточно просто выполнить Rake-задачу:

$ rake db:seed_fu

Давайте рассмотрим примеры создания фикстур.

Традиционный способ, знакомый нам из ActiveRecord — блочной формы использования методов new или create:

Post.seed do |post|
  post.id         =  1
  post.title      = "Very intregant title"
  post.content    = "Lorem ipsum dolor sit amet ..."
  post.user_id    = 1
  post.created_at = DateTime.now
end

User.seed do |user|
  user.id         = 1
  user.name       = "Vladimir Melnick"
  user.login      = "vladimir"
  user.password   = "123456"
  user.created_at = DateTime.now
end

Для создания нескольких записей выгоднее использовать следующий синтаксис:

Post.seed(:id,
  {:id => 1, :title => "title1", :content => 'content1', :user_id => 1, :created_at => DateTime.now }
  {:id => 2, :title => "title2", :content => 'content2', :user_id => 1, :created_at => DateTime.now }
  {:id => 3, :title => "title3", :content => 'content3', :user_id => 2, :created_at => DateTime.now }
  {:id => 4, :title => "title4", :content => 'content4', :user_id => 3, :created_at => DateTime.now }
)

User.seed(:id,
  {:id => 1, :name => "Super User", :login => "blahblah", :password => "123456", :created_at => Datetime.now}
  {:id => 2, :name => "Super User", :login => "blahblah", :password => "123456", :created_at => Datetime.now}
  {:id => 3, :name => "Super User", :login => "blahblah", :password => "123456", :created_at => Datetime.now}
)

Для создания нескольких сотен или тысяч «уникальных» записей я использую следующую технику:

post_contents = [...]
post_titles   = [...]
user_names    = [...]
user_emails   = [...]
#...
100.times do
  Post.seed do |post|
    post.title = titles[rand(post_titles.size - 1)]
    post.content = contents[rand(post_contents.size - 1)]
    #...
  end

  User.seed do |user|
    #...
  end
end

Ссылки

Приятного вам программирования!

Tags: , , ,

Responses

  1. tankard says:

    декабря 24, 2011 at 14:55 (#)

    А чем такой подход отличается от создания rake задачи с гемом Faker?

    99.times do |n|
      name = Faker::Name.name
      email = "example-#{n+1}@example.org"
      password = "password"
      User.create!(:name => name,
                   :email => email,
                   :password => password,
                   :password_confirmation => password)
    end
    
  2. says:

    декабря 24, 2011 at 15:17 (#)

    Жуткий синтаксис

    Есть factory_girl, fabricator — там все изящнее

  3. admin says:

    декабря 24, 2011 at 17:52 (#)

    Михаил, FactoryGirl, если я не путаю исключительно для тестов годится, а с seed-fu я забиваю БД произвольным количеством записей.

  4. admin says:

    декабря 24, 2011 at 17:54 (#)

    tankard, да в принципе ни чем, Faker несколько удобней будет, ведь он, вроде как сам генерит данные, но у меня как-то не сложилось с ним поработать. Нужно будет попробовать.

  5. says:

    декабря 24, 2011 at 19:57 (#)

    Владимир, да им без разницы — в каком окружении запустишь, в таком и будут базу заполнять :)

  6. wildDAlex says:

    июня 10, 2012 at 21:10 (#)

    В синтаксисе создания нескольких записей забыта запятая.

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.