Ignoring Testing can be Explained, but Never Excused

gears2 Many individuals that practice software development will tell you the same thing; testing is vital. I’ve never worked at a place that “requires” automated testing. Any of the testing that we’ve automated was put in place as a way for our team to check ourselves. Those who have implemented it have understood its importance, and put something in place to benefit from it. In these cases, something is better is nothing. What I have dealt with at some jobs is testing as a manual process by the developer (and/or supervisors) to run the application and “eye-ball” the results. This isn’t how testing should work, definitely not how automated testing works and how dare you even bring up the term TDD!

If you don’t have a build server (with an assumed automated test suite) or have a project for tests, or have unit tests at all, there may be reasons for this. These reasons may be explained, but are never excused. I’ve heard or read the following:

  • Writing tests takes too long.
  • Writing tests is hard.
  • It’s not my job to test.
  • I’m in a small shop. We don’t do that. — or — It’s only me on this project. I don’t need tests.

These are valid explanations, but they fail to address the reason that testing doesn’t work for you. It’s not the fault of testing, it’s the fault of the situation you’ve put yourself in or gotten yourself into.

Writing Tests Takes Too Long

Tests do not take long to write. They’re usually no more than a dozen lines of code per test. This excuse can easily be refuted by the fact that tests should be quick to write. If they’re not quick and easy, it’s because your code base is composed of code that is not testable. If this is the case there are probably bigger problems with your project than the lack of tests. You’ll need to look to SOLID principles to increase the quality of your code. This needs to be a pre-requisite to building or maintaining any project.

Explained due to lack of project structure or poor code.

Writing Tests is Hard

Look for the most simple method you have in your project and write a test for it. You now have a way to ensure that this method works as expected when any other part of your project is changed.

        public bool IsPreferredCustomer()
{
if (IsLifetimePreferred)
return true;

if (ClubExpirationDate < DateTime.Now)
return true;

return false;
}

Three simple tests can be written to ensure that this method does exactly what it is supposed to do. You create methods that checks each path through the method and asserts that the expected result is equal to the actual result.

Explained by lack of experience or laziness.

It’s not my Job to Test

Maybe the word “test” or “tester” is not in your job title. This doesn’t excuse you from testing your code. You probably test it visually before handing it off or checking it in anyway. Why not write code that tests it? If you make changes later, you can ensure that you’re not breaking previously tested code that worked. If at the very least, when you said in August that your code worked and now you added/modified something and it now “isn’t working”, you’ll be the first to know and the first to have the chance to fix it before handing it off to another team or even worse, a supervisor.

Explained by lack of commitment or carelessness.

I Work in a Small Shop or I’m the Only One on the Project

The problems with this argument are:

  1. You could be making yourself look bad. Even if you’re doing a small project on your own. You probably want to ensure that your code is checked by itself. If you perform the development for a project and a year later the client hires somebody else to add to or modify your code. You have somewhat of a “proof” that your code works the way it should. This makes you a bit more credible for future work.
  2. You also should add tests to your project because you care about your fellow developer. Have you ever been thrown head-first into a project to “fix it” and the project has no tests? You might be wanting to jump off a cliff instead. You have no idea what your changes will break because there is no guarantee that the code you modify isn’t going to break working pieces of code. Adding tests is a way of paying it forward. Unfortunately for me, I’ve never picked up a project that had previous tests in place. If I ever do, I will contact as many of the previous developers as possible and send them a thank you card!

There is no reason a small team shouldn’t be as confident of their code as a team of hundreds, or even thousands. Whether you’re working on a project of 3,000 Lines of Code or 3,000,000 LOC, the project is only as good as the work put into it.

Explained through the falsehood that small teams are not responsible for quality work.

Have You Heard Enough Yet?

I feel like I’m beating a dead horse. I also feel like those who advocate testing are also the only ones that have taken it up and actually done it. I’ve never read an article by, or talked to a single person who has done unit testing successfully and not advocated it as being extremely important. Once you open Pandora’s box, you can’t go back; if you’re testing, you don’t know what you’re missing.

