Rails Minitest inconsistent data after setup - ruby-on-rails

I've been hitting my head with following issue with no luck:
Trying to test that a rake task populates some tables correctly, I have following configuration:
class InitialDataTest < ApplicationSystemTestCase
def setup
DatabaseCleaner.clean_with :truncation, only: %w[centres projects departments]
System::Application.load_tasks
Rake::Task['populate_lookup_tables:commit'].invoke
sign_in users(:test_user)
end
test 'projects are created' do
puts " Projects: #{Project.count}"
end
test 'centres are created' do
puts "Centres: #{Centre.count}"
end
test 'departments are created' do
puts " Departments: #{Department.count}"
end
end
My rake task actually works as expected (in development, for instance) however, for the test it seems that only 1 table is being populated:
Running via Spring preloader in process 15362
Started with run options --seed 17058
:: Centre populated successfully
:: Project populated successfully
:: Department populated successfully
>> OperationType is not empty
>> DocumentType is not empty
>> RecordErrorType is not empty
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.3-p222), codename: Private Caller
* Min threads: 0, max threads: 1
* Environment: test
* Listening on tcp://0.0.0.0:51272
Use Ctrl-C to stop
Departments: 5
Centres: 0
Projects: 0
3/3[========================================================] 100% Time: 00:00:03, Time: 00:00:03
Finished in 3.88633s
3 tests, 0 assertions, 0 failures, 0 errors, 0 skips
Coverage report generated for Unit Tests to <My Stuff> (28.45%) covered.

By default, Rake task can be only invoked once in a given context. If you want to run it again you need to call Rake::Task['populate_lookup_tables:commit'].reenable first.

Related

Rspec always exits with code 1 when simplecov is enabled

I have a Ruby on Rails 6.1 application I am testing with rspec 3.10, all tests passing and it exits with code 0. When I add Simplecov (using 0.21.2) the exit code is always 1.
My simplecov configuration:
# spec/rails_helper.rb
require 'simplecov'
if !ENV["NO_COVERAGE"]
SimpleCov.start :rails do
minimum_coverage 0
minimum_coverage_by_file 0
filesize = Proc.new { |source_file| source_file.lines.count < 10 }
add_group "Workers", "/app/workers"
add_group "Builders", "/app/builders"
add_group "Queries", "/app/queries"
add_group "Decorators", "/app/decorators"
end
end
Example output (from a Github action)
Finished in 4 minutes 18.1 seconds (files took 11.15 seconds to load)
2415 examples, 0 failures, 154 pending
Randomized with seed 29170
Coverage report generated for RSpec to /app/coverage. 8665 / 13736 LOC (63.08%) covered.
1
Error: Process completed with exit code 1.
If I remove or disable simplecov everything works fine. If I turn it back on, exit code is always 1. This happens on GH Actions, my dev machine and inside Docker containers.
Am I doing something wrong? How do I get simplecov to always return 0 since I don't care about minimum coverage anyway?

Rails 6 doesn't output the result of system tests (with rails test:system)

My Rails application doesn't output the result of the system tests (no failures, no assertions, nothing). The funny thing is that I can see chrome doing what it was expected to do (filling fields, etc...), but when the test is finished, no output on the shell, just the following:
francesco.mari#MB68D:DemographicsMapper (inline_mapping_editing *) $ bin/rails test:system
Puma starting in single mode...
* Version 4.3.8 (ruby 2.6.6-p146), codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Environment: test
* Listening on tcp://127.0.0.1:49330
Use Ctrl-C to stop
francesco.mari#MB68D:DemographicsMapper (inline_mapping_editing *)
Apparently the issue was on the file test_helper.rb. After I added the line parallelize(workers: :number_of_processors) it worked as it should.
class ActiveSupport::TestCase
#...
parallelize(workers: :number_of_processors) # added this line
#...
end

Foreman terminates after the whole process and doesn't run accordingly as defined in Procfile

