I noticed a couple of interesting things when I experimented with Mutant. If you are unfamiliar with Mutant, basically it parses your ruby code into an AST and performs modifications to your code to see if your code breaks. The idea is that with tools like SimpleCov, you can see what lines your tests run, but it does not show that you are actually testing the behavior correctly. Mutant modifies your programs AST to create valid ruby that should break your tests.
I am going to be using a little movie management app as my test app. You can find caketop and look at the code if you like, but really I only expect you to understand what a movie is.
Some tests are just lazy, I found a couple examples of tests like this:
This kind of test has a very simple solution. Just expect something. In this case I went with a regular expression. This should be more robust than trying to match the whole page content which is factory generated and could change.
Missing special cases
Interestingly, not all of the changes I made were in my tests! I was expecting only making changes in my tests, but in reality I ended up making at least equal amounts of changes in my code. And I think the code is better for it. I don’t know if the creator of mutant intended for the tool to expose poor code as well as poor coverage. Either way I found mutant to be a helpful tool for code introspection as well.
One of my favorite finds was a non-dry method that was missing a test. So Mutant threw up on this in a big way.
The method was,
In addition to not fully really understanding ruby’s
self it also
has this special case for setting the admin password that breaks the
typical pattern above.
so First thing I did was extract the special behavior around
admin-pass and the unnecissary references to
Then I added the missing test case,
Constants over static methods
First thing I ran into was a a fun little method for on the model that listed the different sort orders you could use when sorting movies.
The first thing I thought was, “wow this method should be a constant.”
The tests that Mutant ran on this file inserted
throughout the this array of arrays. I realize that I didn’t care
about testing that because this array will always be exactly like this
as long as those are the fields on a Movie you can sort.
When I realized that there really isn’t a practical way to change this array without changing the purpose too. I moved the method into a constant. Next step would normally be to add the method back and just reference the constant to maintain the interface, but I found only one use of this method, so I just referenced it directly there.
The best thing I have found about using mutant is that I actually learned some new patterns to watch for in my future code. I am sure I could find more patterns if I test more things with mutant, but I have already found some small improvements I will be looking for in my code and tests in the future.