-
Notifications
You must be signed in to change notification settings - Fork 3
このgemはrailsでの開発中に感じたfixturesに関する多数の不満を一括して解決するために作られました。 主な理由はfixtureの編集のしずらさと、動的なデータの扱いのしづらさですが、細かい不満点は挙げていくとキリがないので、ここでは飛ばすとして、実際に一つの案件をこなしてみて、どの様に使っていくのかを体験して行きましょう
もしあなたがすでにrailsのプロジェクトを作って、webアプリケーションを開発中であれば、導入は簡単です Gemfileに次の1行を追加してbundle installを行えば、導入は完了します
gem 'flextures'
ただ実際には、人によって作っているアプリケーションの種類は違うと思いますので 説明するための代表としてRPG風のソーシャルゲームを想定して、作業を進めて行かせていただきましょう
本当はもっと多くのテーブルがあるのですが、ここでは簡単のためにテーブルの次の部分だけを取り出します
- usersテーブルには、ユーザーの体力などのステータスを記録する
- ユーザーはアイテムを持っているテーブルと1対多の関連で繋がっている
db/migrate/20110516035555_create_users.rb
class CreateUsers < ActiveRecord::Migration
def self.create
create_table :users do |t|
t.string :name, default: "", null: false
t.integer :sex, default: 0, null: false
t.text :profile_comment,default: ""
t.integer :level, default: 1, null: false
t.integer :exp, default: 0, null: false
t.integer :guild_id, default: 0, null: false
t.integer :hp, default: 0, null: false
t.integer :mp, default: 0, null: false
t.integer :max_hp, default: 1, null: false
t.integer :max_mp, default: 1, null: false
t.integer :attack, default: 1, null: false
t.integer :defence, default: 1, null: false
t.integer :base_attack, default: 1, null: false
t.integer :base_defence, default: 1, null: false
t.timestamps
end
end
end
db/migrate/20110516035565_create_items.rb
class CreateItems < ActiveRecord::Migration
def self.create
create_table :items do |t|
t.integer :user_id, null: false
t.integer :master_item_id, null: false
t.integer :count, default: 0, null: false
t.integer :used_count, default: 0, null: false
t.timestamps
end
end
end
まずは、railsアプリケーションのTOPディレクトリに移動して、次のコマンドを実行して下さい
bundle exec rake -T
そうすると現在使用出来るrakeコマンドの一覧が表示されますが、その中に次の3つのコマンドが追加されています
rake db:flextures:load # load fixture data csv format
rake db:flextures:dump # Dump data to csv format
rake db:flextures:generate # load and dump file (replace) new data file
また、Rspecなどのテスト・ツールからも呼び出す事ができます そのため開発環境と、テスト環境で同じデータでテストを行う事ができるようになっています 実際にこれらの機能を触りながら体験して行きましょう
まずは、何をおいてもユーザーを作成しないといけません
Railsではユーザーのデータは users テーブルに格納するのが通例となっていますので ユーザーのデータを作成しましょう rake コマンド からflexturesを呼び出します
rake db:flextues:dump TABLE=users
こうすると spec/fixtures/ 以下に users.csv というファイルが作成されます 中身を見てみましょう
id,name,sex,profile_comment,level,exp,guild_id,hp,mp,max_hp,max_mp,attack,defence,base_attack,base_defence,created_at,updated_at
ユーザーが現在0人なので、テーブルのカラム名だけがダンプされています ここでExcelを開いて各々のユーザーのデータを打ち込んでいってもいいのですが、もう少しスマートな方法を取りましょう Flexturesでは、データを読み込むときに"フィルタ"という自分で読み込み機能をカスタマイズさせるためのプログラムを通過させます なので以下の様な仕様でフィルタを作成します
- HP,MP,attack,defence などはみんな同じデフォルトの値を設定される
- ユーザーは登録時に、アイテムを2個付与される
- 名前と性別はランダムに勝手に作ってくれる
Flextures::Factory.define :users do |f|
f.name=Faker::Japanese::Name.name unless f.name
f.sex=[0,1].sample unless f.sex
f.max_hp = f.hp = 100 unless f.max_hp.zero?
f.max_mp = f.mp = 30 unless f.max_mp.zero?
f.attack = 30 if f.attack.zero?
f.defence = 30 if f.defence.zero?
f.items<< [ Item.new( master_item_id:1, count:5 ), Item.new( master_item_id:2, count:5 ) ] if f.items.empty?
f
end
経験上、簡単な同値クラステストと境界値テストでしたら10〜50人程度(少ないほど良い)のデータがあれば十分なので とりあえず10人作ってみて、足りない場合少しづつ増やしていくスタイルで行かせていただきましょう 先ほど作った spec/fixtures/users.csv を編集して次のように書き足します
id,name,sex,profile_comment,level,exp,guild_id,hp,mp,max_hp,max_mp,attack,defence,base_attack,base_defence,created_at,updated_at 1 2 3 4 5 6 7 8 9 10
そして次の様にコマンドを実行します
rake db:flextures:load TABLE=users
rake db:flextures:dump TABLE=users,items
これでフィルタを実行したデータが読み込まれて、吐き出しをされます 結果 spec/fixtures/users.csv には次のようなデータが吐き出されます
id,name,sex,profile_comment,level,exp,guild_id,hp,mp,max_hp,max_mp,attack,defence,base_attack,base_defence,created_at,updated_at
1,相米 初栄,0,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
2,楳林 良枝,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
3,南場 寛平,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
4,加野 掬太郎,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
5,真砂 成彰,0,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
6,常陽 真幸,0,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
7,上濱 純孝,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
8,乙辺 充宏,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
9,金沢 昌恵,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
10,野塩 敏惠,1,,1,0,0,100,30,100,30,1,1,1,1,2013-06-18 14:53:36 UTC,2013-06-18 14:53:36 UTC
また、 spec/fixtures/items.csv にもデータが生成されて吐き出されます
id,user_id,master_item_id,count,used_count,created_at,updated_at
1,1,1,5,2,2011-11-12 00:00:00 UTC,2011-11-12 00:00:00 UTC
2,1,2,0,3,2011-11-12 00:00:00 UTC,2011-11-12 00:00:00 UTC
3,1,3,2,4,2011-11-12 00:00:00 UTC,2011-11-12 00:00:00 UTC
4,2,2,2,5,2011-11-12 00:00:00 UTC,2011-11-12 00:00:00 UTC
...以下アイテムのデータ
このようにしてデータを作成して、だいたい欲しい形のデータを作れたら、ここで使ったデータは単体テスト中でも使えますので あとは開発を進めていく中でデータを詰めて行きましょう
このようにして作られたデータはRspec等のテストツールの内側からも呼び出すことができます 今回は先程作ったデータを元に"User#levelup"メソッドのテストを記述しましょう
levelupメソッドの中身ですが今回は複雑な事は避けたいので、次のような作りになっています
class User < ActiveRecord::Base
has_many :items
# ユーザーのステータスを上昇させます
# @params [Integer] level レベルの上昇分
# @return [Integer] 上昇後のレベル
def levelup( level = 1 )
level.times do
self.level += 1
self.max_hp += 5
self.max_mp += 3
self.base_attack += 3
self.base_defence += 3
end
self.save
self.level
end
end
引数で上昇した文のレベルを渡してやると、その分だけステータスが上昇します
これに対して次の様にテストを記述します
require 'spec_helper'
describe User do
describe "#user" do
flextures :users
before do
@before_user = User.first
@user = User.first
@user.levelup
end
it "max_hpが上昇している" do
@user.max_hp.should > @before_user.max_hp+3
end
end
end
テストの中で書かれている flextures :user の箇所でテストデータの読み込みがされます flexturesはYAMLよりもCSVを優先するので users.csv を読み込んでからテストを実行してくれます