programming practices - How big does my project need to be for me to unit test it?

I assume that my project is decoupled enough to allow for unit testing. But how big, exactly, in terms of clases and functions does my project need to be to make unit testing worthwhile?

We all make mistakes and no one's perfect, but I consider myself a decent programmer to handle small projects' errors with stepping through. Or is unit testing a hard necessity no matter of what size your project is?

12 Answers

  1. Adam- Reply

    2019-11-14

    Your project is big enough already.

    In my experience, one class and one function have been sufficient to consider the need for unit testing.

        class Simple {
            boolean reallySimple() {
                return true; // how do we make sure it doesn't change to false?
            }
        }
    
    
        class SimpleTest {
            void assertReallySimple() {
                // ensure reallySimple return value isn't changed unexpectedly
                UnitTestFramework.assertTrue(new Simple().reallySimple());
            }
        }
    
  2. Alva- Reply

    2019-11-14

    I've never bought into the "you must unit test everything" idea, though there are certainly folks out there who have (see gnat's answer!).

    As far as I'm concerned, the main benefits of unit testing are:

    1. Helping ensure changes don't break things.
    2. Helping you design sensible interfaces to your classes (since it forces you to be a client to your own code).
    3. Helping document how your code is expected to be used.

    Basically you need to weigh the time it will take you to write & maintain tests against these factors.

    Number 1 is usually sufficient to make it worth writing tests. In my experience, >95% of code gets modified sooner or later.

  3. Alex- Reply

    2019-11-14

    It's simple: you don't need unit testing if you will discard the program after running it once.

    If this seems excessive to you, consider what the alternative would mean. If there were some size below which unit testing doesn't pay, you would have to keep judging in your mind: "Have I reached the magic size yet? Should I start writing tests?" Now, programmers are notoriously bad at predicting the future, and they are notoriously bad at judging their own skill. Code that looks crystal-clear to you now will become incomprehensible, even to you, even by waiting a month. A project that you are absolutely, positively certain will never be used again, and that you keep around merely on the remote chance that you might want to look up how you solved something before, will be requested again, and will receive change requests.

    It is therefore very likely that you will misjudge whether or not testing is helpful, and when you do start needing tests, you're already not 100% sure what the exact semantics to test actually are. Since I believe that all except trivial one-off programs profit from unit tests, I consider the cost of expending effort on tests that are never run again to be negligible against the risks of extending untested and ill-understood code.

  4. Alan- Reply

    2019-11-14

    Some time ago I found a nice post: Why unit testing speeds up development. It can help you answer the question.

    ...What if the codebase... was provided with a substantial set of unit tests. A set that would say : “if all tests succeed, I guarantee that code still does what it should do” and if a test fails it exactly shows you where some behavior is broken . This is great, I could change the code to add things I want without wandering if the code still does what it should do, I just run the... tests and I have faith. This is a great world to be in as a software engineer. I noticed that I could advance way faster...

    I have “faith”.

    This is probably the most important reason why unit tests speed up development in a enterprise context.

    I can trust that everything still works if all tests pass. If tests fail they will point out exactly where the problem lays...

    ...you have to have a high unit test coverage and good unit tests. When these conditions are respected you’ll find yourself in a situation that the effort for adding new functionality ‘s is almost independent of the size of the application and that in the long run it will speed up development.

    Michael Feathers introduced in one of his books two ways of working with changes in code:

    • edit and pray,
    • cover and modify.

    It does not matter how big is the code base.

  5. Albert- Reply

    2019-11-14

    According to Kent Beck in his answer to Stack Overflow question How deep are your unit tests?, you should test the code that you tend to get wrong.

    If I don't typically make a kind of mistake (like setting the wrong variables in a constructor), I don't test for it.

  6. Andrew- Reply

    2019-11-14

    Unit tests are implemented to save time and improve:

    • bug tracking
    • refactoring and/or re-writing code
    • integration testing
    • regression testing, etc.

    It is a must to write unit tests for relatively complex parts of the program.

    If you are sure that writing unit tests now will not save your time in future, you can skip it. However, you never know, and personally I can't think of a case when it is cheaper (in sense of time, money and nerves) not to write unit tests but do all the testing manually instead.

  7. Andy- Reply

    2019-11-14

    "Should I unit test this" can usually be answered by answering the following question: "Is it important that this function works properly, and is it important for me to know when it stops working?"

    Of course, it's a lot more complicated than that, but that's a good way to start. Eventually you'll also weigh whether the code is already being tested by virtue of being used in another function, or whether your time would be better spent in another function, etc.

  8. Anthony- Reply

    2019-11-14

    Unless you are going to write code without testing it, you are always going to incur the cost of testing.

    The difference between having unit tests and not having them is the difference between the cost of writing the test and the cost of running it compared to the cost of testing by hand.

    If the cost of writing a unit test is 2 minutes and the cost of running the unit test is practically 0, but the cost of manually testing the code is 1 minute, then you break even when you have run the test twice.


    For many years I was under the misapprehension that I didn't have enough time to write unit tests for my code. When I did write tests, they were bloated, heavy things which only encouraged me to think that I should only ever write unit tests when I knew they were needed.

    Recently I've been encouraged to use Test Driven Development and I found it to be a complete revelation. I'm now firmly convinced that I don't have the time not to write unit-tests.

    In my experience, by developing with testing in mind you end up with cleaner interfaces, more focussed classes & modules and generally more SOLID, testable code.

    Every time I work with legacy code which doesn't have unit tests and I have to manually test something, I keep thinking "this would be so much quicker if this code already had unit tests". Every time I have to try and add unit test functionality to code with high coupling, I keep thinking "this would be so much easier if it had been written in a de-coupled way".


    TL;DR version:

    Write a test when the cost of writing the test, plus the cost of running it as many times as you need to is likely to be less than the cost of manually testing it as many times as you need to.

    Remember though that if you use TDD, the cost of writing tests is likely to come down as you get better at it, and unless the code is absolutely trivial, you will probably end up running your tests more often than you expect.

  9. Arthur- Reply

    2019-11-14

    Test as soon as you observe regressions happen or fear causing some with your edits and not noticing.

    Kindle that fear, let it grow to an adequate size: the sooner you test, the better.

    Please note: depending on your role in the project, unit tests may not be the only kind of tests you want to write.

    Everybody is rightfully obsessed with unit tests, because of bad mainstream testing practices in the past; but if you never tested before, you really should focus on testing in general, unit testing alone isn't going to solve world's problems.

  10. Austin- Reply

    2019-11-14

    I believe that it's not the size of the project but the type of project which decides if it should use testing or not.

    If you are working on a proof of concept, or on some other project where the goal is to learn from the coding, then testing is not required. If the project is meant to be used, maybe even sent into production, then it should be tested.

    A quote from Robert C. Martin's "Clean Code": "If it's trivial to write, it's trivial to test", so there's no excuse to skip on the testing for short and trivial programs.

  11. Ben- Reply

    2019-11-14

    It really isn't a matter of size-- it's what you do with it (and how old it is). If I'm noodling around learning how a technology works and plan on throwing the thing away (we call this a spike in Scrum), I'll just code without doing much testing. If you are planning on developing it further (even if you are just noodling around), you should write tests around the code. TDD is a design technique even before it is a testing technique. You want to have a clear picture of what you want the code to do before you get bound up in the particulars of the execution. I would also NOT recommend trying to write extensive unit tests around large amounts of legacy code. Try to identify those parts that are complex (have a high cyclomatic complexity/spaghetti code feel to them) and those parts which fail frequently (they will often be the same). As others have suggested, I'd go read Kent Beck's book on TDD and definitely read Michael Feather's book. What they don't cover very much is the political aspect to writing unit tests around code. A lot of developers hate having to alter their code to make it testable, and a lot of developers do not feel the need to test code at all. It is something we have to work on as a profession. Every other engineering discipline is required to prove (often mathematically) that their work met the specification. We should do the same.

  12. Benson- Reply

    2019-11-14

    Binding a Projects in limits of classes or functionality and then judging if this is suitable for unit testing may be wrong. There are numerous benefits of unit testing an application but real beauty starts when you have to maintain an application or have to work in distributed environment. So the choice comes here. Even a small change in your code can cause disasters.
    I would not only suggest 'Unit Testing' but would also recommend to check your code coverage, ensuring maximum of your code is covered with Unit Test. Threshold for code coverage shall not be less than 95% and target must be around 100%. You can go for tools to track your code coverage and generate a report.
    Visual Studio Provides Coverage Data - http://msdn.microsoft.com/en-us/library/ms182496(v=vs.80).aspx
    Also you can use NCover or dotCover.

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>