More than a decade using RSpec has left me flummoxed in terms of "classical" Rails testing. I'm on a new project built using the Jumpstart application template and all the tests are standard Rails tests so here's a quick recap that I wrote, well, to force myself to step back in time and go "old school". And if you don't like my version then you should really read this. And if you are using Devise for authentication then you really must read this.
Making Tests Debuggable
The ability to use byebug in a testing context for breakpoints and stepping through code is utterly invaluable. Here's what you need to do for that:
- Add byebug into a development, test group in Gemfile.
- Add the line require 'byebug' to the very top of test_helper.rb
How Do You Skip a Test?
You put the keyword 'skip' at the top of the test that you need to skip. This is equivalent to xit in RSpec.
The very basic of testing is nothing more than test execution so to run all model tests:
rails test test/models/
and to run one file
rails test test/models/user_test.rb
and to run everything:
and to run with verbose mode:
rails test -v test/models
and to run verbosely and fail on the first test failure:
rails test -v -f test/helpers/application_helper.rb
and to run just one specific test:
rails test test/controllers/labels_controller_test.rb:9
Note: RSpec is very good at running the next test if the line number shifts a bit (example you put in :8 but you added a line so its actually :9). With standard rails test, you get this madness:
❯ rails test test/controllers/projects_controller_test.rb:17 Running via Spring preloader in process 95090 Run options: --seed 52687 # Running: Finished in 0.010622s, 0.0000 runs/s, 0.0000 assertions/s. 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
The 0 runs, 0 assertions, 0 failures, 0 errors, 0 skips can best be interpreted as:
Yo! Hoser! I don't know what to do here so I'm going to confuse you deliberately. Ha Haw!
Death to Fixtures; Viva La Factory Bot
Within the RSpec world, we long, long ago tossed out the concept of static fixtures and embraced the world of Factories via FactoryBot. I haven't used classical Rails testing with FactoryBot before but here's what to do:
- Add FactoryBot to Gemfile in a test section.
- Run bundle install.
- Create a factories directory mkdir test/factories
- Generate a sample factory
- Add include FactoryBot::Syntax::Methods to the top of test/test_helper.rb
- Stop spring with bin/spring stop
- Start spring with bin/spring start
- Write a simple test using FactoryBot like my test foo blog post.
- Run the test.
Here's a sample test using my foo example:
require 'test_helper' class LabelTest < ActiveSupport::TestCase test 'should return foo' do subject = FactoryBot.create(:label) assert_equal subject.foo, 'bar' end test 'should return FOO' do assert_equal Label.foo, 'BAR' end end
As shown above, the canonical test operator is assert_something (or just assert). Above I am using assert_equal but there are lots of assertion statements including:
- assert_difference do
- assert_no_difference do
And I am certain that there are more but this is a decent sampling of most of the assertion statements that I can remember using once upon a time.
Here's a minimal example of assert_redirected_to:
test "should get index and redirect to / when logged in and no projects" do get labels_url assert_redirected_to new_user_session_path end