Introduction
I started learning automated tests back in 2020. It was due to an invoicing feature we had in a Telecom application which was a big and very crucial feature but had no test coverage, so any time I had to touch that file it involved a lot of manual testing to ensure nothing was breaking. I wanted to save time and have a peace of mind so I had to start automating those logics covering all edge cases. This is how the journey of automated tests started for me. But it wasn’t easy, let me tell you why.
First step of learning was realizing I needed to learn writing tests and now the next step was to figure out “how”. I knew I should write tests but the next main question now was “Where do I start?”
I still clearly remember the feeling of helplessness during that time not knowing where and how to start. I knew about the term “Capybara” at that time, and you will laugh when I tell you about the query I searched in the Google: “How to write model and validation tests using Capybara”. That’s the level of proficiency I had at test concepts; total layman. For those who don’t know, Capybara is used for writing system tests that interact with browsers while model/validations fall into unit tests. This is the first reason I want this guide to exist; I don’t want you to feel the same helplessness I felt and I want to help you answer questions like “Why should I write tests?” and “How do I get started with writing tests?”.
Over the time, I slowly learnt writing tests with RSpec. Through Twitter I also found an unofficial mentor (hi @sowenjub), I would go and ask random questions and he would help me figure things out. I am forever grateful to Arnaud for answering all my questions and not complaining even once.
I started with RSpec because whenever I searched “testing in Rails”, I always ended up with blogs that mostly used RSpec. I didn’t know at that time “minitest” existed and it was the default in Rails. It was only in 2024 I truly jumped to Minitest. I feel the reason Minitest doesn’t feel as accessible as RSpec is that there are fewer beginner friendly, practical guides for it. That’s another reason I am writing this guide; I want this to be a go-to guide for all beginners who are starting with their first automated tests with Rails and Minitest.
That’s the background of my journey and why I want this guide to exist as well as be free. Now let’s talk about the guide itself.
What’s in the guide #
With the guide, you’ll learn to test Rails applications with Minitest from the ground up: step by step, one topic at a time. The goal is to make Minitest as approachable as RSpec so that when someone searches for “testing in Rails” or “Minitest Rails”, they can find this guide, stick to the default stack provided by Rails and kickstart their automated testing journey without having to switch the test framework.
Here is what’s inside this guide in order:
| Topic | Description |
|---|---|
| Basic Rails App setup with Minitest and System Tests | Spin up the Recipes app with the Rails default with one addition: system tests which has been removed from defaults from Rails 8. Enough Capybara wiring to follow later chapters. |
| Types of tests | How unit (model), integration (request), and system (browser) tests differ in Minitest land, and when each is a good fit. |
| Approaching automated tests as a beginner | A simple loop when you feel stuck: what you would check by hand, what you are actually varying in the test, and how you will know it passed. Now automate all of that with Minitest. |
| Various tools used in Rails for testing | Minitest, fixtures, Capybara, and when something like WebMock or VCR earns a place. |
| Your first automated test: homepage loads without error | One small green test in the real app so you practice running the suite and trusting a passing run. |
| Fixtures: introduction and setup tips | YAML fixtures, associations, and keeping data predictable so later tests do not fight random state. |
| Simple CRUD system tests | Drive the browser through list, show, create, update, and delete for Recipes using the fixture data you set up earlier. |
| Testing models | Validations, scopes and methods. What to test and when. |
| Doubles and Stubs | What doubles and stubs buy you in Minitest and when each is a good fit so tests stay readable without mocking the whole world. |
| Adding more complexity: a second resource and associations | Grow Recipes with nested resources, more system and model tests, and nested params without losing the thread of one app. |
| E2E and Integration tests for Controllers/Requests | When request or controller tests earn their keep instead of pushing everything through a time consuming system test. |
| Authentication / Authorization Tests | Who can hit which actions, signed-in and signed-out flows, ownership, and redirects. |
| Sending your first email: Mailer tests | Keep mailers thin, assert on body and delivery, use fixtures for related records, and stub only when the scenario really needs it. |
| Background Jobs and their tests | Exercise enqueue and perform paths, keep jobs thin. |
| Mock external services | Stub and record HTTP with WebMock and VCR so tests don’t hit the real network and stay deterministic in CI. |
| Adding tests to an existing app | A practical order of attack when the codebase already exists: align on goals, start where tests are easiest to add, then widen coverage. |
| Test coverage: what and how much to cover | Why there is no magic percentage, and which team pains usually mean you need more tests (bugs, fear of deploy, manual regression, refactor paralysis). |
| Setting testing habits and TDD | Building a routine around tests, when test-first actually helps, and when writing tests after is fine. |
| Running tests in CI | Run the same suite in GitHub Actions or similar CI: databases, env vars, headless browsers for system tests, and keeping the pipeline boring and reliable. |
What you’ll use: the Recipes app #
I feel you learn faster when there are practical examples you can go through by writing the code by hand. This is why in this guide we will take a simple example app for Recipes and build it piece by piece.
We start simple (one resource, basic CRUD) and grow it as we go: validations, associations, fixtures, system tests, mailers, jobs, and more. You’re not jumping between unrelated examples. You build one app and test it at each stage. That way you see how tests fit into a real codebase.
If you follow along in order, you can build the Recipes app as you read and run the tests yourself. Each chapter assumes you’ve seen the previous ones though it won’t be too hard to wrap your head around even if you do jump between chapters but I don’t recommend that at least for beginners.
Who is this guide for #
This guide is aimed first at beginners who are new to writing tests in Rails and don’t know where to start. If that’s you, we’ll go step by step with Rails defaults (Minitest, fixtures) and one app so you can build a habit without the noise. It’s also for mid and senior developers. Maybe you’ve been testing in RSpec and want to see how Minitest holds up, or you’re adding tests to a legacy app and want a clear pattern to follow. Maybe you just want a single place to look up how to test mailers, jobs, or file uploads. There’s something here for everyone.
More than a one-time read #
This guide is also the base for a practical handbook. As we add chapters and a blog section, you’ll find concrete tips and tricks (for example: How do I test file uploads in Rails? How do I test a “share this recipe” email?). The aim is to be the place you come back to when you hit a specific “how do I…?” in your day-to-day work.
Ready to set up a Rails app with Minitest and run your first test? Head to the next chapter.
Disclaimer
This guide is written in tandem with AI but reviewed and enhanced by me based on my experience with Rails and testing. I stand by the advice and patterns here.