I Mock Your Fixtures
Testing is a beautiful thing. There are no words to describe the immense pleasure I get from writing a good test. When I first started here at Thoughtbot, I had been unexposed to the glory of testing. The days of writing code and then manually going through my application to make sure the changes I made worked the way I expected them to - are over.
In the early days of my testing, I really had no desire to write tests. The tests I wrote basically were just mimicking code I had already written. It felt like I was writing the same code in two different places, and it felt like I was doing something wrong. I couldn't understand why anyone would waste time doing this? I know the code I wrote was good, I manually tested it, and it worked when I coded it. I was doing everything right – my code was fine, who cares about writing more code just to 'prove' my code worked? The application I was given had no tests written for it anyway. Why should I need to write tests for someone else's code?
As time progressed, and the application I was working on got more and more tests – I had this strange euphoric feeling, something was very right about my tedium. Everything I had ever known as a developer was slowly being replaced by this insane desire to test. Any change I wanted to make, I would first update my tests – watch them fail, and code until they passed. After a while – I would go an entire day with out actually manually using my application.
I was on top of the world, I had a bunch of controllers, and models interacting with other models with validations and tons of fixtures that could prove those interactions – everything was tested. No one could could change my code without breaking a test. It felt good, it felt like my application was secure.
That was about when I had my 'fall from innocence', if you will. I guess it had to happen eventually, it might not happen to everyone. The general flow and specification of my application was changing. They were small changes at first – nothing too major, a few changes here, a few tests to patch there, no big deal – I guess it's just part of the life cycle of an application. It needs to be able to adapt to its surrounding environment. I hoped it was just a temporary thing, but I was so terribly wrong.
My secure euphoric feeling was draining away. There was something innately wrong with the amount of time it took to change anything about the way my application was working. There was one point, I changed one method on one model, to reflect one additional column I had just added from one migration I wrote. I updated my unit tests for that model, and ran rake. The 'simple' addition to my model turned into a disaster. My application painfully complained about all the things I had broken. I had functional tests calling that method in a view from a related object breaking. It was almost like the only test that was passing, was the unit test specifically for the model I had changed.
I took a deep breath, and opened my fixtures file. Changed an id here, added another fixture there. I would fix one test, to find out I had broken a 'search' action in a controller somewhere on the other side of my application. Why is that happening? I didn't change that search action!? More fixtures, more updated tests and more time wasted – my model now had its new column, and all tests were passing.
I wasn't sure how much longer I could handle this fragile application. Until one day, it came, a new application, a clean slate, not one line of code, not one model, nothing. And this guy right here, got to start his first application from the ground up.
A coworker and I, here at T-bot, complained about all the things we hated about developing applications. We came up with standards and coding practices and had a vision for an ideal application. We were sick of the things that slow down development, and make an application unmaintainable. With a strict (borderline insane) dedication to our ideals and much discussion – we agreed (among a bunch of other things) to not use any fixtures for our tests.
My testing strategy was completely overhauled and dedicated to our new ideals. The 'new code' excitement came back. It was like my glory days of innocence when I knew very little about testing. I'm not yet an expert on mocking, it's still very new to me, but I feel that it is possible, that our ideal application can be developed without the crutch of fixtures. This is going to be a tough task to complete so I plan to write a more 'technical' follow up post, but for now, it's time to find the essence of stubs and mocks.