Rails Tutorial Chapter3をやる 断片的なメモ
2章はさくっと飛ばしまして、今章で作成するsample_app
を今後も使っていく、ということで作るのですが。
断片的なメモなので、あまり参考にならないかと。Nitrous.io上で開発してます。
- テストの作成と実施
- provideとyield
- setupメソッド
- Bitbucketへリモート追加してプッシュ
- マイグレーションのロールバック
- Railsコマンドとその省略形
- トピックブランチをBitbucketにプッシュ
- 追加の設定いろいろ(Guardなど)
Testing
$ ls test/controllers/ static_pages_controller_test.rb
コントローラ作成時にそれに対応したテストファイルも生成されている。そこにテストメソッドを書いていく。
require 'test_helper' class StaticPagesControllerTest < ActionController::TestCase test "should get home" do get :home assert_response :success end test "should get help" do get :help assert_response :success end end
test "should get home" do get :home assert_response :success end
ホーム画面にアクセスしたら成功してほしいよね! というメソッド。
bundle exec rake test
または rake test
コケる例
test "should get about" do get :about assert_response :success end
これを追加してみる。当然aboutページはまだ用意してないので、コケるはず。
Finished in 0.139130s, 21.5625 runs/s, 14.3750 assertions/s. 1) Error: StaticPagesControllerTest#test_should_get_about: ActionController::UrlGenerationError: No route matches {:action=>"about", :controller=>"static_pages"} test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>' 3 runs, 2 assertions, 0 failures, 1 errors, 0 skips 3 tests 2 assertions, 0 failures, 1 errors
errorでました。マッチするrouteがないよと。
なので色々ルート追加すると。そんな感じでテストを進めていく。
assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
titleタグ内のテキストを調べる。
provideとyield
<% provide(:title, "Home") %> <!DOCTYPE html> <html> <head> <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title> </head> <body> <h1>Sample App</h1> <p> This is the home page for the <a href="http://www.railstutorial.org/">Ruby on Rails Tutorial</a> sample application. </p> </body> </html>
<% provide(:title, "Home") %>
で:titleというシンボルで"Home"という文字列を設定するよと。
それをtitle
タグ内で受け取る。<%= yield(:title) %>
として表示。
setupメソッド
require 'test_helper' class StaticPagesControllerTest < ActionController::TestCase def setup @base_title = "Ruby on Rails Tutorial Sample App" end test "should get home" do get :home assert_response :success assert_select "title", "Home | #{@base_title}" end test "should get help" do get :help assert_response :success assert_select "title", "Help | #{@base_title}" end test "should get about" do get :about assert_response :success assert_select "title", "About | #{@base_title}" end end
setupメソッドは各testメソッドの前に1回ずつ実行される。ベースタイトルを定義しているだけの簡単なものだが、いちいちassert_select
にベタに書いていく、ということを避けることができる。
Bitbucketへリモート追加してプッシュ
ここでBitbucketにてsample_app
というリポジトリを作っておく。
そしてリモート追加してプッシュ
$ git remote add origin git@bitbucket.org:noriyotcp/sample_app.git $ git push -u origin --all
マイグレーションのロールバック
$ bundle exec rake db:migrate
We can undo a single migration step using$ bundle exec rake db:rollback
これでマイグレーションをひとつ戻せる、ということかな。これは知らんかった。
Rails コマンドとその省略形
Full command | Shortcut |
---|---|
$ rails server | $ rails s |
$ rails console | $ rails c |
$ rails generate | $ rails g |
$ bundle install | $ bundle |
$ rake test | $ rake |
TopicブランチをBitbucketにプッシュ
$ git status $ git add -A $ git commit -m "Add a Static Pages controller" $ git push -u origin static-pages
最後のコマンドはstatic-pagesブランチをBitbucketにプッシュしている。
Advanced testing setup
3.7.2 Backtrace silencer
backtraceは長くて不便なので、
config/initializers/backtrace_silencers.rb
Rails.backtrace_cleaner.add_silencer { |line| line =~ /rvm/ }
注意点は必ずサーバーを再起動させること。
3.7.3 Automated tests with Guard
いちいちrake test
と打つのめんどい。Gemfileに以下を記述してbundle install
gem 'guard-minitest'
インストール後、アプリのルートディレクトリにて初期化
$ guard init
ではなく
$ guard init minitest
$ guard init minitest 04:48:39 - INFO - Writing new Guardfile to /home/action/workspace/sample_app/Guardfile 04:48:40 - INFO - minitest guard added to Guardfile, feel free to edit it
Guardファイルが生成されるので、そこに色々設定する。Rails Tutorialのをそのままコピペ。
# Defines the matching rules for Guard. guard :minitest, spring: true, all_on_start: false do watch(%r{^test/(.*)/?(.*)_test\.rb$}) watch('test/test_helper.rb') { 'test' } watch('config/routes.rb') { integration_tests } watch(%r{^app/models/(.*?)\.rb$}) do |matches| "test/models/#{matches[1]}_test.rb" end watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches| resource_tests(matches[1]) end watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches| ["test/controllers/#{matches[1]}_controller_test.rb"] + integration_tests(matches[1]) end watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches| integration_tests(matches[1]) end watch('app/views/layouts/application.html.erb') do 'test/integration/site_layout_test.rb' end watch('app/helpers/sessions_helper.rb') do integration_tests << 'test/helpers/sessions_helper_test.rb' end watch('app/controllers/sessions_controller.rb') do ['test/controllers/sessions_controller_test.rb', 'test/integration/users_login_test.rb'] end watch('app/controllers/account_activations_controller.rb') do 'test/integration/users_signup_test.rb' end watch(%r{app/views/users/*}) do resource_tests('users') + ['test/integration/microposts_interface_test.rb'] end end # Returns the integration tests corresponding to the given resource. def integration_tests(resource = :all) if resource == :all Dir["test/integration/*"] else Dir["test/integration/#{resource}_*.rb"] end end # Returns the controller tests corresponding to the given resource. def controller_test(resource) "test/controllers/#{resource}_controller_test.rb" end # Returns all tests for the given resource. def resource_tests(resource) integration_tests(resource) << controller_test(resource) end
guard :minitest, spring: true, all_on_start: false do
このラインはSpringサーバーを使いつつ、頭からフルテストをするのを防いでくれる?
SpringとGitのコンフリクトをさけるため、.gitignoreに記述する。
/spring/*.pid
ちょっと注意点のメモ
$ bundle exec guard
でならないなあ。
$ guard
でもなんか変なんだけど。
WARN: Unresolved specs during Gem::Specification.reset: minitest (>= 3.0) WARN: Clearing out unresolved specs.
ちょっと忘れてしまいましたが、その後chruby
を使いRubyのバージョンを2.0.0
にして、gemを入れ直していったんですが、そのせいなのかどうなのかguardにおいてcommand not found
とでてしまいました。
Gemfileにguard追加しないとだよね。
group :test do gem 'minitest-reporters' gem 'mini_backtrace' gem 'guard' # 追加 gem 'guard-minitest' end
これで怒られずにguardを使えるようになった。テスト自動化は楽チン。
ブランチ作成してBitbucketにも追加
マスターだけでなく、トピックブランチをローカルに作って、それをBitbucketに反映させたい。
tomoのconcrete5 :: Bitbucketでbranchを使ってみた(メモ)
ブランチの作成
git branch (branch name)
git push origin (branch name)上記コマンドでブランチ名を指定して作成します。2行目で、Bitbucketに反映させます。
するとgit push
だけでなく
Bitbucketへの反映、従来は、git push だけでよかったですが、今後は、都度ブランチ名の指定が必要です。
git push origin (branch name)
ブランチ名を指定してプッシュ。
引数なしでプッシュすると
引数なしのgit pushは危険なので気をつけましょう - DQNEO起業日記
引数なしで"git push"すると、何がpushされるかご存知でしょうか?
デフォルトでは、ローカルブランチと同名のブランチがリモート上にあるならそれらを一気にpushしてしまいます。 カレントブランチが何であろうと関係ないのです。
これを人よんで絨毯爆撃pushといいます。(←いま思いついた)
(中略)
すると、どこに何がpushされると思いますか?
実は、master -> masterにpushされます。 masterがまだpushできる状態でない場合、これはかなり痛い。すごく痛い。頭が頭痛でおなかが腹痛。
しかもpushしたかった当のbr1ブランチはpushされないというオチ。(リモートにbr1ブランチがない限りは)
この挙動は大半のユーザの期待とは異なるのではないでしょうか。
(中略)
その4:デフォルトの挙動を"simpleモード"に変更する(ただしGit1.7.11以降のみ) git config --global push.default simple git push simpleモードとは、「カレントブランチと同名のリモートブランチが存在する場合のみ、カレントブランチのpushが行われる」モードだそうです。
simple
- likeupstream
, but refuses to push if the upstream branch's name is different from the local one. This is the safest option and is well-suited for beginners. It will become the default in Git 2.0. https://github.com/git/git/blob/master/Documentation/config.txt公式アナウンスによれば、Git次期バーション(おそらく2.0)あたりからこの"simple"モードがデフォルトになるそうです。 今からこの設定にして馴れておくのがよいでしょう。
とうとう Git 2.0 が現実のものに。便利な機能満載 - Atlassian Japan
重要! git push (引数なし) のデフォルトが simple なプッシュの仕組みに 単純な引数なしの git push のデフォルトの動作は、これまで直感的に理解できるものではありませんでした。ローカルとリモートでブランチ名が一致する限り、ブランチはすべてリモートに送られ、これが、matching オプションの意味でした。
Git 2.0 で、push のデフォルトが simple に変更され、より具体的・直感的で、対象範囲が狭まりました。これにより、
同じリモートでカレントブランチが対象リモートブランチと連携するように設定されている場合のみ、カレントブランチが同名ブランチへ、
通常のフェッチ先ではないリモートにプッシュする場合は、カレントブランチが同名ブランチへ、push されるようになります。
デフォルトになっているのなら心配はない?
でも一応ブランチ名を指定してpushする方法を覚えておくといいかなと。
すぐ分かる! git の origin と master ってなんだ? - Qiita
git push はデフォルトでは、同じブランチ名がリモート上にある場合、全部のブランチを push しちゃう?
git push -b bitbucket master
なんかあまりRailsの話じゃなくなってますね・・・。