Now that we know more about testing strategies and principles let's write some tests. From here and now, I'll try to do everything inside a dummy project and show you how to do something there. The steps I’ll follow are:
-
1. Create and empty Rails project
- 2. Configure our test suite
- 3. Create a scaffold
- 4. Write tests
1. Create and empty Rails project
rails new blog
2. Configure our test suite.
Now we're going to do the most important part. But first we need to have this context:
* Almost no one uses mini-test to write testing in real world Rails projects. So, if you want to know about how mini-test works, go ahead. But I highly recommend focusing on RSpec. RSpec is the library for writing tests in real world Rails projects. Spend your learning time wisely
* Almost no one uses Ruby without any framework. So don't spend time making fancy things with RSpec and Ruby. Instead spend your time learning about Rspec and Rails. I said this because a lot of tutorials focus on Ruby and RSpec, and that doesn't make any sense, since in real world projects you'll be working on Rails projects. Spend your learning time wisely
* Save these steps for the future, because this is the way you'll be always configuring your test suite. Is a repetitive process. First it will be a lot of fun, but in the 3th project it'll feel boring. Believe me
* What if we have a project running but we don't have RSpec and any test at all and we want to configure everything? These next steps change slightly, but almost all of them will work exactly the same. We’ll be talking about this in other blog post
So, let's begin. In your Gemfile you need to add rspec-rails gem
# Gemfile
group :development, :test do
...
gem 'rspec-rails'
end
Now, from the console run
$ bundle install
$ rails generate rspec:install
Now let's check our database configuration. Look for this file: /config/database.yml and you'll see this line (since we're using sqlite3 as default database)
default: &default
adapter: sqlite3
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
timeout: 5000
# other code here
test:
<<: *default
database: db/test.sqlite3
This line means that the test database is going to use the default setup, with the sqlite3 adapter and that the database is going to be named as test.sqlite3. Right there is where our RSpec suite is going to save our test data, like Factories. We’ll have a blog post about Factories later
Now let's make RSpec as our default tests generator. What does this means? is simple, each time you run a rails generator, like
$ rails g model ...
$ rails g migration ...
$ rails g controller ...
These commands will create dummy tests for you in mini-test (the default test suite in Rails). As we mentioned before, we'll be using RSpec almost always in real world projects, so that files will become obsolete from the very beginning. We need to generate the same files, but in RSpec. How do we do that? Changing these lines of code
# config/application.rb
...
module Blog
class Application < Rails::Application
...
# add the following lines
config.generators do |g|
g.test_framework :rspec, fixture: true
g.fixture_replacement :factory_bot, dir: 'spec/factories'
g.view_specs false
g.helper_specs false
end
end
end
With these, each time we run generators, we'll have the RSpec working for us, creating the necessary files and dummy tests
Preparing the database.
Now that we have almost everything in place, we need to prepare our database. Let's run these commands
$ rails db:migrate
$ rails db:test:prepare RAILS_ENV=test
$ rails db:migrate RAILS_ENV=test
Even we can access to our test database with this command
$ rails c -e test
At this point we have everything in place to create our first tests. Let's commit. You can see this commit here:
Configuring RSpec · danielmoralesp/[email protected] (github.com)3. Create a Scaffold
Now we're going to create some resources inside our blog post app. In this case we'll write the Article model with all of the this rails create for us
$ rails g scaffold Article title description:text
$ rails db:migrate
The lines that matter for us here are these
create spec/models/article_spec.rb
create spec/requests/articles_spec.rb
create spec/routing/articles_routing_spec.rb
We can see that these files were created by the generators inside our /config/application.rb These files talk about models, requests and routing specs. You can check those files by yourself. One of them contains a lot of code, like:
spec/requests/articles_spec.rb
Lets run this command first
$ bundle exec rspec
We can see an output like this
***.**********........
Pending: (Failures listed here are expected and do not affect your suite's status)
1) Article add some examples to (or delete) /home/danielmorales1202/danielmorales_project/blog/spec/models/article_spec.rb
# Not yet implemented
# ./spec/models/article_spec.rb:4
...
The important output here are the symbols
***.**********........
I know, it's a bit cryptic the first time you see this. But we can use another command to have a better idea about what is happening
Article
add some examples to (or delete) /home/danielmorales1202/danielmorales_project/blog/spec/models/article_spec.rb (PENDING: Not yet implemented)
/articles
GET /index
renders a successful response (PENDING: Add a hash of attributes valid for your model)
GET /show
renders a successful response (PENDING: Add a hash of attributes valid for your model)
GET /new
renders a successful response
GET /edit
render a successful response (PENDING: Add a hash of attributes valid for your model)
Now we have a better idea about what's happening. We have pending tests and other passes now. For instance:
/articles
GET /new
renders a successful response
This is a successful test! and we cannot write a single line of text. The generator did all of that for us.
On the next blog post we'll go deeper on this and write our own tests
Thanks for reading
DanielM