如果这是一个基本问题,我是新手,很抱歉。
我正在使用 M1 Mac。 我正在通过使用 docker 构建 Rails 环境来创建应用程序。
我从 Docker 中启动 Rspec,并在集成测试中出错。 并得到这个错误。
Failure/Error: expect(current_path).to eq '/users/1'
expected: "/users/1"
got: "/users/56"
(compared using ==)
# ./spec/requests/users_login_spec.rb:16:in `block (3 levels) in <main>'
每次我运行 rspec 时,用户数量都会以 56 的倍数增加。
Failure/Error: expect(current_path).to eq '/users/1'
expected: "/users/1"
got: "/users/122"
(compared using ==)
# ./spec/requests/users_login_spec.rb:16:in `block (3 levels) in <main>'
这里是测试代码。
spec/requests/users_login_spec.rb
require "rails_helper"
RSpec.describe "User login", type: :request do
before do
@user = FactoryBot.create(:user)
end
context "login test" do
it "Enabled users can log in successfully"do
visit root_path
visit login_path
fill_in 'session[email]', with: @user.email
fill_in 'session[password]', with: @user.password
click_button 'Log in'
expect(current_path).to eq '/users/1'
end
end
end
这是factorybot测试用户文件。
spec/factories/users.rb
FactoryBot.define do
factory :user do
name { 'username' }
email {Faker::Internet.free_email}
password { 'password' }
password_confirmation { 'password' }
activated { true }
activated_at { Time.zone.now }
trait :admin do
admin { true }
end
trait :no_activated do
activated { false }
activated_at { nil }
end
end
end
Gemfile.
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", "7.0.4"
gem "ransack"
gem "image_processing", "1.12.2"
gem "active_storage_validations", "0.9.8"
gem "bcrypt", "3.1.18"
gem "faker", "2.21.0"
gem "will_paginate", "3.3.1"
gem "bootstrap-will_paginate", "1.0.0"
gem "bootstrap-sass", "3.4.1"
gem "sassc-rails", "2.1.2"
gem "sprockets-rails", "3.4.2"
gem "importmap-rails", "1.1.0"
gem "turbo-rails", "1.1.1"
gem "stimulus-rails", "1.0.4"
gem "jbuilder", "2.11.5"
gem "puma", "5.6.4"
gem "bootsnap", "1.12.0", require: false
group :development, :test do
gem "mysql2"
gem "debug", "1.5.0", platforms: %i[ mri mingw x64_mingw ]
gem "rspec-rails"
gem 'guard-rspec', require: false
gem "rspec_junit_formatter"
gem 'factory_bot_rails'
end
group :development do
gem "web-console", "4.2.0"
end
group :test do
gem "capybara", "3.37.1"
gem "selenium-webdriver", "4.2.0"
gem "rails-controller-testing", "1.0.5"
gem "minitest", "5.15.0"
gem "minitest-reporters", "1.5.0"
gem "guard", "2.18.0"
gem "guard-minitest", "2.4.6"
gem 'rspec-rails'
gem 'spring-commands-rspec'
gem 'factory_bot_rails'
gem 'database_cleaner'
gem 'launchy'
end
group :production do
gem "aws-sdk-s3", "1.114.0", require: false
end
gem "erb-formatter", "~> 0.4.1"
gem "dockerfile-rails", ">= 1.0", :group => :development
会话控制器中用于登录的创建方法。 但这不太可能是错误的。 因为即使在应用程序上实际以用户 1 身份登录,我也被重定向到 users/1.
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by(email: params[:session][:email].downcase)
if user && user.authenticate(params[:session][:password])
if user.activated?
forwarding_url = session[:forwarding_url]
reset_session
params[:session][:remember_me] == '1' ? remember(user) : forget(user)
log_in user
redirect_to forwarding_url || user
else
message = "Account not activated. "
message += "Check your email for the activation link."
flash[:warning] = message
redirect_to root_url
end
else
flash.now[:danger] = 'Invalid email/password combination'
render 'new', status: :unprocessable_entity
end
end
def destroy
log_out if logged_in?
redirect_to root_url, status: :see_other
end
end
我已经将 docker 引入到现有的 Rails 应用程序中。 引入之前没有出现这个错误。 这是 docker 容器配置。(e_note 是我的应用程序)
测试用的容器test-db有问题吗? 这些是 docker 相关文件。
docker-compose.yml
version: "3.8"
services:
db:
image: mysql:8.0.32
volumes:
- dbvolume:/opt/homebrew/bin/mysql/data
platform: linux/x86_64
env_file: development.env
test-db:
image: mysql:8.0.32
volumes:
- dbvolume:/opt/homebrew/bin/mysql/data2
environment:
MYSQL_DATABASE: docker_test
MYSQL_ROOT_PASSWORD: password
MYSQL_USER: test_user
MYSQL_PASSWORD: passw0rd
platform: linux/x86_64
web:
build:
context: .
dockerfile: Dockerfile
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/e_note
- gem_data:/usr/local/bundle
ports:
- "3000:3000"
depends_on:
- db
- test-db
env_file: development.env
stdin_open: true
tty: true
command: bundle exec rails server -b 0.0.0.0
volumes:
dbvolume:
gem_data:
Dockerfile
FROM ruby:3.2.0
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
mariadb-client \
nodejs \
vim \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /e_note
COPY Gemfile /e_note/Gemfile
COPY Gemfile.lock /e_note/Gemfile.lock
RUN gem install bundler
RUN bundle install
COPY . /e_note
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
这是一个数据库文件。
database.yml
# MySQL. Versions 8.0.32 and up are supported.
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: user # development.envで記載したユーザ名
password: <%= ENV["MYSQL_PASSWORD"] %>
socket: /tmp/mysql.sock
host: db
development:
<<: *default
database: e_note_development
test:
<<: *default
username: test_user
password: passw0rd
database: docker_test
host: test-db
production:
<<: *default
database: e_note_production
username: <%= Rails.application.credentials.db[:user_name] %>
password: <%= Rails.application.credentials.db[:password] %>
host: <%= Rails.application.credentials.db[:endpoint] %>
pool: 20
timeout: 1000
第一次出现这样的错误
我可能忘了粘贴一些信息。 如果您当时可以发表评论,那将会很有帮助。
非常感谢。
不要将数据库 ID 硬编码到您的规范中。这绝不是一个好主意。
require "rails_helper"
RSpec.describe "User login", type: :system do
# use let/let! instead to setup test dependencies.
let!(:user) { FactoryBot.create(:user) }
# use descriptions that can be read as plain english.
it "lets enabled users sign in" do
visit root_path
click_link "Sign in" # or whatever link there is in the UI
fill_in 'Email', with: user.email # Use the labels like real person would
fill_in 'Password', with: user.password
click_button 'Log in'
expect(current_path).to eq user_path(user)
end
end
Rails 默认情况下通过使用 transactional tests - 又名 transactional fixtures 处理测试之间的数据库清理。测试包含在数据库事务中,该事务在拆卸阶段回滚。这是一个非常快速的策略,但这样做的一个结果是表的自动递增计数器不会像表在测试之间被删除或截断一样被重置。