前提
RailsチュートリアルにDockerを使い、学習を進めています。開発環境
Ruby:3.0.2 rails:6.0.4発生したエラー
5.3.4 リンクのテスト
統合テストを使うと、アプリケーションの動作を細かくてテストすることができる site_layoutというテストのテンプレートを生成ターミナル.
$ docker-compose exec web bundle exec rails generate integration_test site_layout
invoke test_unit
create test/integration/site_layout_test.rb
リスト 5.32
assert_templateメソッドを使って、Homeページが正しいビューを描画しているか確かめる
test/integration/site_layout_test.rb
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", help_path
assert_select "a[href=?]", about_path
assert_select "a[href=?]", contact_path
end
end
リスト 5.33
統合テストが通る確認しようとしたところ次のようなエラー
ターミナル.
$ docker-compose exec web bundle exec rails test:integration
Started with run options --seed 57511
ERROR["test_layout_links", #<Minitest::Reporters::Suite:0x0000aaaad715fa40 @name="SiteLayoutTest">, 0.205297333013732]
test_layout_links#SiteLayoutTest (0.21s)
Minitest::UnexpectedError: DRb::DRbRemoteError: expecting <"static_pages/home"> but rendering with <["rescues/blocked_host", "rescues/layout"]> (Minitest::Assertion)
test/integration/site_layout_test.rb:7:in `block in <class:SiteLayoutTest>'
1/1: [============================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.24128s
1 tests, 1 assertions, 0 failures, 1 errors, 0 skip
but rendering with <["rescues/blocked_host", "rescues/layout"]>
と出ていたので調べてみると、エラーの原因は、Rails 6.0からの仕様変更のようです。
解決策①
```$ rails test:integration```が実行されるときに、テストはexample.comへアクセスしているよう. デフォルトだと、開発環境ではexample.comへのアクセスは許可されていないconfig/enviroments/development.rb
Rails.application.configure do
#省略
config.hosts << "www.example.com"
#省略
end
を追加することによって、開発環境でexample.comへのアクセスを許可することにより、とりあえずはテストが通る
ターミナル.
$ docker-compose exec web bundle exec rails test:integration
Started with run options --seed 41448
development=---=---=---=---=---=---=---=---=---=---=---=---=---=---=--] 0% Time: 00:00:00, ETA: ??:??:??
1/1: [============================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.98599s
1 tests, 5 assertions, 0 failures, 0 errors, 0 ski
通った
解決策②
しかし本来テストは開発環境ではなくテスト環境で行うもの 解決策①では、通ったものの「テストが開発環境で実行されてしまう」という根本的な解決になっていない 私のdocker-compose.ymlには、RAILS_ENVの値としてdevelopmentが固定されているので、テスト実行時にテスト環境を使うことができなかった なので、RAILS_ENVの値を空にすることにより、根本解決となるdocker-compose.yml
...略
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- ./src:/app
ports:
- "3000:3000"
environment:
#developmentを削除
RAILS_ENV:
depends_on:
- db
ターミナル.
$ docker-compose stop
本当は$ docker-compose run --rm --service-ports web で起動させた方がいいみたいです
$ docker-compose up -d
$ docker-compose exec web bundle exec rails test:integratio
Started with run options --seed 34526
1/1: [============================================================] 100% Time: 00:00:02, Time: 00:00:02
Finished in 2.05303s
1 tests, 5 assertions, 0 failures, 0 errors, 0 skips
通った
(解決策①で追加したexample.comへのアクセスを許可をするコードを消しても通る)
補足
test/integration/site_layout_test.rb にputs ENV["RAILS_ENV"]
を追加することで
test
とdevelopment
どちらがコンソールに表示されるか確認できる
テストの動作検証時でもputsデバックは便利
test/integration/site_layout_test.rb
require 'test_helper'
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get root_path
puts ENV["RAILS_ENV"]
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", help_path
assert_select "a[href=?]", about_path
assert_select "a[href=?]", contact_path
end
end
ターミナル.
$ docker-compose exec web bundle exec rails test:integration
Started with run options --seed 21354
test: [=---=---=---=---=---=---=---=---=---=---=---=---=---=---=---=--] 0% Time: 00:00:00, ETA: ??:??:??
1/1: [============================================================] 100% Time: 00:00:01, Time: 00:00:01
Finished in 1.20476s
1 tests, 5 assertions, 0 failures, 0 errors, 0 skips
↑テスト環境が使われていることがわかる
皆さんに感謝です
何かご指摘やアドバイスなどあれば、ぜひよろしくお願いします