(blogging from Write/Speak/Code)
A few months ago I started talking to other developers about something super exciting and wonderful I had just learned about. It had totally changed how I thought about writing code, so I was excited to learn what others thought about this super interesting thing. “I just learned about test-driven development guys! How cool is that!?”
*crickets*
Apparently I'm a bit behind the TDD times. A lot of people seem to think it's pretty boring and old-hat. It's too slow and dogmatic. It's something you have to do for work, not something you would worry about with a personal project. Also, why am I bothering anyway, when I'm writing in Haskell? A statically-typed immutable language doesn't need tests. “The types are your tests.”
I learned about TDD by attending Code Retreat, which is a day-long event during which you partner with other programmers in an attempt to implement Conway's Game of Life in a single hour, *while* writing passing tests. Some people who attended –like myself – weren't comfortable with TDD, and some pairs kinda fudged the requirements in order to get closer to a working product. But a working product wasn't the point. It was about learning to work with others – and learning to test. I paired with other beginners as well as senior developers.
I was amazed how the red-green-refactor process clarified and structured the process of making the game. The game is pretty simple, but not trivial. Different teams came up with different places to start. But I noticed, the teams who started with tests and didn't try to fudge that aspect, they were able to find a small, manageable place to start and work from. Teams that didn't would often bite off more than they could chew. Then at the end of the hour, their code wouldn't run at all, while the TDD pairs could at least say, "It's not done, but we implemented cells and a grid, and we have a solid base to work from."
I took that approach into Haskell, and decided to use TDD while making a text adventure game engine. There's not a lot of good how-tos on getting started with TDD in Haskell and some of it is outdated. Still, I found the process very worthwhile. Using TDD helped me choose what parts of the engine to work on first (“well, what would be easy to test?”). It also helped when I made big refactoring changes. Haskell is great because the compiler will yell at you if the types don't match up, but unfortunately, even in Haskell types aren't always perfectly expressive. The tests sometimes caught problems that the compiler missed and often helped me pinpoint places where my logic wasn't sound.
When I started studying Python recently, I found the increased expressiveness and flexibility of the language both exhilarating and a bit scary. I was amazed how I could come up with a function, just off the top of my head, and it would run! The only problem is when a function runs, but doesn't do what I thought it would do. I feel very insecure compared to Haskell. How do I know if what I'm doing is the RIGHT way to do it? One solution has been to learn more about design patterns and Python conventions, but TDD is what really gives me a security blanket. Even when my code is ugly or un-Pythonic, with tests I can feel more certain it will at least do what I expect.
In anything, fresh eyes can cause you to appreciate something that more experienced people just take for granted. Testing is not just something boring that has to be done for boring work projects. It's a whole way to think about writing programs! I'm really glad I went to Code Retreat and learned how even my small personal projects and learning exercises can benefit from tests.
A few months ago I started talking to other developers about something super exciting and wonderful I had just learned about. It had totally changed how I thought about writing code, so I was excited to learn what others thought about this super interesting thing. “I just learned about test-driven development guys! How cool is that!?”
*crickets*
Apparently I'm a bit behind the TDD times. A lot of people seem to think it's pretty boring and old-hat. It's too slow and dogmatic. It's something you have to do for work, not something you would worry about with a personal project. Also, why am I bothering anyway, when I'm writing in Haskell? A statically-typed immutable language doesn't need tests. “The types are your tests.”
I learned about TDD by attending Code Retreat, which is a day-long event during which you partner with other programmers in an attempt to implement Conway's Game of Life in a single hour, *while* writing passing tests. Some people who attended –like myself – weren't comfortable with TDD, and some pairs kinda fudged the requirements in order to get closer to a working product. But a working product wasn't the point. It was about learning to work with others – and learning to test. I paired with other beginners as well as senior developers.
I was amazed how the red-green-refactor process clarified and structured the process of making the game. The game is pretty simple, but not trivial. Different teams came up with different places to start. But I noticed, the teams who started with tests and didn't try to fudge that aspect, they were able to find a small, manageable place to start and work from. Teams that didn't would often bite off more than they could chew. Then at the end of the hour, their code wouldn't run at all, while the TDD pairs could at least say, "It's not done, but we implemented cells and a grid, and we have a solid base to work from."
I took that approach into Haskell, and decided to use TDD while making a text adventure game engine. There's not a lot of good how-tos on getting started with TDD in Haskell and some of it is outdated. Still, I found the process very worthwhile. Using TDD helped me choose what parts of the engine to work on first (“well, what would be easy to test?”). It also helped when I made big refactoring changes. Haskell is great because the compiler will yell at you if the types don't match up, but unfortunately, even in Haskell types aren't always perfectly expressive. The tests sometimes caught problems that the compiler missed and often helped me pinpoint places where my logic wasn't sound.
When I started studying Python recently, I found the increased expressiveness and flexibility of the language both exhilarating and a bit scary. I was amazed how I could come up with a function, just off the top of my head, and it would run! The only problem is when a function runs, but doesn't do what I thought it would do. I feel very insecure compared to Haskell. How do I know if what I'm doing is the RIGHT way to do it? One solution has been to learn more about design patterns and Python conventions, but TDD is what really gives me a security blanket. Even when my code is ugly or un-Pythonic, with tests I can feel more certain it will at least do what I expect.
In anything, fresh eyes can cause you to appreciate something that more experienced people just take for granted. Testing is not just something boring that has to be done for boring work projects. It's a whole way to think about writing programs! I'm really glad I went to Code Retreat and learned how even my small personal projects and learning exercises can benefit from tests.