英文:
Database data not appearing in Capyara/RSpec system tests
问题
这是您的spec/system/group_index_spec.rb
文件,其中包含一些Ruby代码和测试。以下是其中的一部分内容:
RSpec.describe 'Group Index', type: :system do
let(:user) { User.create(name: 'First User', email: 'test@user.com', password: 'password') }
# ...(省略部分代码)...
it 'displays all groups', js: true do
visit groups_path
expect(page).to have_content('Group 0')
expect(page).to have_content('Group 1')
expect(page).to have_content('Group 2')
expect(page).to have_content('Group 3')
expect(page).to have_content('Group 4')
end
end
请注意,这是测试文件的一部分,用于测试网页应用程序中的组列表页面。如果您需要关于代码的其他翻译,请提供更多详细信息。
英文:
This is my spec/system/group_index_spec.rb
file.
require_relative '../rails_helper'
RSpec.describe 'Group Index', type: :system do
let(:user) { User.create(name: 'First User', email: 'test@user.com', password: 'password') }
before do
# driven_by(:rack_test)
puts 'Creating test data...'
5.times do |i|
group = Group.create(name: "Group #{i}", author: user)
group.icon.attach(io: File.open(Rails.root.join('spec', 'models', 'files', 'test.jpg')), filename: 'test.jpg',
content_type: 'image/jpeg')
5.times do |j|
Entity.create(name: "Entity #{j}", amount: 100, author: user)
end
end
Group.all.each do |group|
group.entities << Entity.all.sample(rand(1..3))
end
Entity.all.each do |entity|
entity.groups << Group.all.sample(rand(1..3))
end
puts 'Logging in...'
visit new_user_session_path
fill_in 'user_email', with: 'test@user.com'
fill_in 'user_password', with: 'password'
click_button 'Log in'
end
it 'displays all groups', js: true do
visit groups_path
expect(page).to have_content('Group 0')
expect(page).to have_content('Group 1')
expect(page).to have_content('Group 2')
expect(page).to have_content('Group 3')
expect(page).to have_content('Group 4')
end
end
When I run this test, I get this error message.
Creating test data...
Logging in...
F
Failures:
1) Group Index displays all groups
Failure/Error: expect(page).to have_content('Group 0')
expected to find text "Group 0" in "CATEGORIES\nNew"
[Screenshot Image]: /home/shasherazi/programming/microverse/budget-app/tmp/capybara/failures_r_spec_example_groups_g
roup_index_displays_all_groups_713.png
# ./spec/system/group_index_spec.rb:36:in `block (2 levels) in <top (required)>'
Finished in 8.22 seconds (files took 1.64 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/system/group_index_spec.rb:34 # Group Index displays all groups
Here is a short video showing the process.
Here is my rails_helper.rb
file that I modified taking advice from the internet.
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails'
require 'capybara/rspec'
require 'database_cleaner'
# Add additional requires below this line. Rails is not loaded until this point!
# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
abort e.to_s.strip
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
# You can uncomment this line to turn off ActiveRecord support entirely.
# config.use_active_record = false
# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, type: :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://rspec.info/features/6-0/rspec-rails
config.infer_spec_type_from_file_location!
# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
Capybara.run_server = true
Capybara.server_port = 7000
Capybara.app_host = "http://localhost:#{Capybara.server_port}"
end
Everything works fine in my dev environment where I am using faker
to create sample data in a similar way. I have spent almost all day today finding the solution to this problem but couldn't. I'll be very grateful to you if you help.
Solution
I needed to call .save
manually to actually save the data. Here is the corrected test file.
require_relative '../rails_helper'
RSpec.describe 'Groups', type: :system do
let(:user) { User.create(name: 'First User', email: 'test@user.com', password: 'password') }
before do
# comment the line below to run tests in browser
driven_by(:rack_test)
puts "\nCreating test data..."
5.times do |i|
group = Group.create(name: "Group #{i}", author: user)
group.icon.attach(io: File.open(Rails.root.join('spec', 'models', 'files', 'test.jpg')), filename: 'test.jpg',
content_type: 'image/jpeg')
group.save
5.times do |j|
entity = Entity.create(name: "Entity #{j}", amount: 100, author: user)
entity.save
end
end
Group.all.each do |group|
group.entities << Entity.all.sample(rand(1..3))
end
Entity.all.each do |entity|
entity.groups << Group.all.sample(rand(1..3))
end
puts 'Logging in...'
visit new_user_session_path
fill_in 'user_email', with: 'test@user.com'
fill_in 'user_password', with: 'password'
click_button 'Log in'
end
after(:all) do
puts "\nCleaning up..."
Group.destroy_all
Entity.destroy_all
User.destroy_all
end
it 'displays all groups, their names, and icons', js: true do
visit groups_path
user.groups.each do |group|
expect(page).to have_content(group.name)
expect(page).to have_css("img[src*='#{group.icon.blob.filename}']")
end
end
end
答案1
得分: 1
你在这里非常关注数据库方面的事情,但这似乎不是你的问题。
我认为在你的测试中,在你的期望之前应该执行pp Group.all
,只是为了确认(对自己来说)这不是一个数据库问题。
你收到的错误消息似乎表明你实际上在分类索引页面(或者出于某种原因,组索引页面正在使用分类索引视图):
预期在"CATEGORIES\nNew"中找到文本"Group 0"
可能保存在/home/shasherazi/programming/microverse/budget-app/tmp/capybara/failures_r_spec_example_groups_group_index_displays_all_groups_713.png
的截图可以帮助你确认这一点,然后你可以开始排除故障。
英文:
You have so much focus here on the DB side of things, but that doesn't seem to be your issue.
I think you should pp Group.all
in your test before your expectation, just to confirm (for yourself) that this is not a DB issue.
The error message you're getting seems to suggest that you're actually on the categories index page (or the groups index page is using the categories index view for some reason):
> expected to find text "Group 0" in "CATEGORIES\nNew"
Probably the screenshot being saved in /home/shasherazi/programming/microverse/budget-app/tmp/capybara/failures_r_spec_example_groups_g
can help you confirm this and you can begin troubleshooting.
roup_index_displays_all_groups_713.png
答案2
得分: 0
这里的问题很可能是您的用户实际上没有登录。这是因为操作是异步进行的,您没有等待登录成功。您的测试实际上是在运行以下代码:
...
visit new_user_session_path
fill_in 'user_email', with: 'test@user.com'
fill_in 'user_password', with: 'password'
click_button 'Log in'
visit groups_path
expect(page).to have_content('Group 0')
...
这将导致visit groups_path
取消了click_button
调用触发的任何请求,并以未经身份验证的用户身份访问组页面。您可以尝试在click_button
之后添加sleep 5
来查看是否可以解决问题。如果可以的话,您应该用实际查找页面变化的方式来替换sleep
,大致如下:
fill_in 'user_password', with: 'password'
click_button 'Log in'
expect(page).to have_content('Logged In')
英文:
The issue here is likely that your user isn't actually logged in. This is because actions happen asynchronously and you're not doing anything to wait for the login to succeed. Your test is effectively running
...
visit new_user_session_path
fill_in 'user_email', with: 'test@user.com'
fill_in 'user_password', with: 'password'
click_button 'Log in'
visit groups_path
expect(page).to have_content('Group 0')
...
Which will cause the visit groups_path
to cancel any request triggered by the click_button
call, and visit the groups page as an unauthenticated user. You can test that by just adding a sleep 5
after the click_button
to see if it fixes your issue. If it does you'll want to replace the sleep
with something that actually looks for a change in the page that indicates the login has completed, along the lines of
fill_in 'user_password', with: 'password'
click_button 'Log in'
expect(page).to have_content('Logged In')
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论