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

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

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

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

1回答

3915閲覧

Dockerを用いるとRSpecによるテストでデータベースがリセットされなくなる

退会済みユーザー

退会済みユーザー

総合スコア0

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2019/12/14 05:18

前提・実現したいこと

Dockerを用いてRubyonRailsのアプリケーションを作成しています。
RSpecの2回目以降のテストでデータベースを初期化しないと同じテストが通らなくなる問題が発生しました。

Rails 5.2.4
Ruby 2.5.3
RSpec 3.9

  • rspec-core 3.9.0
  • rspec-expectations 3.9.0
  • rspec-mocks 3.9.0
  • rspec-rails 3.9.0
  • rspec-support 3.9.0

発生している問題・エラーメッセージ

RSpecでUserモデルのテストを書いたときに問題が発生しました。
Userモデルにはデフォルトで作成されるカラム以外ではname(string)のみを追加しています。
とりあえずRSpecが動作するか確かめるために下記のようなテストを作成しました。

RSpec

1require 'rails_helper' 2 3RSpec.describe User, type: :model do 4 describe "something to be performed" do 5 context "under condition" do 6 it "behaves like" do 7 user = User.new(name: "yamada taro") 8 user.save 9 current_user = User.find(1) 10 expect(current_user.name).to eq("yamada taro") 11 end 12 end 13 end 14end

1回目はパスするのですが、2回目以降にカラムが存在しないとエラーが出ます。

Terminal

1F 2 3Failures: 4 5 1) User something to be performed under condition behaves like 6 Failure/Error: current_user = User.find(1) 7 8 ActiveRecord::RecordNotFound: 9 Couldn't find User with 'id'=1 10 # ./spec/models/user_spec.rb:9:in `block (4 levels) in <top (required)>' 11 12Finished in 0.02954 seconds (files took 1.79 seconds to load) 131 example, 1 failure 14 15Failed examples: 16 17rspec ./spec/models/user_spec.rb:6 # User something to be performed under condition behaves like

原因を調べたところ、テスト用データベースの内容は削除されているようなのですが、idがインクリメントされて2回目以降のレコードが作成されているようです。(2回目はid=2、3回目はid=3...)
テスト用のデータベースをリセットするとテストはパスします。
docker-compose run web rails db:migrate:reset RAILS_ENV=test
参考:https://yoji4910.hatenablog.com/entry/2019/09/21/023658

データベースをリセットする方法としてdatabase_cleanerを見つけましたが、そもそもローカル環境でRSpecを使って同じことをしてみましたが何度テストを実行してもエラーは出ませんでした。

###質問
Dockerの設定に不具合があるのでしょうか?
それともDockerを利用する時はdatabase_creanerを利用しなければならないのでしょうか?

関係のありそうなファイル・Docker・Gemfile

Dockerをきちんと理解し切れていないので訳のわからないことをしているかもしれません。

railshelper

1require 'spec_helper' 2ENV['RAILS_ENV'] ||= 'test' 3 4require File.expand_path('../config/environment', __dir__) 5 6abort("The Rails environment is running in production mode!") if Rails.env.production? 7require 'rspec/rails' 8 9begin 10 ActiveRecord::Migration.maintain_test_schema! 11rescue ActiveRecord::PendingMigrationError => e 12 puts e.to_s.strip 13 exit 1 14end 15RSpec.configure do |config| 16 config.fixture_path = "#{::Rails.root}/spec/fixtures" 17 config.use_transactional_fixtures = true 18 config.infer_spec_type_from_file_location! 19 config.filter_rails_from_backtrace! 20end

spechelper

1RSpec.configure do |config| 2 3 config.expect_with :rspec do |expectations| 4 expectations. 5 include_chain_clauses_in_custom_matcher_descriptions = true 6 end 7 8 config.mock_with :rspec do |mocks| 9 mocks.verify_partial_doubles = true 10 end 11 12 config.shared_context_metadata_behavior = :apply_to_host_groups 13end

Dockerfile

1FROM ruby:2.5.3 2ENV LANG C.UTF-8 3RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs mysql-client 4RUN mkdir /myapp 5ENV APP_ROOT /myapp 6WORKDIR $APP_ROOT 7 8ADD ./Gemfile $APP_ROOT/Gemfile 9ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock 10 11RUN bundle install 12ADD . $APP_ROOT 13 14COPY entrypoint.sh /usr/bin/ 15RUN chmod +x /usr/bin/entrypoint.sh 16ENTRYPOINT ["entrypoint.sh"] 17EXPOSE 3000

dockercompose

1version: '3' 2services: 3 db: 4 image: mysql:5.7 5 environment: 6 MYSQL_ROOT_PASSWORD: password 7 MYSQL_DATABASE: root 8 ports: 9 - "3306:3306" 10 11 web: 12 build: . 13 command: rails s -p 3000 -b '0.0.0.0' 14 volumes: 15 - .:/myapp 16 ports: 17 - "3000:3000" 18 links: 19 - db

Gemfile

1source 'https://rubygems.org' 2git_source(:github) { |repo| "https://github.com/#{repo}.git" } 3 4ruby '2.5.3' 5gem 'rails', '~> 5.2.3' 6gem 'mysql2', '>= 0.4.4', '< 0.6.0' 7gem 'puma', '~> 3.11' 8gem 'sassc-rails' 9gem 'uglifier', '>= 1.3.0' 10gem 'coffee-rails', '~> 4.2' 11gem 'turbolinks', '~> 5' 12gem 'jbuilder', '~> 2.5' 13gem 'bootsnap', '>= 1.1.0', require: false 14 15group :development, :test do 16 gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] 17 gem 'rspec-rails', '~> 3.8' 18 gem 'factory_bot_rails', '~> 5.0' 19end 20 21group :development do 22 gem 'web-console', '>= 3.3.0' 23 gem 'listen', '>= 3.0.5', '< 3.2' 24 gem 'spring' 25 gem 'spring-watcher-listen', '~> 2.0.0' 26end 27 28group :test do 29 gem 'capybara', '>= 2.15' 30 gem 'webdrivers' 31end 32 33gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] 34

試したこと


データベースのリセットでテストはパス
現状毎回データベースのリセットをする必要がある。


find_by(name: "~~")でレコードが作成されていることは確認
expect(current_user.id).to eq(1)とすると

Failure/Error: expect(current_user.id).to eq(1) expected: 1 got: 2

といったようにインクリメントされていることを確認


テスト用のデータベースをみてもデータはなし。
データの削除自体はきちんと行われている模様。


ローカル環境では何度行ってもテストはパス

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

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

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

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

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

guest

回答1

0

transactionでAUTO INCREMENTな主キーが1に戻ると決めつけるのはどうなのか?と思います。
適当にググってみましたが、SQLiteのみの挙動のようです。

もし、仮に管理ユーザーなどとして特定のidをもちたいのならばidを明記し

ruby

1User.create(id: 1, name: "yamada")

などと作成するとよいでしょう。

id: 1であることが重要でないのならば

ruby

1current_user = User.order(:created_at).last

になるかなと思います。

投稿2019/12/14 05:52

asm

総合スコア15147

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

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

退会済みユーザー

退会済みユーザー

2019/12/14 06:20

早速のご回答ありがとうございます。 idが1であることは重要ではないのですが、なぜDockerを使用しなかったときと違う挙動になったのか、何か間違えた設定をしているのかと思った次第です。 SQLiteの挙動ということなので、MYSQLを使えるように設定できていないのか調べてみたいと思います。 そもそもこういった書き方自体が良くないのですね。今後はご回答頂いたような書き方をしたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問