parallel_tests, rspecテストコードのリファクタリング, gitで詰んだかと思った話

/ 19日目/ 4週目・作業週 コメント

parallel_tests を使ってみる

プロジェクトではなく、環境にインストール。 -> 微妙な結果に

基本的にここを参考に。 まずはgemのインストール。

$ gem install parallel_tests

次の記述に従って、dbの設定を編集。

並列実行の数の指定はここを参考にすると良い。今回はクアッドコアのマシンなので4にした。

テスト用データベースの準備

$ parallel_rspec -n 4 -e 'rake db:create' 
$ parallel_rspec -n 4 -e 'rake db:test:prepare'

実際に走らせる

$ parallel_rspec spec/ -n 4

75秒 -> 45秒に高速化された。んー、思ったほどではない・・・。

そして、普通にテスト走らせた時にはなかったエラーが・・・。

やっぱり、プロジェクトにインストールしないとだめか。

rspecをもっと綺麗に書きたい

とても参考になる。

あと、違うデータに対して同じit{..}を実行しているので、その重複を無くしたい。次が参考になりそう。shard examplesを使えばいいっぽい。

実際の使用例は、次も参考になる。

Gitで詰んだかと思った

  1. あるブランチ(branch-hogeとしよう)をorigin(Github)にpush
  2. masterの変更を取り込むためにlocalのbranch-hogeで$git rebase masterとする。 <-ここがそもそもの間違い
  3. branch-hogeのコミットを$ git rebase -iでまとめる。
  4. $ git push origin branch-hogeとするとエラーになる。2.で履歴が置き換わっているためbranch-hoge@originにpushできない。
  5. あーrebaseしたからか!と気づいて、$ git reflogでHEADの履歴を参照するも、rebase -iでよくわからないことに・・・。

詰んだかと思いましたが、なんとかリカバった。手順は、

  1. $ git checkout --track origin/branch-hogeてローカルに追跡ブランチorigin-branch-hogeを作成。
  2. branch-hogeからorigin-branch-hogeに必要なコミットをcherry-pick。このとき、-nを使うとgit addした状態で追加されていくので、origin-branch-hogeに必要な変更をためていって、最後にコミットすれば良い。
  3. push可能な変更を追跡ブランチに追加することができたので、$ git pushすると良い。PullReqでautomergeできない場合は、masterを merge

教訓

すでにpushしたブランチでrebaseするべからず

relationで関連オブジェクトを取得するときにunscopedを使いたい

ちょっとハマった

新知識

Gitのpre-commit-hookでテストする

昨日のやつで思いついたけど、テストの必要ないコミットには、コメントでそのことを示せばいいのでは。頭に"!“をつけるとか。試してみようか。

polymorphicでわからないこと

class Comment < ActiveRecord::Base
  belongs_to :commentable, polymorphic: true
  # この下を書くのと書かないとでは何が違う?
  # 書いたほうがComment.includes(:article)とかできて良さそうだけど
  # なにか弊害があるんだろうか?
  belongs_to :article,
    foreign_key: 'commentable_id'
  belongs_to :picture,
    foreign_key: 'commentable_id'
end

class Article < ActiveRecord::Base
  has_many :comments, as: :commentable
end

class Picture < ActiveRecord::Base
  has_many :comments, as: :commentable
end

belongs_to :parent があればコードがすんなり書ける気がする。

[追記:2013-11-16]

belongs_to :parent とかけば、確かにincludesで別モデルに関するリレーションを定義できるのだけれど、SQLが複雑になって遅くなったりする。というか、そもそもpolymorphicなので、一種類の親モデルを持つわけではない。つまりbelongs_toで親になりうる全てのモデルを指定すると、それぞれのモデルインスタンスが、全てを親に持つことになってしまっておかしな定義になる。ちょっとめんどくさいけれど、

にあるように、joinの定義はSQLで書くのが無難なよう。こうしたほうがいいよ、というのがあったらぜひ教えてほしい。

参考

[追記:2013-11-17]

上記URLのSolutionも参考になる。

belongs_to :article,
  foreign_key: 'comemntable_id',
  conditions: "comments.commentable_type = 'Article'"

とすれば、commentable_typeが'Article'のcommentにだけ、articleという子プロパティが作られる。 これは一回使ってみたい。

[追記:2013-11-18]

続きを書きました。

コメント