Reading MiniTest: Wrap Up
I just finished reading the source code from the minitest/unit and minitest/spec libraries of the minitest gem.  My last five blog posts contain a detailed explanation of how the library works.  This post provides a summary to tie it all together.
Including minitest/autorun in a ruby script results in MiniTest::Unit#autorun being called. Â So, that's where we get started...
MiniTest::Unit#autorun creates a new instance of MiniTest::Unit and calls its #run method. The command line arguments are processed into a set of options. The list of all MiniTest::Unit::TestCase subclasses is split into suites that should run in parallel and suites that should not. A block that gets the test methods for each suite, creates an instance of the suite for each method, and runs the test via MiniTest::Unit::TestCase#run is mapped onto both sets of suites. The results are merged into a single array, and the stats are computed and output.
MiniTest::Unit::TestCase#run registers a block that reports errors if the INFO signal is raised. It runs the setup hooks followed by the method under test. NoMemoryError, SignalException, Interrupt, and SystemExit exceptions are passed through, while others cause the runner to "puke", logging the exception messages in the report. The teardown hooks are called with similar exception handling. Finally, Ruby's default INFO signal handling is restored.
MiniTest::Assertions is mixed into MiniTest::Unit::TestCase. It provides multiple methods for asserting and refuting conditions, keeping track of the number of assertions, and generating useful error messages.
MiniTest::Spec is a subclass of MiniTest::Unit::TestCase that contains some additional methods to aid in behavior-driven development by providing a DSL for building the tests.  Kernel#describe determines which MiniTest::Spec subclass should be used and dynamically subclasses it, defining the contents of the class by the entire passed-in block. Calls to :before and :after define setup and teardown methods. Calls to the #it and #specify methods define test methods that evaluate blocks of code. All of the must and wont methods provided by MiniTest::Expectations map to assert and refute methods in MiniTest::Assertions.  They are mixed into Object to allow expectations to be placed on any object in the spec.
All of this adds up to a library that can be used for both test-driven and behavior-driven design and development. Â On top of that, the code is a great read. Â The gratification of understanding how a method works becomes addicting rather quickly, causing you to push deeper into the call stack. Â With a clean code base, a little bit of meta-programming, and nothing too clever, MiniTest is a good example of the type of code we should aim to write.