Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Surrounded by fields of brown? Inspire better tests with Muse.
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



Interactive Test-Later Development

If you’re reading this, you probably know about “TDD”, “BDD”, TATFTZDD. All developers always test their code, right?

Well, sometimes—for whatever reason—there’s Ruby code out there that’s untested. That’s where Muse comes in. You have code that works (for some definition or “works”) and you want to get your test suite to reflect that before you start changing other things around.

Maybe you’re working on a brownfield project that a lesser developer started. (Maybe that lesser developer is an earlier you…)

Maybe this was a toy that you were experimenting with and you didn’t even know how to even start testing it… like this very project.

Maybe you’re some kind of weirdo that’s used to developing interactively and you like that kind of thing.

Muse doesn’t care! Muse loves you for who you are. Muse just wants to inspire better tests!


Muse keeps a context with a suite, test, and setup and assertion lines. (These terms may change, but as a goal is to be able to generate tests in multiple test_libraries, terms were chosen that don’t exactly line up with any one library.) Here’s a chart of how they match up to test libraries (currently only MiniTest is fully supported):

Muse MiniTest MiniTest::Spec Wrong
suite test case class “description” block NA
test test case method “it” block NA
setup lines without assertions lines without assertions lines without assertions
assert lines with assert_equals lines with assert_equals lines with assert { }

Example Session

#  Start a session (TODO: allow starting from gem):
⎈  bundle exec bin/muse 
# Set the suite (in this case we're writing tests for Muse's Context class):
(suite):(test) :) suite Context
# Set the test:
Context:(test) :) test has lines
# Write some setup lines:
Context:has lines :) setup
Context:has lines *setup* :) context =
=> #<Muse::Context:0x000001009f8520
 @test_libraries=[:mini_test, :wrong]>
Context:has lines *setup* :) exit
# Write some assertions:
Context:has lines :) assert
Context:has lines *assert* :) context.lines
=> []
Context:has lines *assert* :) exit
# Show the test
Context:has lines :) show-test
def test_has_lines
  context =
  assert { context.lines == [] }
# See (or set) the test-libs. Currently limited to these.
Context:has lines :) test-libs
# Copy the test to the clipboard and open the test file in your editor.
Context:has lines :) edit-test
Using test file at /Users/andrew/Play/muse/test/test_context.rb
Copying test to clipboard.


  • MiniTest::Spec support
  • Use Muse to write its own test suite because I like being meta.
  • TestUnit support
  • ActiveSupport::TestCase support
  • Rspec support
  • Make a real gem
  • Allow setup and assert to take one-liners
  • Smarter determination of test libraries
  • Don’t add lines with errors to the context. Also make it possible to pop off the last line.
  • Probably need to clean up bindings between tests
  • Oh man, what would be really cool would be if we didn’t just generate tests a strings of text, but actually ran within the test lib’s runner so we could take advantage of setup methods, nesting, convenience methods…
  • Some problems with quoting on assertion outputters

Some cool stuff

  • Muse is based on Pry which gives us some amazing functionality on its own: you can dig into objects, list their instance variables, do tab completion on their methods, and so much more.
  • Use a continuous testing tool. I use infinity_test, but there a bunch out there (e.g. autotest). See the .infinity_test configuration in this project for a usage example.
Something went wrong with that request. Please try again.