質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
RubyGems

RubyGemsはRubyによるプログラミングのためのパッケージマネジメントツールです。ユーザはこれを使用することで、Rubyライブラリのダウンロードやアップデートや、依存関係の自動解決が可能になります。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

2903閲覧

DatabaseCleanerの設定内容がよくわかりません

shyamahira

総合スコア19

RubyGems

RubyGemsはRubyによるプログラミングのためのパッケージマネジメントツールです。ユーザはこれを使用することで、Rubyライブラリのダウンロードやアップデートや、依存関係の自動解決が可能になります。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

0クリップ

投稿2016/11/07 12:44

railsでRspecを使っていますが、テストデータベースをexampleごとにクリーンにするためにDatabaseCleanerを使いたいと思っています。

こちらのDatabaseCleanerのREADMEにはrspecでDatabaseCleanerを使う場合の例が載っていますが、各ブロックで何をやっているのかいまいち理解できませんでした。

Everyday Rails - RSpecによるRailsテスト入門にもREADMEとほぼ同じ内容の下記設定がありますが、この説明文を見ても理解できません。

RSpec.configure do |config| # Configure DatabaseCleaner to reset data between tests config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with :truncation end config.around(:each) do |example| DatabaseCleaner.cleaning do example.run end end config.after(:each) do DatabaseCleaner.clean end end

よく理解できない点

config.before(:suite) ブロック

各example前にトランザクションでロールバックして、次にトランケートでデータの全件削除をしていると思いますが、何故このように2段階の処理をする必要があるのか?

config.around(:each)ブロック

  • config.aroundが何のブロックかわからない
  • DatabaseCleaner.cleaningブロックはDatabaseCleaner.startとDatabaseCleaner.cleanをするブロックだと思うが、本当にそうなのかよくわからない
  • example.runの意味がわからない

config.after(:each)ブロック

example後にデータの削除をしているのだと思うのですが、前述のconfig.before(:suite)でデータの削除を事前にするのに、何故事後にもわざわざ削除をしようとしているかがわからない


各ブロックでやっていることや関連性についてご教示いただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

config.before(xxx) は DatabaseCleaner ではなくRSpecのフックです。
フックスコープのための新しい名前: :example と :context にわかりやすく書いてありました。

ruby

1c.before(:each) { } # 全てのテストスイート中のそれぞれのexampleの前に実行される 2c.before(:all) { } # それぞれのトップレベルのグループの最初のexampleの前に実行される 3c.before(:suite) { } # 全てのspecファイルがロードされたあと、最初のspecが実行される前に一度だけ実行される

で、その各フックのブロックの中に書いてあるものが DatabaseCleaner に関するものです。

config.before(:suite) do DatabaseCleaner.strategy = :transaction DatabaseCleaner.clean_with :truncation end

は、どのようにDatabaseCleanerを動作させるかの設定です。
最初に1回だけやればいいので before(:suite) です。

ruby

1 config.around(:each) do |example| 2 DatabaseCleaner.cleaning do 3 example.run 4 end 5 end

こちらが実施にDataBaseCleanerを動かすところ
example毎にDatabaseCleanerをstartさせて example を実行し DatabaseCleaner で clean する動きです。

ruby

1 config.after(:each) do 2 DatabaseCleaner.clean 3 end

こちらも実施にDataBaseCleanerを動かすところですが
DatabaseCleanerをstartさせ example を実行し DatabaseCleaner で clean する動きです。

最後の config.after はたぶん例のために書いてあるだけで実際は config.around が書いてあれば不要だと思います。

最新の例

ruby

1RSpec.configure do |config| 2 3 config.before(:suite) do 4 DatabaseCleaner.strategy = :transaction 5 DatabaseCleaner.clean_with(:truncation) 6 end 7 8 config.around(:each) do |example| 9 DatabaseCleaner.cleaning do 10 example.run 11 end 12 end 13 14end

config.afterは書いてないですね。


Readmeをみると、start clean cleaningの3つが、書かれているのですが、どのように使いわけるのでしょうか。

READMEに書いてありますが。。。

startは

Some strategies need to be started before tests are run (for example the :transaction strategy needs to know to open up a transaction). This can be accomplished by calling DatabaseCleaner.start at the beginning of the run, or by running the tests inside a block to Database.cleaning.

という事です。
strategies によっては事前処理が必要でそれを行うのが DatabaseCleaner.start です。

で実際に削除を行うのが DatabaseCleaner.clean

そんでもって Database.cleaning は block を実行する前に DatabaseCleaner.start して 終ったら DatabaseCleaner.clean してくれるそうです。

投稿2016/11/08 02:15

編集2016/11/09 00:41
hana-da

総合スコア1728

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shyamahira

2016/11/08 14:30

大変よく理解できました。ありがとうございました。 ただ、'DatabaseCleanerをstartさせる' とはどのような意味があるのかがまだモヤっとしています。 Readmeをみると、start clean cleaningの3つが、書かれているのですが、どのように使いわけるのでしょうか。
shyamahira

2016/11/09 08:08

> strategies によっては事前処理が必要でそれを行うのが DatabaseCleaner.start です。 > で実際に削除を行うのが DatabaseCleaner.clean > そんでもって Database.cleaning は block を実行する前に DatabaseCleaner.start して 終ったら DatabaseCleaner.clean してくれるそうです。 すみません。READMEをちゃんと読んでませんた。 ご回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問