1. 9

  2. 9

    This post is not minitest vs rspec but rather Test::Unit style syntax versus spec style syntax. Minitest supports both.

    The article also less presents an argument and more just shows the syntaxes to you and hopes your gut agrees.

    1. 7

      The minitest example only verifies if the Foo class has a three properties and those are not nil, while the RSpec example verifies if model Foo has three associations defined and all the associated models can be nil. So it’s not exactly an apples-to-apples comparison.

      Personally, I do like the spec-style syntax as it allows me to describe behaviour based on contexts, which is slightly more cumbersome to do with Test::Unit-style syntax. That being said, I did notice that people tend to go to town with RSpec but thankfully there’s the Better Specs site which can provide some general guidance.

      1. 5

        I don’t agree. I do agree that RSpec’s level of fanciness can get to be a bit much, and you can end up with something pretty unreadable if you go too far into it. A little bit like Ruby itself infact. But it also has the best tools for organizing large numbers of tests, writing sophisticated mocks and asserts easily, separating shared elements out into a single place, and doing it all the right way, not compromising the independence of individual tests, without you even having to think about it.

        1. 4

          Is the argument here “RSpec is a DSL and therefore bad”? People learn new DSLs all the time, and the rspec one isn’t particularly complicated. Sure, MiniTest is ruby classes, but you still need to figure out how all the parts work together.

          What is include_context? What is is_expected? How can I identify SUT (System under test) when I cannot see it? Why should I care an object internals like class name class_name?

          This is the reason I like RSpec: it’s got some up-front complexity, but it gives you a huge amount of power. Shared contexts make it easy to parameterize test suites and bootstrap complex tests from simple seeds. When you have to write integration code for three vendors, having to write the tests once and adapt them per vendor is really nice.

          is_expected is honestly one of those features I never really liked, so I’m not gonna defend it. But subject and described_class are great for doing setup and mocking.

          class_name is a Rails thing, not an RSpec thing. You can use it in MiniTest too.

          One thing you didn’t mention: test metadata. You can put metadata on rspec tests do to setups or filter tests you care about. Plus before :suite, let statements, expect over lambdas… there’s lots of really powerful stuff in RSpec.

          (My main complaint about RSpec is calling tests “specs”.)

          Actually that’s one of the reasons Google invented a simple and stupid language called Golang instead of a magical one

          What’s that got to do with RSpec?

          1. 3

            I’m currently working on two projects, one of which has minitest and one has rspec. Rspec is way more ergonomic.

            Things that minitest lack:

            • Lazy initialization of variables. Rspec has let, in minitest I have to make instance variables in setup(), which initialize even if particular test doesn’t need them. Usually it’s activerecord records persisted to database, so initialization is not cheap.
            • Proper mocking/stubbing. Object#stub is half-baked functionality with poor API. Want to stub constant? You can’t. Want to stub method which takes block? You can’t. Want to make stub return different values? Make callable object with clunky code, because passing block to #stub is for additional checks and not for returning values. This is the worst stubbing lib I’ve seen.
            • Rspec has rspec binary to run tests, with minitest you have to do ruby -Ilib\:test test_file.rb -n /foo/.
            • Rspec has tags, with minitest you have to use class hierarchies and mixins for it (for example if you want some integration tests to use real browser, others to use Rack::Test). Please don’t forget to call super in setup(). Or maybe in before_setup()?
            • No matchers. Want to check that each item in list satisfies something? Do it in freaking loop. You won’t see the whole list when tests fails.

            I strongly prefer rspec. It’s much better well-thought. “Simplicity” for hard problem of testing? Just no. And I don’t see problems with learning curve.

            1. 1

              I didn’t make any arguments but I just clarified down points but definitely there are a lot of of advantages to use RSpec that mature developers use but a lot of juniors go way to crazy about it :D

              Thanks for all replies