如何使用工厂创建要用 Rspec 和 Capybara 进行测试的测试数据
How to use factories to create test data to be tested with Rspec and Capybara
我正在尝试使用 rspec/capybara 测试我的分页功能。我使用 FactoryBot 创建了文章,但遇到了两个问题。如果我创建数据:
- 在
before
块中,数据保存到数据库中,不会在套件运行后擦除。
- 在场景块中并使用
save_and_open_page
查看数据是否显示在屏幕上,它没有显示。所以,我认为数据没有足够的时间保存。
宝石文件:
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.3'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.4'
gem 'react-rails'
# Use postgresql as the database for Active Record
gem 'pg', '~> 1.1'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false
gem "aws-sdk-s3", require: false
group :development, :test do
gem 'rspec-rails', '~> 5.0.0'
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'factory_bot_rails'
gem 'lorem_ipsum_amet'
gem 'dotenv-rails'
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 4.1.0'
# Display performance information such as SQL time and flame graphs for each request in your browser.
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
end
group :test do
gem 'simplecov', require: false
gem 'codecov', require: false
gem 'capybara'
gem 'webdrivers', '~> 5.0'
gem 'launchy', '~> 2.5'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
这是工厂:
FactoryBot.define do
factory :article do
sequence(:title) {|i| "Article #{i}"}
body {"This is the test body of the article."}
end
end
这是我的测试套件。我只展示了一个例子,因为其余的概念是相同的:
RSpec.feature "Paginations", type: :feature do
before(:all) do
ActionController::Base.allow_forgery_protection = true
# FactoryBot.create_list(:article, 100)
end
before(:each) do
visit articles_path
end
after(:all) do
ActionController::Base.allow_forgery_protection = false
end
scenario "user visits articles home page to see only 10 articles", js: true do
FactoryBot.create_list(:article, 10)
save_and_open_page
expect(page).to have_css "div.item-container-sizing.item-container-padding.flex-row-space-between", count: 10
end
end
这里的主要问题是 out-of-order 执行。您在创建测试所需的对象之前访问页面,因此对象在呈现的页面上不可见(呈现页面时它们不存在)。对于大多数测试,您不希望在 before 块中调用 visit
,除非您有一系列测试都需要相同的测试数据并访问相同的页面。在这种情况下,只需将 visit
移动到场景中即可。此外,不要 over-specify 您要查找的元素的选择器,因为这会使您的测试变得脆弱。您没有显示 html 的样子,但假设此页面仅显示一个文章列表,那么只检查您的 类 中的一篇可能就足够了,或者将您的期望范围限定在一个页面区域,然后使用更通用的 CSS 选择器
scenario "user visits articles home page to see only 10 articles", js: true do
FactoryBot.create_list(:article, 10)
visit articles_path
# save_and_open_page
expect(page).to have_css "div.item-container-sizing.item-container-padding.flex-row-space-between", count: 10
end
我正在尝试使用 rspec/capybara 测试我的分页功能。我使用 FactoryBot 创建了文章,但遇到了两个问题。如果我创建数据:
- 在
before
块中,数据保存到数据库中,不会在套件运行后擦除。 - 在场景块中并使用
save_and_open_page
查看数据是否显示在屏幕上,它没有显示。所以,我认为数据没有足够的时间保存。
宝石文件:
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '3.0.3'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main'
gem 'rails', '~> 6.1.4', '>= 6.1.4.4'
gem 'react-rails'
# Use postgresql as the database for Active Record
gem 'pg', '~> 1.1'
# Use Puma as the app server
gem 'puma', '~> 5.0'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'
# Use Active Storage variant
# gem 'image_processing', '~> 1.2'
# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.4', require: false
gem "aws-sdk-s3", require: false
group :development, :test do
gem 'rspec-rails', '~> 5.0.0'
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
gem 'factory_bot_rails'
gem 'lorem_ipsum_amet'
gem 'dotenv-rails'
end
group :development do
# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem 'web-console', '>= 4.1.0'
# Display performance information such as SQL time and flame graphs for each request in your browser.
# Can be configured to work on production as well see: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/README.md
gem 'rack-mini-profiler', '~> 2.0'
gem 'listen', '~> 3.3'
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
end
group :test do
gem 'simplecov', require: false
gem 'codecov', require: false
gem 'capybara'
gem 'webdrivers', '~> 5.0'
gem 'launchy', '~> 2.5'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
这是工厂:
FactoryBot.define do
factory :article do
sequence(:title) {|i| "Article #{i}"}
body {"This is the test body of the article."}
end
end
这是我的测试套件。我只展示了一个例子,因为其余的概念是相同的:
RSpec.feature "Paginations", type: :feature do
before(:all) do
ActionController::Base.allow_forgery_protection = true
# FactoryBot.create_list(:article, 100)
end
before(:each) do
visit articles_path
end
after(:all) do
ActionController::Base.allow_forgery_protection = false
end
scenario "user visits articles home page to see only 10 articles", js: true do
FactoryBot.create_list(:article, 10)
save_and_open_page
expect(page).to have_css "div.item-container-sizing.item-container-padding.flex-row-space-between", count: 10
end
end
这里的主要问题是 out-of-order 执行。您在创建测试所需的对象之前访问页面,因此对象在呈现的页面上不可见(呈现页面时它们不存在)。对于大多数测试,您不希望在 before 块中调用 visit
,除非您有一系列测试都需要相同的测试数据并访问相同的页面。在这种情况下,只需将 visit
移动到场景中即可。此外,不要 over-specify 您要查找的元素的选择器,因为这会使您的测试变得脆弱。您没有显示 html 的样子,但假设此页面仅显示一个文章列表,那么只检查您的 类 中的一篇可能就足够了,或者将您的期望范围限定在一个页面区域,然后使用更通用的 CSS 选择器
scenario "user visits articles home page to see only 10 articles", js: true do
FactoryBot.create_list(:article, 10)
visit articles_path
# save_and_open_page
expect(page).to have_css "div.item-container-sizing.item-container-padding.flex-row-space-between", count: 10
end