At one of the recent WAN Parties, there was some discussion on testing. Some items came up that really got me thinking about why the last 2 years has sold me on testing. From memory, I’m going to go over my thoughts on some of the comments.
It’s hard to write tests first. How did you learn?
Well, I didn’t have a choice. I learned TDD by taking a job as a junior looking for some mentorship. My first two projects were:
- Get every old app we supported (~ 24) into a build script and onto our CI server
- Write a small make work app, but do it completely via TDD.
Me and my coworkers had done some pairing and I had written some tests with people, but I always had someone to lean on so it was kind of easy.
However, once I started out on my own, building a system from the ground up and having no idea where I wanted the design to go? That’s when things got difficult. I remember spending literally an entire afternoon writing a single test. One. I don’t even know if I finished. I just remember knowing Point A and Point B and having no idea which path to take between the two.
Of course, as my boss would come and check in on me he would say "That’s good… but why can’t it look like this"? He’d sit down and write a few lines and suddenly I’d feel like a total moron.
The point of the story is: It takes work. It takes writing tests and realizing their crap and continuing on writing more. Don’t expect your first foray into true TDD to be easy, and don’t expect to do it well. However, I can guarantee you that if you stick with it, it _will_ become second nature.
Also, if you can get one, find yourself a mentor to help you. It will help immensely.
How do I know what I should be testing?
I’m inclined to say "Pretty much everything". I’m not a coverage nazi, though we do have some guidelines and goals around it in our shop. However, there’s just code that it doesn’t make sense to test. Like a value object made up entirely of autoprops. I’m pretty sure I know how that thing’s going to work.
Don’t tests force your design?
It seems like many people feel that because everyone has their brilliant idea of what the design of the system is going to be, that they will write tests that will suit their perceived design. For me this is true, but the true power of it is that it shows you ahead of time where your design has flaws.
Yes, I usually have a path that I think I’m going to take when I start writing a test. However, often times before I’m done a set of tests for a feature, I end up changing my mind. The thing about writing the tests first is that it shows you where your design has flaws and where it’s going to cause you pain. If it’s painful for me to write a test then it’s probably going to be a pain in the ass to write and maintain. Pain in writing tests usually signals that you’re trying to do too much at once, often you’re trying to break SRP.
In the end, you’re not only testing your code. You’re also testing your design.
I hear all this propaganda over and over, but how do you know?
For me, I have two projects that I currently work on. One with tests and one without. The one without tests was started before I learned about TDD (though I’m currently trying to begin adding tests, it’s very difficult to retrofit). As well, the one without TDD uses ruby. I heard someone say at the WAN Party the other night that Static Languages and their compilers are just a set of implicit tests. After using a dynamic language I can totally agree.
Anyway, I always find myself trying to find excuses to do something else than my non-TDD project. Why? Because I’m scared to do anything with it. Since I have no tests, I have spent (literally) countless hours fixing bugs only to have them come back into play the next time I fix another bug. I have no way of telling whether what I’m fixing is breaking something else that depends on it. Personally, I think that had I just bitten the bullet a year ago and started putting the tests ever just around the bugs I was currently fixing that I would be well ahead of where I am today on that project.
I’m starting to notice a trend here….
I agree. The funny part I’ve always thought about testing is that as someone learning it, you don’t really see the benefits. In fact, in most cases, the benefits don’t ever fully show themselves until you’ve been working on a project for a long time, or even better, need to come back to it.
Maybe you’re at the opposite end of the spectrum. You’re not skeptical of the claims, you’re curious. Maybe you’re curious like I was 2 years ago because making any changes to an old project is like pulling teeth. Or maybe your current project has hit a standstill because bugs keep creeping in and every change introduces two new ones.
My Story (in a nutshell)
I graduated from University in 2004. I had been working for an Oil and Gas company doing some development part time during the 3 years prior. After graduating I took my first job as a software developer in a small (2 developers, about 6 hardware/network/whatever guys, plus admin staff) company. I was taught to develop in ways I always somewhat questioned. After a while I started to read up on things. The only article that still stands out in my mind that I read was Martin Fowler’s article on Dependency Injection. I know I read some on the Open Closed Principle. And none of it made sense to me. I had too many stumbling blocks in my way:
- I didn’t learn anything in my Computer Science Degree except algorithms and some cool hardware stuff
- My current ‘mentor’ didn’t understand these things either
- I knew I had problems, but I couldn’t even define them even though I was reading about the solutions to my problems
Then I got lucky. I went looking for jobs because I knew there was a better way and I told everyone I interviewed with that. Then I was finally told at one interview that they knew exactly what I was feeling because they had just gone through that pain. They also told me that they had the answers I was looking for.
I took that job and it was the best thing I ever did.
It gave me the things I needed:
- People who understood where I was coming from
- A requirement to learn every day
I truly believe that the easiest and best way to learn is to have someone with you guiding you in the right direction while also forcing you to go out on your own. I can understand people skepticism, I once had it. But then I got sick of fixing the same thing over and over. I realize that this is getting long so I’ll just end with another personal note: If I hadn’t taken that job and learned what I have over the last two years, I would no longer be in software.
The short story is, Testing saved my career.