Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
FactoryGirl導入 #TechLunch
Search
Livesense Inc.
PRO
April 21, 2014
Technology
0
52
FactoryGirl導入 #TechLunch
FactoryGirl導入
2013年1Q RC opening
2013/11/06 (水) @ Livesense TechLunch
発表者:松永 一郎
Livesense Inc.
PRO
April 21, 2014
Tweet
Share
More Decks by Livesense Inc.
See All by Livesense Inc.
株式会社リブセンス 会社説明資料(報道関係者様向け)
livesense
PRO
0
770
26新卒_総合職採用_会社説明資料
livesense
PRO
0
1.4k
株式会社リブセンス会社紹介資料 / Invent the next common.
livesense
PRO
1
8.8k
26新卒_Webエンジニア職採用_会社説明資料
livesense
PRO
1
5k
中途セールス職_会社説明資料
livesense
PRO
0
140
EM候補者向け転職会議説明資料
livesense
PRO
0
58
コロナで失われたノベルティ作成ノウハウを復活させた話
livesense
PRO
0
180
転職会議でGPT-3を活用した企業口コミ要約機能をリリースした話
livesense
PRO
0
1.2k
株式会社リブセンス マッハバイト_プレイブック
livesense
PRO
0
720
Other Decks in Technology
See All in Technology
Storybook との上手な向き合い方を考える
re_taro
5
1.3k
複雑なState管理からの脱却
sansantech
PRO
1
160
インフラとバックエンドとフロントエンドをくまなく調べて遅いアプリを早くした件
tubone24
1
440
Lambda10周年!Lambdaは何をもたらしたか
smt7174
2
130
Exadata Database Service on Dedicated Infrastructure(ExaDB-D) UI スクリーン・キャプチャ集
oracle4engineer
PRO
2
3.2k
Python(PYNQ)がテーマのAMD主催のFPGAコンテストに参加してきた
iotengineer22
0
540
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
3.9k
個人でもIAM Identity Centerを使おう!(アクセス管理編)
ryder472
4
240
電話を切らさない技術 電話自動応答サービスを支える フロントエンド
barometrica
1
120
【令和最新版】AWS Direct Connectと愉快なGWたちのおさらい
minorun365
PRO
5
780
アジャイルチームがらしさを発揮するための目標づくり / Making the goal and enabling the team
kakehashi
3
160
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
950
Featured
See All Featured
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
GitHub's CSS Performance
jonrohan
1030
460k
Designing Experiences People Love
moore
138
23k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Building Better People: How to give real-time feedback that sticks.
wjessup
364
19k
Fontdeck: Realign not Redesign
paulrobertlloyd
82
5.2k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
26
2.1k
A Philosophy of Restraint
colly
203
16k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
109
49k
Building an army of robots
kneath
302
43k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Code Review Best Practice
trishagee
64
17k
Transcript
FactoryGirl導入 PlatformHR作成過程のKnowhow共有 その1
諸君、私はテストが大好きだ!! この地上で行なわれるありとあらゆるテストが大好きだ。 テストを並べたrspecやcucumberの一斉実行が .... と共に成功を返すのが好きだ 以前までredやyellowだったテストがリファクタリングや修正でgreenになった時など心がおどる スケジュールに滅茶苦茶にされるのが好きだ 必死に作るはずだったテストがpendingとだけ記載されてカバレッジが下がっていく様はとてもとても悲しいものだ 色々な要求に押し潰されテストが後回しにされるのが好きだ 色々な要求に追いまわされ外注の様に動作保証が出来ないcodeを作るのは屈辱の極みだ
諸君 私はテストを、リファクタリングが可能な量のテストを望んでいる 諸君 私に付き従うプロジェクトメンバー諸君 君達は一体なにを望んでいる? 更なるテストを望むか? 情け容赦のない糞のようなコードを望むか? 鉄風雷火の限りを尽くし三千世界のバグやエンバグを炙り出す嵐の様なテストを望むか? よろしい、ならばテストだ 少佐、かわいいよ、少佐
• activerecord • activecontroller • partial • api • railsの仕組みに乗ってないコード
• 業務フロー PlatformHRで行なっている自動テスト対象
前提 ActiveRecordの場合、dbと密になっており、on memoryなテス トを構築するのは面倒なので厳密な意味でのunit testでは無い 方法を採りました。 また、rails界隈のactiverecord系のテストツールも基本dbを使 う物が多いようです。 そういうわけで、dbとの連携を前提としたテストで行ないます。
通常良く使われるfixtureによる開発 ActiveRecord::TestFixtures::ClassMethods#fixtures を使って、rspecファイル毎にdbをリセットする(設定によっては この限りでは無い。テスト毎のリセットはtransaction)。 なお、基本fixtureファイル名とテーブル名は一致させる必要が あり、別のファイルをloadする場合は色々と面倒。
fixture使う場合のcode engines.platform-hr.jp/spec/models/companies_spec.rb(tag: gem_0.1.17) require ‘spec_helper’ describe Comapny do fixtures Dir.new(fixture_path).grep(/^[^\.]/).map{|f|
f.gsub(/\.yml/, '').to_sym} ….. fixtureがデフォルトで読まれるdirectory下から、テーブル名のシンボルを準備し、 fixturesメソッドに渡している。 このテストで使うレコード/使わないレコードの分別が面倒なので、基本、全テーブル 放り込んでいる。
この場合のデメリット • テスト毎にfixtureを切り替えたくても面倒 • fixtureの初期準備や、テーブル構成の変更時 の追従がかなり大変 • ちゃんとしたリレーション状態を保つのも大変 よーするにすごくたいへん
FactoryGirlってなに? 大雑把にいうと。 FactoryGirlとは、FactoryGirlのコンテキストに、あ るテーブルのあるレコードを新しく頂戴(書込み済 みも、未書き込みも両方OK)とすると、対象の ActiveRecord instanceが返却される仕組み。
少し細かく言うと。 • FactoryGirlはテーブル毎にFactoryを定義し て、それに従ってrecordが作成される。 • Factoryからrecordを取り出す際に、定義を上 書きする事も可能。 • また、Factoryの定義内にロジックを入れて色々 する事が出来る。
実際のFactoryの定義 定義 spec/factories/resumes.rb
Factoryの定義 2,3行目 FactoryGirl.define do factory :factory名 do 各種定義 end end
簡単な使いかた(生成) dbに作成された状態を作る $record = FactoryGirl.create(:resume) dbにpersist前の状態を作る $record = FactoryGirl.build(:resume) 100件作る
$records = FactoryGirl.create_list(:resume, 100)
簡単な使いかた(初期値上書き) Factoryの定義の値を上書きして別の値を使う $record = FactoryGirl.create(:resume, :medium => hoge_medium) $record =
FactoryGirl.create(:resume, :name_ruby => ‘イチ ロー’)
簡単な使い方 (trait) traitにより、create/buildする際にロジックを分ける事が出来る 例(users) $admin = FactoryGirl.create(:user_admin) $owner = FactoryGirl.create(:user_owner)
呼出側で適用とかも出来る $admin = FactoryGirl.create(:user, :admin)
定義 固定値 20行目 name_ruby ‘ふりがな’ これにより生成される際はいつでも ふりがな が値 として入ってくる。
遅延評価 FactoryGirlの値はFactoryの定義が評価された時に決定する。逆に言うと、factory で生成する毎に値を変えたい場合は遅延評価( {}でくくる )する必要がある。 hoge_time Time.now とした場合、何度取り出しても、同じ値が出てくる 22行目 以下のようにすると遅延評価され、factoryで生成する度に18-58年前のバラバラの
日付を作る事が出来る birthday { Date.today.years_ago( 18 + rand(40) ) - rand(100)}
連番 7行目 sequence(:medium_member_id){|n| “medium-member-id-# {n}”} 生成される度にnがカウントアップされ、その結果をゴニョゴニョ した値をrecordにセットする これを利用すると nのmodを取ったりして色々データに色を出 す事が出来る
他のFactoryとの連携 5行目 association :medium, :factory => :medium ResumeはMediumをbelongs_toしてリレーション している。 この定義により、指定無い場合は自動でmedium
が作られ、関連付けされる(db的にも)
traitの作成 前述のように、traitという機能によりfactoryに色を 出す事が出来る spec/factories/users.rb:15-24 spec/factories/resumes.rb:9-18
FactoryGirlの組込 FactoryGirlはデータ作成の為の物なので、persist したデータのクリーニングが必要。 そこで、DatabaseCleanerというgemとセットで使う 事が多い。
DatabaseCleaner 以下の機能を持つgem • clean_with ◦ いくつかの方式でdbをクリアする ◦ truncateとかtransactionとかdeleteとか • start
◦ 戻しポイントの指定(begin tranみたいなの) • clean ◦ 戻す(rollback的な)
どう組み合わせるか PlatformHRの基本的なやりかた その1(scoutで多用) • DatabaseCleanerのstrategy(start/cleanをどのように行なうか)をtransaction指 定で行なう。 1. rspecの根っこ(L1)のbefore :allで初期状態作成 a.
DatabaseCleaner.clean_withでtruncate b. truncateは重いので、対象テーブルを指定 2. L1のbefore :each でDatabaseCleaner.start 3. L1のafter :each でDatabaseCleaner.clean ただし、既存のfixtureが使えない。
どう組み合わせるか PlatformHRの基本的なやりかた その2(fixtureを使った既存テストの多いengines側 でのやりかた) • そのままfixturesでloadすると、テスト毎にrollbackが走り、rspecのcontext内で 共通的にFactoryGirlで作成した値が飛んでしまう。 • fixturesでtransactionを使わず、テスト毎にdbへfixtureをロードする方法もある が、テスト実行が重くなる
なので、fixtureのロードのタイミングに関しては自前で組み込んだ。 注意点として、db/seeds.rbを使っていると、このデータも飛ばされてしまうため、 fixtureに寄せた。どーせproductに対するマスター投入なんか初回しかやらないし。
最後に • テストがあれば万事OKってわけじゃないけど、テストが無い と出来ない事はいっぱいあるので、ちゃんとテスト書きましょ う。 • でもなんでもテスト書きゃ良いってもんでも無くて(開発時/仕 様変更時の工数が膨らむ)、ちゃんと観点をもって書きましょ う。 •
でもcontroller/modelでのcoverageは100%(組み合わせが あるのでそれ以上)が望ましいと思う。 • Magical Factory Girlに期待。