I am working on importing data from web based CSV into database, so I created a rake task that imports data into database. However I tried to make running my rails app a little seamless and I integrated the import rake task and running rails server into foreman.
However, when I run foreman start, the processes start but terminates after the rake task finishes. I also will like that rake task to start first before running rails s
Here is what I have done below:
lib/tasks/web_import.rake
require 'open-uri'
require 'csv'
namespace :web_import do
desc 'Import users from csv'
task users: :environment do
url = 'http://blablabla.com/content/people.csv'
# I forced encoding so avoid UndefinedConversionError "\xC3" from ASCII-8BIT to UTF-8
csv_string = open(url).read.force_encoding('UTF-8')
counter = 0
duplicate_counter = 0
user = []
CSV.parse(csv_string, headers: true, header_converters: :symbol) do |row|
next unless row[:name].present? && row[:email_address].present?
user = CsvImporter::User.create row.to_h
if user.persisted?
counter += 1
else
duplicate_counter += 1
end
end
p "Email duplicate record: #{user.email_address} - #{user.errors.full_messages.join(',')}" if user.errors.any?
p "Imported #{counter} users, #{duplicate_counter} duplicate rows ain't added in total"
end
end
Procfile
rake: rake web_import:users
server: rails s
when I run forman start, the image below shows the process
I will like the rake task in the foreman to run first before running rails s command. I also don't want it to terminate by itself. I don't know what am doing wrong.
Any help is appreciated.
I solved this by refactoring the Procfile. Instead of having two tasks, I merged it to just one command using && so I can determine which command takes the prefix and which one takes the suffix.
So I changed the profile to:
tasks: rake web_import:users && rails s -p 3000
With this I have my import run first and server command being the last.
If you noticed, I added port with -p flap so as not make sure server is listening on port 3000. Note adding port is optional.
I hope this helps someone as well.

How to setup error 404 page in Ruby on Rails system testing

Rails 5.1 introduced system testing that uses Capybara with Selenium to test the UI of Rails application.
I'm wondering to how to use this system testing to test the UI of error pages.
For standard controller tests, we can do something like below to assert response to be 404.
test 'should get not_found' do
get errors_not_found_url
assert_response :not_found
end
But for system tests, if I go to a 404 page, exception will be thrown in controller level and tests terminate immediately without rendering the page.
test '404 page should render with the correct title' do
# act.
visit NOT_FOUND_URL
# assert.
assert_equal("#{APP_NAME} - #{TITLE_404}", page.title)
end
Exception is thrown in controller level.
$ rails test test/system/error/error_page_test.rb
Run options: --seed 30076
# Running:
Puma starting in single mode...
* Version 3.9.1 (ruby 2.3.1-p112), codename: Private Caller
* Min threads: 0, max threads: 1
* Environment: test
* Listening on tcp://0.0.0.0:55237
Use Ctrl-C to stop
2017-07-09 11:10:45 +1200: Rack app error handling request { GET /books/12345678 }
#<ActionController::RoutingError: Could not find book '12345678' by id or name>
/myapp/app/controllers/books_controller.rb:7:in `index'
/Users/yze14/.rvm/gems/ruby-2.3.1/gems/actionpack-5.1.2/lib/action_controller/metal/basic_implicit_render.rb:4:in `send_action'
/Users/yze14/.rvm/gems/ruby-2.3.1/gems/actionpack-5.1.2/lib/abstract_controller/base.rb:186:in `process_action'
...
Under development/test environment, config.consider_all_requests_local can be set to false in order to show error page instead of stracktrace. But this doesn't swallow exception during system tests.
If you don't want Capybara to re-raise server exceptions in the tests you can set Capybara.raise_server_errors = false.
Secondly, you should check your Gemfile and make sure any gems like web-console,better-errrors, etc are only loaded in the development environment (not in the test environment)
Finally, you shouldn't be using assert_equal with title, you should be using the Capybara provided assert_title which includes waiting/retrying behavior and will reduce potential flakiness in tests.
assert_title("#{APP_NAME} - #{TITLE_404}")

Running tests for ruby on rails

I use RubyMine, Windows
I wrote test:
class PostTest < ActiveSupport::TestCase
# Replace this with your real tests.
fixtures :posts
test "the truth" do
#first_posts = posts(:first_posts)
assert #first_posts.title == "Ruby on rails"
end
end
But when I run test with rubyMine ( with bottom button I select "test" and run it)
i get this
C:\Ruby187\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:\Ruby187\bin/rake test
Testing started at 1:44 PM ...
(in D:/Projects/TestProject)
Empty test suite.
0 tests, 0 assertions, 0 failures, 0 errors
Test suite finished: 0.031002 seconds
Errors running test:units!
Empty test suite.
Process finished with exit code 1
E.g my test suite is empty, but test suite has one test: "the truth"
When i run tests from console (ruby post_test.rb), I have
D:\Projects\TestProject\test>ruby unit/post_test.rb
Loaded suite unit/post_test
Started
Ruby on rails
.
Finished in 1.7471 seconds.
1 tests, 1 assertions, 0 failures, 0 errorsWhat's wrong?
This bug RubyMine (build 98.47) http://youtrack.jetbrains.net/issue/RUBY-6158

Resources