The Programmer's Testing Trap

The Programmer's Testing Trap

"If you wish to build a ship, do not divide the men into teams and send them to the forest to cut wood. Instead, teach them to long for the vast and endless sea."—Antoine de Saint-Exupéry

As a young fledging programmer, I was told (and had a hunch) that testing is important. Yet, I never really knew why testing was important. At university, we were made to test everything. We were, proverbially, sent into the forest to cut as much wood as we possibly could.

My tests broke builds more than my actual code did.

Particularly whenever I wanted to change my code. The change worked perfectly, but I was still testing for the original code, and so the tests made loud angry noises that indicated what sort of awful human being I was.

I stopped writing tests.

Things were much easier, I could do what I liked. Nobody said no. However, when the time came to refactor a major component of a fairly large project, I realised why tests exist. Each time I made one change, I had to manually go through the whole program, making sure everything else still worked fine. I realised that, actually, I was still testing. Not with code, but I became my own test suite. I was using my own time and eyes to test what could have been automated.

I started longing for the vast and endless sea.

My breakthrough came from the book Practical Object Oriented Design in Ruby (can't recommend highly enough). We should test interfaces and behaviour. Not data structures, not methodology.

Let's consider the simple interface of "I want pizza". We have two objects involved: you, and the pizza shop. You tell the pizza shop "I want pizza". In this situation, what should be tested?

  1. The number of staff in the shop?
  2. The order in which ingredients are added to the pizza?
  3. Whether the delivery man uses a scooter or a car?

Actually, the only thing that should be tested is whether or not you receive a pizza. Think about it. If you didn't know anything about the process, yet you still receive a pizza, is the interface successful? Yes, yes it is.

By testing only the interface, the question and its result, we now have flexibility. The pizza shop can change their staff, and the test is still happy, because the pizza still arrives. The delivery man can win the lottery and deliver your pizza in a Jaguar, and your test doesn't complain, because you still got the pizza.

The test still gives you security—any change that will actually stop you getting a pizza will break the test. The shop can change their ingredients, as long as they are still giving you pizza. If they make roast turkey instead, then "I want pizza" is a failed interface, and your test will break.

So let's make sure we are testing, and testing well. Let's test interface, instead of implementation. Let's test the "what", not the "how". These tests no longer hinder change and improvement, but they do ensure the successful operation of your code.

要查看或添加评论,请登录

Regan Ryan的更多文章

  • Copying Prod DB => Staging on Heroku

    Copying Prod DB => Staging on Heroku

    TL;DR heroku pg:backups capture --app my-production-app heroku pg:backups:url --app my-production-app heroku…

  • OWASP Top 10 Web Application Security Risks

    OWASP Top 10 Web Application Security Risks

    The OWASP Top 10 is a global standard of the most important security risks to today's web applications. For any…

  • Your proudest code is your worst

    Your proudest code is your worst

    The other day I sat down and worked really hard to solve a particular parsing problem. I used regex because I like a…

  • Changing Designs Mid-Project

    Changing Designs Mid-Project

    Can it also come in firetruck-red? It's a common and often inescapable event—the developer is halfway through building…

    2 条评论

社区洞察

其他会员也浏览了