Skip to content

Latest commit

 

History

History
263 lines (181 loc) · 8.12 KB

README.md

File metadata and controls

263 lines (181 loc) · 8.12 KB

mighty_test

Gem Version Gem Downloads GitHub Workflow Status Code Climate maintainability

mighty_test (mt) is a TDD-friendly Minitest runner for Ruby projects. It includes a Jest-inspired interactive watch mode, focus mode, CI sharding, run by directory/file/line number, fail-fast, and color formatting.


Quick Start

Features

Community

Install

The mighty_test gem provides an mt binary. To install it into a Ruby project, first add the gem to your Gemfile and run bundle install.

gem "mighty_test"

Then generate a binstub:

bundle binstub mighty_test

Now you can run mighty_test with bin/mt.

Tip

When installing mighty_test in a Rails project, make sure to put the gem in the :test Gemfile group. Although Rails has a built-in test runner (bin/rails test) that already provides a lot of what mighty_test offers, you can still use bin/mt with Rails projects for its unique --watch mode and CI --shard feature.

Requirements

mighty_test requires modern versions of Minitest and Ruby.

  • Minitest 5.15+
  • Ruby 3.1+

Support for older Ruby versions will be dropped when they reach EOL. The EOL schedule can be found here: https://endoflife.date/ruby

Note

mighty_test currently assumes that your tests are stored in test/ and are named *_test.rb. Watch mode expects implementation files to be in app/ and/or lib/.

Usage

mt defaults to running all tests, excluding slow tests (see the explanation of slow tests below). You can also run tests by directory, file, or line number.

# Run all tests, excluding slow tests
bin/mt

# Run all tests, slow tests included
bin/mt --all

# Run a specific test file
bin/mt test/cli_test.rb

# Run a test by line number
bin/mt test/importer_test.rb:43

# Run a directory of tests
bin/mt test/commands

Tip

mighty_test is optimized for TDD, and excludes slow tests by default. Slow tests are defined as those found in test/{e2e,feature,features,integration,system} directories. You can run slow tests with --all or by specifying a slow test file or directory explicitly, like bin/mt test/system.

⚙️ CI Mode

If the CI environment variable is set, mighty_test defaults to running all tests, including slow tests. This is equivalent to passing --all.

mighty_test can also distribute test files evenly across parallel CI jobs, using the --shard option. The shard nomenclature has been borrowed from similar features in Jest and Playwright.

# Run the 1st group of tests out of 4 total groups
bin/mt --shard 1/4

In GitHub Actions, for example, you can use --shard with a matrix strategy to easily divide tests across N jobs.

jobs:
  test:
    strategy:
      matrix:
        shard:
          - "1/4"
          - "2/4"
          - "3/4"
          - "4/4"
    steps:
      - uses: actions/checkout@v4
      - uses: ruby/setup-ruby@v1
        with:
          bundler-cache: true
      - run: bin/mt --shard ${{ matrix.shard }}

In CircleCI, you can use the parallelism setting, which automatically injects $CIRCLE_NODE_INDEX and $CIRCLE_NODE_TOTAL environment variables. Note that $CIRCLE_NODE_INDEX is zero-indexed, so it needs to be incremented by 1.

jobs:
  test:
    parallelism: 4
    steps:
      - checkout
      - ruby/install-deps
      - run: SHARD="$((${CIRCLE_NODE_INDEX}+1))"; bin/mt --shard ${SHARD}/${CIRCLE_NODE_TOTAL}

Tip

--shard will shuffle tests and automatically distribute slow tests evenly across jobs.

🧑‍🔬 Watch Mode

mighty_test includes a Jest-style watch mode, which can be started with --watch. This is ideal for TDD.

# Start watch mode
bin/mt --watch

In watch mode, mighty_test will listen for file system activity and run a test file whenever it is modified.

When you modify an implementation file, mighty_test will find the corresponding test file and run it automatically. This works as long as your implementation and test files follow a standard path naming convention: e.g. lib/commands/init.rb is expected to have a corresponding test file named test/commands/init_test.rb.

Watch mode also offers a menu of interactive commands:

> Press Enter to run all tests.
> Press "a" to run all tests, including slow tests.
> Press "d" to run tests for files diffed or added since the last git commit.
> Press "h" to show this help menu.
> Press "q" to quit.

🔬 Focus Mode

You can focus a specific test by annotating the method definition with focus.

class MyTest < Minitest::Test
  focus def test_something_important
    assert # ...
  end

Now running bin/mt will execute only the focused test:

# Only runs MyTest#test_something_important
bin/mt

In Rails projects that use the test syntax, focus must be placed on the previous line.

class MyTest < ActiveSupport::TestCase
  focus
  test "something important" do
    assert # ...
  end

This functionality is provided by the minitest-focus plugin, which is included with mighty_test.

🛑 Fail Fast

By default, mighty_test runs the entire test suite to completion. With the --fail-fast option, it will stop on the first failed test.

# Stop immediately on first test failure
bin/mt --fail-fast

# Use with watch mode for even faster TDD
bin/mt --watch --fail-fast

This functionality is provided by the minitest-fail-fast plugin, which is included with mighty_test.

🚥 Color Output

Successes, failures, errors, and skips are colored appropriately by default.

# Run tests with color output (if terminal supports it)
bin/mt

# Disable color
bin/mt --no-rg

Screenshot of bin/mt output

This functionality is provided by the minitest-rg plugin, which is included with mighty_test.

💬 More Options

Use -w to enable Ruby warnings when running tests:

bin/mt -w

Minitest options are passed through to Minitest.

# Run tests with Minitest pride color output
bin/mt --pride

# Run tests with an explicit seed value for test ordering
bin/mt --seed 4519

# Run tests with detailed progress and explanation of skipped tests
bin/mt --verbose

# Show the full list of possible options
bin/mt --help

If you have Minitest extensions installed, like minitest-snapshots, the command line options of those extensions are supported as well.

# Update snapshots
bin/mt -u

Support

If you want to report a bug, or have ideas, feedback or questions about the gem, let me know via GitHub issues and I will do my best to provide a helpful answer. Happy hacking!

License

The gem is available as open source under the terms of the MIT License.

Code of conduct

Everyone interacting in this project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

Contribution guide

Pull requests are welcome!