To make the guide practical and easy to follow, we will use an app for noting and sharing **Recipes**. We start from a fresh `rails new`, add features step by step, and grow complexity as we go. While we add features we will add **tests beside the code** so you always see how Minitest fits a real codebase.

## Assumptions

- Ruby is installed.

  If you do not have Ruby yet, use rbenv, asdf, mise, or another version manager you like. That makes it easy to switch Ruby per project. You can also start from the [official Ruby installation guide](https://www.ruby-lang.org/en/documentation/installation/?utm_source=minitestrails.com).

  Once the Ruby is installed, make sure it's available by checking the version:

  ```bash
  ruby -v
  ```

  Example output:

  ```text
  ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]
  ```

- Rails is installed.

  To generate a new app, you need Rails already installed globally. Make sure to have that ready. Once the Ruby is setup you can install latest version of Rails with `gem install rails`.

  You can check the version of Rails with:

  ```bash
  gem install rails
  rails -v
  ```

  Example output:

  ```text
  Rails 8.1.3
  ```

## What you will do in this chapter

- You will generate the Recipes app
- Install gems
- Prepare the test database
- Run the default Minitest suite so you trust your machine before we talk theory 
in the next chapter

By the end you should get **green** output from `bin/rails test:all` at the root of your `recipes` app.

## Generate the Recipes app

Onto the exciting part, we will generate a new Rails app for Recipes 
that we will be using for adding features and tests. 

1. Open a terminal.
2. `cd` to the folder where you keep projects (change the path to match your machine):

   ```bash
   cd ~/projects
   ```

3. Confirm where you are:

   ```bash
   pwd
   ```

    You should see the path you expect. The next command will create a **sibling** folder next to whatever else lives here.

4. Generate the app

    ```bash
    rails new recipes
    ```

   `rails new` creates a directory named `recipes` and fills it with a full Rails skeleton.

### What each part of the command means

| Part | Meaning |
|------|---------|
| `rails new` | Rails generator. Creates a new application skeleton. |
| `recipes` | Directory name and default module name. That is the **Recipes** app for the rest of the guide. |

### What you should see

When the generator finishes, list the new folder:

```bash
ls recipes
```

You should see `app/`, `config/`, `db/`, `test/`, `Gemfile`, `config.ru`, and other usual Rails files.

This means Rails app is now setup.

## System test gems in the Gemfile

Open `Gemfile` and find the **`group :test do`** block. It should include:

```ruby
group :test do
  # Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
  gem "capybara"
  gem "selenium-webdriver"
end
```

Ensure these two gems are inside the Gemfile, they are required for system tests to work properly.

**_NOTE_:** If those lines are missing, add them under `group :test`, save, then run `bundle install` again.

## First git commit

This step is optional but recommended. Make a first commit so you can roll back if a later step goes wrong:

```bash
  cd recipes
  git status
  git add .
  git commit -m "Initialize Recipes app"
```


## What is inside `test/`

Let's take a look at files and folders inside the `test` folder. To do that, hit the following command from the app root:

```bash
ls test
```

You should always see at least:

| Path | Role |
|------|------|
| `test/test_helper.rb` | Boots **test**, loads `rails/test_help`, shared Minitest setup (for example **fixtures** and **parallel** workers). |
| `test/controllers/` | Controller tests when you use them. |
| `test/models/` | Model tests: validations, scopes, plain Ruby on your models. |
| `test/integration/` | Integration tests: full HTTP cycle through routing, controller, and often views. |
| `test/fixtures/` | YAML **fixtures** for sample rows. |
| `test/mailers/` | Mailer tests. |
| `test/helpers/` | Helper tests (we use them rarely). |

### Why `test/system` might be empty at first

On a plain Rails 8 app, the **`test/system`** directory and **`test/application_system_test_case.rb`** file are often not created until you generate your first system test. Maintainers summarized the default like this:

> System tests are a nice to have but don't make sense to be generated by default since you don't want to test every endpoint this way. They should be used for testing critical paths, especially where JS is involved.

We will still use system tests where they earn their keep: **critical flows** and **smoke checks** that the app boots in a real browser.

Don't worry about missing folder and file yet, we will get both of them when we generate one system test in the app later in this chapter, we will talk more about these files and folder there. For more detail about the removal decision of system tests from defaults, you can check following pull requests in the Rails repository:

- [Skip all system test files on app generation](https://github.com/rails/rails/pull/56272?utm_source=minitestrails.com)
- [Don't generate system tests by default](https://github.com/rails/rails/pull/55743?utm_source=minitestrails.com)

## Prepare the test database

Rails uses a **separate** database for `RAILS_ENV=test`. Prepare it once so you do not chase connection errors during your first run:

```bash
RAILS_ENV=test bin/rails db:prepare
```

What that does:

- Loads the app in **test**
- Creates the test database if it is missing
- Applies the schema so it matches **`db/schema.rb`**

## Run non-system tests

```bash
bin/rails test
```

That runs everything under **`test/`** **except** files inside **`test/system`**. Use it when you want a fast loop without booting the browser.

### How to read the output

Example shape:

```text
Run options: --seed 12345

# Running:

..

Finished in 0.012345s, 161.8 runs/s, 161.8 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
```

- **runs** — how many `test "..." do` blocks ran
- **assertions** — how many `assert_*` calls ran
- **failures** — failed assertions
- **errors** — unexpected exceptions
- **skips** — tests you marked skipped with `skip "this test"` inside the test block

A brand new app ships a small number of sample tests. The exact counts are not important. You want 0 failures and 0 errors.

## Add system tests (generator + smoke test)

Right now we don't have any system test setup because Rails 8 doesn't ship that by 
default as already noted in previous sections. So, let's now setup the system test and 
add one simple system test to ensure it's working.

Generate a system test scaffold:

```bash
bin/rails generate system_test rails_default_pages
```

That should create (names matter):

| File | Role |
|------|------|
| `test/application_system_test_case.rb` | Base class for every system test: Capybara + **Selenium** driver. |
| `test/system/rails_default_pages_test.rb` | First system test file (we replace its body in a moment). |

### What is inside `test/application_system_test_case.rb`

```ruby
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :headless_chrome, screen_size: [ 1400, 1400 ]
end
```

- **`require "test_helper"`** — same boot path as other tests (`ENV`, `config/environment`, Minitest helpers).
- **`ApplicationSystemTestCase`** — inherits **`ActionDispatch::SystemTestCase`**, Rails wrapper around Capybara + a driver.
- **`driven_by :selenium, using: :headless_chrome, ...`** — runs **Chrome** without opening a window. Good for day to day runs.

**_NOTE_:** You need a working **Chrome** or **Chromium** install for system tests to work. If `bin/rails test:system` fails with a driver error, install Chrome and retry.

### Smoke test for `/up`

A new Rails app already exposes the **health check** at **`/up`** (see `config/routes.rb`). That gives a boring, stable URL for your first visit.

Replace **`test/system/rails_default_pages_test.rb`** with:

```ruby
require "application_system_test_case"

class RailsDefaultPagesTest < ApplicationSystemTestCase
  test "health check responds over the browser" do
    visit "/up"
    assert_current_path "/up"
  end
end
```

<%= render Shared::Tip.new(
  title: "New assertions",
  markdown: <<~MD
    1. **`visit "/up"`**
      Opens a URL in the test browser.

    2. **`assert_current_path "/up"`** asks "is the browser on this path?"
      Syntax: `assert_current_path` plus the path string. Fails if a redirect or typo sent you somewhere else.
  MD
) %>

Line by line:

- **`test "..." do`** — names the example in Minitest output.
- **`visit "/up"`** — Capybara drives the browser to that path on the test server (not necessarily port 3000; Rails picks a free port).
- **`assert_current_path "/up"`** — Checks if the URL in the browser equals `/up` or not. Fails the test if the URL doesn't match.

Run system tests only:

```bash
bin/rails test:system
```

You want **`0 failures`** and **`0 errors`**. Assertion count can differ slightly by Rails version; the important part is green.

<%= render Guide::SupportCta.new(
  variant: :mid_chapter,
  site_metadata: site.data.site_metadata,
  milestone_hook: "You have a real browser test running now, not just theory, and that is exactly the kind of milestone this guide is built around.",
  headline: "You just shipped your first system smoke test.",
  body_text: "Getting system tests green on a fresh app is where many guides hand-wave. If this chapter got you past that setup wall, fund the next chapter and keep the guide free."
) %>

## Run everything together

You can also run all tests (**unit, integration, and system**) in one go. On a fresh app it is a quick confidence check before you start building features. You can run them all with the following command:

```bash
bin/rails test:all
```

That runs **non-system** tests **and** **`test/system`** in one go. After this chapter you should see at least the default tests **plus** your **`/up`** system test in the combined output.

## Commit your work

Once `bin/rails test:all` is green, save what you added in this chapter:

```bash
git add .
git commit -m "Add system tests and /up health check smoke test"
```

That commit usually includes the Capybara gems in your `Gemfile`, `test/application_system_test_case.rb`, and `test/system/rails_default_pages_test.rb`. Small checkpoints like this make it easier to roll back one step or see exactly when something broke.

If you already made the optional **Initialize Recipes app** commit earlier, treat this as your second checkpoint. If you skipped that step, you can commit twice (initialize, then system tests) or use one message that covers both. Either way, get a green `bin/rails test:all` on disk before you continue.

## End of Chapter 1

You now have:

- A **Recipes** app with **Minitest** under **`test/`**
- **Capybara** and **Selenium** ready for **system tests**
- A green starting point for the Recipes app that you will begin building in chapter 5
- A green **`bin/rails test:all`** on your machine

You have not built recipe pages, validations, or mailers yet. That is intentional. Chapters 2 through 4 are vocabulary and approach (map, tools, scenarios). [Chapter 5](/guide/your-first-test/) is the first time you add Recipe code and automated tests.

When you are ready, continue to **[Types of Tests in the Rails World](/guide/kinds-of-rails-tests/)**.