Related:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Chris Missal

Oh hey, I'm a Senior Consultant for Headspring in Austin, TX. I've been working in software professionally since 2006 and I really, really love it. I'm mostly in the Microsoft world, but enjoy building computer things of all sorts (to be vague). When I'm not slinging code, I'm probably out and about slinging discs, bowling balls, or good beer with great friends.
This entry was posted in Best Practices, Testing. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://blog.fohjin.com Mark Nijhof

    Great read! Just this afternoon a college said something like: “I don’t like this test, to complex” and after we looked at it we agreed that the existing code had to many responsibilities which made it harder to create a test for the new functionality using it. We changed the code and the test became simple again.

  • http://www.lostechies.com/members/schambers/default.aspx schambers

    Good post.

    While I agree that you should always test and there is no excuse for it. Another thing that really effects testing is getting legacy code under test. Sometimes the technical debt is just too great to get old code under test.

    From the aspect of new development however, I agree completely, there is no excuse for leaving out tests.

  • m4bwav

    re: “Writing Tests Takes Too Long”/”Explained due to lack of project structure or poor code.”

    If the deadline is too tight, and the lead developer is not at all familiar with TDD, then your kind of f**ked.

    I would like to refactor the code to make it more testable, but the lead developer would both be concerned about the time I’m taking because they wouldn’t really care what it was for, and because I would be altering their poor design. Many lead developers are defensive about their position, and wouldn’t like someone upstaging them by refactoring the code for reasons they don’t understand.

    I love TDD, but I think TDD advocates forget that teaching TDD, and it’s concepts takes time for those unfamiliar to them. And in time deadline situations, especially with rookie leads, it’s going to be hard sell.

  • http://the-software-simpleton.blogspot.com/ Paul Cowan
  • http://blog.rainer.eschen.name rainwebs

    @m4bwav: good point.

    Maybe some words from the lead developer/architect’s point-of-view to this. In teams with limited resources and/or limited timeframes, you’ve to decide for the important things. First, the functionality you’ve to deliver, second the documentation quality (Javadocs, etc.) for later maintenance, third all the modern extras, like TDD. I can skip unit tests if I test on a higher level (e.g. the user interface). This is what the elder did in the past. And it worked with the right testing teams.

    And the real question to me is what do I loose not following the TDD ideas? I don’t think its stability. If the test team is smart, this is no problem. Maybe flexibility in changing or extending existing code. Some bugs will be found later. But, what does this cost me in the end? Basically, I’ve to be more careful with my interface designs and have to invest more time in pre-planning.

    With limited resources and limited time frames I can’t expect to get extra time for refactoring. So, the design has to hit the target earlier anyway. I’ve no problem to invest more time in design, and skip unit tests. Maybe not modern today, but it worked in the past.

    Some words about my experience with the team. All developers love to write unit tests. It’s ok to me. I’m the opposite to the lead developer m4bwav mentioned. I even change my designs if the arguments show that my ideas doesn’t deliver the best result the team can produce:

    http://blog.rainer.eschen.name/2008/02/20/the-mission-of-a-software-architect/

    But, it’s not enough to be motivated. There are a lot of young developers in the team. Lack of experience, not only in TDD but also in software engineering principles, is a big point here. So, the more tests we have, and the more customizable (and complex) the implementation gets, the lesser useful the unit test are. Even continuous integration gets worser.

    So, what’s missing here (and that was not mentioned in this post)? Planning. TDD needs time to be successfully implemented. I think the developers try to follow all ideas of this post, but that’s not the point. Only the quality of the unit tests result is important. This quality is not for free. We don’t get it automatically. And it’s a hard job to get it. Looking back the last years I think even without limitations TDD is only successful if your functional design is extended with a test design.

    Provocation: is it really worth the effort, or is TDD only a hype? Any studies? Nobody is question the efficiency anymore.

  • Stephen Smith

    My development philosophy is the alternative to writing testable code is writing DETESTABLE code – in both senses of the word.

    My experience is that where I have been and the excuse to not invest in quality practices such as TDD is a lack of time because of deadlines. It is the most compelling argument for investing in TDD.

    Quality can NOT be bolted onto a product by additional QA testing at the end. Quality must be built in by the use of quality practices and tools. A significant characteristic of quality is that is closes the feedback loop as early as possible and as often as required. Automated testing such as that produced as a result of applying TDD and automated user acceptance testing meets these quality characteristics perfectly.

    Where we have relied on QA testing to close the feedback loop many loops are being closed a long time after the code was written and many loops are being closed all at the one time, resulting in many raised bugs to resolve, when we least want the stress in the development – test – release cycle for an application release.

    Many developers can see the benefits of the growing suite of unit tests as a result of applying TDD as being a powerful regression tool. They find difficulty in understanding that TDD’s real value is as a powerful object-oriented design tool that via continuous refactoring continuously permits more optimal designs, conforming to SOLID principles, to emerge as the developer continuously discovers more about the nature of the requirements being implemented and concurrently simpler and more elegant designs for implementing them. Where we have relied on QA to essentially “clean up” after us fixing each bug has often resulted in unknowingly creating several others as there has been little or no attempt at implementing separation of concerns, a real circus.

    Applying TDD is a powerful communication mechanism for determining exactly what are the requirements to be implemented. The tests are a black and white, pass or fail, explicit view of the expected behaviour of the module being implemented. The automated tests are executable documentation. It drives out all forms of ambiguity in the requirements or the developer’s interpretation of the requirements. Business analysts have always appreciated the fact that I will be persistant in working with them in teasing out the exact meaning of the requirements as it provides invaluable feedback to them that I have understood the requirements and where needed they have gone back to the business for clarification where required. Business analysts worst nightmare is where the developer does not understand and has made their own assumptions where there is ambiguity.

    Delivering business value in software development boils down to building the right thing (the optimal requirements that deliver business value to the user) and building the thing right (the optimal design). TDD, along with other forms of automated testing, is such an important enabler and verifier in being able to build the right thing and to build it right.

  • http://the-software-simpleton.blogspot.com/ Paul Cowan

    It just feels wrong that we have to have verification and backup for every line of code we write in the shape of multiple assertions.

    I often hear the TDD is design argument which seems to contradict what most have previously stated. It is often quoted that you need tests in order to refactor. This would lead you to believe the tests are indeed there to TEST nothing has broke during the refactoring.

    Also TDD seems like a bad design choice. We start writing code with no idea of design in place until after countless refactorings a design is somehow discovered.

    This voyage of discovery seems somewhat wasteful.

    The SOLID acronym is the new darling of alt.net. I’m waiting for a post saying there is no excuse not to write code that does not adhere to SOLID.

  • http://the-software-simpleton.blogspot.com/ Paul Cowan

    I often hear the TDD is design argument which seems to contradict what most have previously stated. It is often quoted that you need tests in order to refactor. This would lead you to believe the tests are indeed there to TEST nothing has broke during the refactoring.

    Also TDD seems like a bad design choice. We start writing code with no idea of design in place until after countless refactorings a design is somehow discovered.

    This voyage of discovery seems somewhat wasteful.

    The SOLID acronym so the new darling of alt.net. I’m waiting for a post saying there is no excuse not to write code that does not adhere to SOLID.

  • http://www.twitter.com/freddy_rios freddy

    @Paul,

    TDD doesn’t negates the need for an application architecture that is concerned with the bigger aspects of the system. It is about design of the more granular pieces that make up the software.

  • Stephen Smith

    @Paul,

    TDD ideally is just “enough design up front” and then you are NOT limited to your initial design decisions which would have been made when you knew least about the module being implemented.

    The refactoring provides the freedom to always permit more optimal designs to emerge as you discover more about the nature of the requirements being implemented and the best way to implement them.

    Doing TDD well is an art to be learnt in itself with practice and mentoring.