#testing

Notes on Fast Test, Slow Test

Recently I got lots of inspirations and thoughts on how to write good tests. Thanks to Cookpad, the company I’m working on, I get the chance to work on a very large scale rails app. But it also introduces me to some very bad tests. Sometimes I found myself so difficult to add any spec, as it needs lots of extra efforts to make the fixture data, also one model got too many dependencies and collaborators, etc. I know it’s wrong, the code smells, just don’t know where to start.

So when I watched this video “Fast Test, Slow Test” by @garybernhardt, who also runs DestroyAllSoftware screencast, I found it very helpful and wanted to take some notes on it.

Three Goals in Testing

How to Fail in Testing

What you’re saying here is that we acknowledge that this code sucks, so we’re going to go in and write tight tests around it that solidifies interface and just bake the badness forever. This is the worst way to do unit testing, go in your legacy system and write test around bad code.

Too many dependencies in test

You end up with a test suite where it tends to either completely succeed or completely fail. It doesn’t give you any fine-grained feedback about what has actually gone wrong it just tells you you broke something. And you are left to dig these stack traces. In the ideal test suite you don’t have to dig through stack traces because ideally once test fails it will tell you exactly was broken (of course you never achieve that)

More than 8 lines for a model test

I would ask myself why do I need to setup so much of the world to test this one small piece of behavior. That causes me to decompose it which causes better system design.

10% System/Acceptance Test, 90% Unit Test

(in terms of test cases, not lines of code)

That applies to mostly object heavy system like web app, that have a lot of logic and not a lot of boundaries.

Advice on models that very tied to database

Question

If you’re working with model objects that they’re very tied to the database specifically things like you have to save that one object before you can associate with the other object and that means hitting the database. What’s your advice in terms of writing fast unit test?

Answer

Take all of that behavior that’s on your model objects and pull out of their into service classes that are stateless, that interact with the model objects. So view calls a service, service contains the intelligence and the service manipulates the model objects.

You can still have methods on your model objects do things like wrap specific queries in class methods, or wrap specific mutations when multiple fields are commonly manipulated together.

It’s okay to have those on your model object and then have the service use those but if you pull the behavior of the system out into the service, and you control the boundary between the service in the model by those methods you’ve written on the model, then you can mock out more easily and safely.

Qihuan Piao

Qihuan Piao

Originally from China and now living in Tokyo, I started this blog to practice English. Over the years, writing helped me find my own voice and explore thoughts about identity, life, and ordinary things that catch my curiosity. I mostly write for myself, but I love it when something here connects with someone else.

Meanwhile, what I wrote in Japanese

夜型の僕が早起きを31日間頑張って思ったこと

June 22, 2013

Meanwhile, what I wrote in Chinese

飘雪,歌词很美

January 19, 2013