我每次测试,测试用户的数量都在增加......?

问题描述 投票:0回答:1

如果这是一个基本问题,我是新手,很抱歉。

我正在使用 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 是我的应用程序) docker config

测试用的容器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

第一次出现这样的错误

我可能忘了粘贴一些信息。 如果您当时可以发表评论,那将会很有帮助。

非常感谢。

ruby-on-rails ruby docker model-view-controller rspec
1个回答
1
投票

不要将数据库 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 处理测试之间的数据库清理。测试包含在数据库事务中,该事务在拆卸阶段回滚。这是一个非常快速的策略,但这样做的一个结果是表的自动递增计数器不会像表在测试之间被删除或截断一样被重置。

© www.soinside.com 2019 - 2024. All rights reserved.