Hi everyone — I’m pleased to share that our initial Minitest support is now merged into the gem’s main branch.
I’ve implemented the block-based test/setup/teardown API, as you suggested above (with some tweaks to make it fit better with setup and teardown methods in superclasses).
I decided to host the base classes inside the gem. They exist as Hanami::Minitest::{Test,RequestTest,FeatureTest}. I’ve also take the opportunity to use this as a first foray into internalising some of the test setup code (in those same classes) rather than generating everything into the user’s app.
I’d love for you to check it out and please share any other thoughts you might have!
@jaredwhite so far I haven’t implemented first-class support for minitest/spec, simply as a matter of needing to draw the line somewhere and balance my work for Hanami’s upcoming release. I’d definitely love for us to have this in the future. And in the meantime, I think a dedicated minitest/spec user can take matters into their own hands and manually add extend Minitest::Spec::DSL line directly into test/support/minitest.rb, just as you shared.
I’ve added a --test switch to the hanami new command, so users will be able to run hanami new --test=minitest my_cool_app.
See below for an overview of our Minitest support as I have merged it.
Set up everything we need to have Hanami Minitest to work as a full alternative to Hanami RSpec.
Provide three base classes, hosted within the gem:
Hanami::Minitest::Test(inherits fromMinitest::Test)Hanami::Minitest::RequestTest(includesRack::Test::Methodsand defines the app)Hanami::Minitest::FeatureTest(includes the Capybara DSL/assertions, sets up Capybara, and includes a teardown to reset Capybara’s state)
Enhance Hanami::Minitest::Test with a block-based class-level DSL providing test "my test" do, setup do and teardown do methods.
Provide these CLI command hooks:
hanami install, which generates the full setup (this will eventually run as part ofhanami newonce we provide an option to choose Minitest for testing)generate slicegenerate actiongenerate part
A full Hanami Minitest setup does the equivalent of everything we do with Hanami RSpec. It creates this structure:
test
├── requests
│ └── root_test.rb
├── support
│ ├── db
│ │ └── cleaning.rb
│ ├── db.rb
│ ├── features.rb
│ ├── minitest.rb
│ ├── operations.rb
│ └── requests.rb
└── test_helper.rb
test_helper.rb is the test setup entry point and should be required from the top of each test file:
require "pathname"
TEST_ROOT = Pathname(__dir__).realpath.freeze
ENV["HANAMI_ENV"] ||= "test"
require "hanami/minitest"
require "hanami/prepare"
require_relative "support/minitest"
TEST_ROOT.glob("support/**/*.rb").each { |f| require f }
support/minitest.rb is for adding any behaviour that should appear in every test:
class Hanami::Minitest::Test
# Add helper methods to be used by all tests here.
end
support/operations.rb is for making Success and Failure available directly in every test. It serves as an example of how you can use “topic”-specific support files, how not everything needs to be grouped by its top-level test type.
require "dry/monads"
class Hanami::Minitest::Test
# Provide `Success` and `Failure` for testing operation results.
include Dry::Monads[:result]
end
support/requests.rb is for customising request tests:
class Hanami::Minitest::RequestTest
# Add custom request test helpers here.
end
support/features.rb is for customising (Capybara) feature tests:
class Hanami::Minitest::FeatureTest
# Add custom feature test helpers here.
end
support/db.rb sets up tests that need to use the database. Right now it mostly bring in the TestSupport::DB::Cleaning module, which configures DatabaseCleaner in the same way we do for RSpec:
require_relative "features"
require_relative "db/cleaning"
module TestSupport
module DB
def self.included(mod)
mod.include DB::Cleaning
end
# Add helper methods to be used by DB tests here.
end
end
class FeatureTest
include TestSupport::DB
end
In terms of the actual test files we generate, here’s an example from running hanami generate action posts.show, test/actions/posts/show_test.rb:
# frozen_string_literal: true
require "test_helper"
class MinitestExample::Actions::Posts::ShowTest < Hanami::Minitest::Test
test "works" do
params = {}
response = MinitestExample::Actions::Posts::Show.new.call(params)
assert_predicate response, :successful?
end
end
We create test classes:
- Whose names match their corresponding class, with
Testappended - Using the compact class definition format, to keep the file compact and not nested n-levels deep (users will need to fully or selectively disable the
Style/ClassAndModuleChildrenRuboCop cop in their apps to let these stay) - Using the
testblock-based method - With a very simple starter test