How to organize minitest/unit tests? How to organize minitest/unit tests? ruby ruby

How to organize minitest/unit tests?


I know several folks coming from RSpec to minitest struggling with the same question. They love the ability to nest using describe/context blocks and want to continue in minitest. There are several solutions:

  1. Use minitest's spec DSL: While there are minor differences, the spec DSL gives you most (all?) of the good parts of the rspec DSL. The big difference is the lack of context blocks. But you can just as easily use describe in its place and everything works as you'd expect.
  2. Use directories and files: I prefer this option. I dislike scrolling through a 300 line test file, regardless whether its using the spec DSL or the classical xUnit style. I do not find nesting unrelated tests helpful. The same rules for comprehension for code applies to tests. So break it up. Create a directory and place several files within it.

Here is an example of how my test files are organized:

test/     models/            user/                 authentication_test.rb                 email_test.rb                 reservation_test.rb                 user_test.rb                 username_test.rb

I use this structure whether I'm using the spec DSL or the xUnit style. When using the spec DSL I specify what I'm testing in my describe block like so:

require "minitest_helper"describe User, :authentications do  before do    # ...


You can also throw multiple classes into one test file:

module PizzaTest  class Isolation < ActiveSupport::TestCase    test "is awesome by default" do      assert Pizza.new.awesome?    end  end  class Integration < ActiveSupport::TestCase    fixtures :all    test "is awesome too" do      pizzas('one-with-everything').awesome?    end  endend

and even nest test classes:

class PizzaTest < ActiveSupport::TestCase  test "is awesome by default" do    assert Pizza.new.awesome?  end  class Integration < ActiveSupport::TestCase    fixtures :all    test "is awesome too" do      assert pizzas('one-with-everything').awesome?    end  endend


I prefer this way (only a little bit) but I think it easier to follow:

class ConventionalNameTest < ActiveSupport::TestCase  class ContextTest < ConventionalNameTest    # so much stuff...  end  class AnotherContextTest < ConventionalNameTest    # and some more...  end