views:

699

answers:

11

I have a largish complex app around 27k lines. Its essentially a rule drive multithreaded processing engine, without giving too much away Its been partially tested as it's been built, certain components.

Question I have, is what is the pro's and con's of doing unit testing on after the fact, so to speak, after its been implemented. It is clear that traditional testing is going to take 2-3+ months to test every facet, and it all needs to work, and that time is not available really.

I've done a fair bit of unit testing in the past, but generally it's been on desktop automation or LOB apps, which are fairly simple. The app is itself is highly componentized internally, interface driven really. I've not decided on what particular framework to use. Any advice would be appreciated.

What say you.

+3  A: 

If you are doing any refactoring, those tests will help you detect any bugs that will appear in the process.

gruszczy
+20  A: 

I think there are several advantages to unit testing existing code

  • Regression management
  • Better understanding of the code. Testing it will reveal cases you did not anticipate and will help define the behavior of the code
  • It will point out design deficiencies in the code as you stuggle to test poorly defined methods.

But I think it's more interesting to consider the cons of unit testing code. AFAIK, there are no cons. All of the time spent adding tests will pay for themselves even in everything but the shortest of time cycles.

JaredPar
+1 for better understanding of the code. I'm currently working on refactoring a system based on problems I found while writing unit tests for common use scenarios.
Anna Lear
I really wouldn't say there are no cons. You can easily sink a lot of time trying (and failing) to write tests for a system that wasn't designed with testability in mind, or writing tests for easily testable but stable and largely bug-free parts, and end up with very little value and/or a test suite that is very hard to maintain.
Michael Borgwardt
Very few significant blocks of code are genuinely bug-free and stable when they haven't been unit tested. There's all those rare conditions that you've never triggered yet.
Steve314
If you haven't thought to trigger it, then why would you think to write a unit test for it?
quillbreaker
@Michael, true there are initial start up costs and I can see how it could be considered a con if you get a bit to aggressive at the start. But in general I find I can at least begin testing leaf portions of the product with very little cost.
JaredPar
For "normal" testing, the tester doesn't know what units there are, and doesn't know what rare conditions exist in each unit, and even if he does, it's very hard to know how to trigger them through the whole integrated system. You can get, for instance, conditions that only occur with rare thread-related timing issues, that you simply cannot trigger them by choice on a running system. If you write the unit test and the unit at the same time, you can see all the decision points and test them. There are even tools that will check your test coverage, if you really want to get serious.
Steve314
@Steve314: you're describing TDD, or something close to it. But that's not the case we're discussing here. My point is that when writing tests after the fact, there are usually parts of the application that are easy to write tests for, and parts where it is much harder, as well as parts that benefit more from tests than others. If you start with the wrong parts, you expend a lot of effort for little benefit, which can result in the whole thing getting cancelled by management.
Michael Borgwardt
Even after the fact, it's still unit testing - you still look at the source code when writing the tests. I don't think it'll help here - the guy doesn't have enough time even without unit testing, and doing unit tests now won't save doing any of that existing work. But my point is exactly what I said - very few significant code blocks don't have bugs, particularly without unit testing.
Steve314
+1: There are no cons. You can spend money into trying (and failing) to write tests which show you that you have quality issues. This is not "sunk" -- this is "learning". Learn now what you need to fix when you have a fighting chance of fixing it.
S.Lott
+6  A: 

Here's a few of each to my mind:

Pro:

  • Time is saved in not having to test methods that have been removed as the design evolved over time. What is left is what really has to get tested.
  • By adding tests, this allows an opportunity to review all the aspects in the app and determine what other optimizations one could add now that a working prototype is ready.

Con:

  • Large time investment to get the tests written, new functionality may be delayed for some time to generate all the tests.
  • Bugs may have been introduced that the tests will discover that may cause this to be longer than initially planned.

The main point would be that adding unit tests allows for refactoring and putting more polish on the application.

JB King
+2  A: 

Unit testing "after the fact" is still valuable, and provides most of the same advantages of unit testing during development.

That being said, I find it's more work to test after the fact (if you want to get the same level of testing). It's still valuable, and still worth while.

Personally, when trying to tackle something with limited time, I try to focus my testing efforts as much as possible. Any time you fix a bug, add tests to help prevent it in the future. Any time you're going to refactor, try to put enough testing in place to feel confident you're not going to break something.

The only con of adding unit testing is that it does take some development time. Personally, I find that the development time spent on testing is far outweighed by the time saved in maintenance, but this is something you need determine on your own.

Reed Copsey
+1  A: 

Unit testing is still definitely useful. Check out http://en.wikipedia.org/wiki/Unit_testing for a full list and explanation of the benefits.

The main benefits you will gain are documentation, making change easier, and it simplifies future integration.

There are really no costs to adding unit testing except your time. Realize though that the time you spend adding unit testing will reduce the amount of time you will need to spend in other areas of development by at least the same amount and most likely more.

RandomBen
+5  A: 

I think one of the biggest con of testing "after the fact" is that you will probably have a harder time testing. If you write code without tests, you usually don't have testability in mind and end up writing code that is hard to test.

But, after you spent this extra time writing tests and changing your code for better testability, you'll be much more confident about making changes, once you won't need a lot of time to debug and check if everything is ok.

Finally, you might find new bugs which weren't caught before, and spend some time fixing it. But hey, that's what tests are for =)

Samuel Carrijo
+8  A: 

There are many reasons to unit test code. The main reason I would advocate unit testing after the fact is simple. Your code is broken, you just don't know it yet.

There is a very simple rule in software. If the code is not tested, it's broken. This may not be immediately obvious at first, but as you begin testing, you will find bugs. It's up to you to determine how much you care about finding these bugs.

Besides this, there are several other important benefits of unit testing,

  • regression testing will be made simpler
  • other developers, that are less knowledgeable, can't break your desired behavior
  • the tests are a form of self documentation
  • can reduce time in future modifications (no more manual testing?, less bugs?)

The list can go on and on. The only real drawback is the time it takes to write these tests. I believe that drawback will always be offset by the time it takes you to debug problems you could have found while unit testing!

Chris Wilson
I totally agree.
scope_creep
Code can still be broken when it has gone through unit testing and passed - but I certainly agree with the basic point.
Steve314
A: 

Unit testing doesn't prove that a system works. It proves that each unit works as an independent unit. It doesn't prove that the integrated system will work

Unit testing "after the fact" is useful for two things - finding bugs that you've missed so far and won't find using any other kind of testing (especially for rare conditions - there's huge numbers of rare conditions that can happen in particular units for any real world system), and as regression tests during maintenance.

Neither of these is going to help much in your situation - you need to do other forms of testing either way. If you don't have time to do what you need to do, taking on even more work is unlikely to help.

That said, without unit testing, I guarantee you will have nasty surprises when the customers start using the code. It's all those rare conditions - there's so many of them that some of them are bound to occur soon. Black-box testers tend to get into habitual patterns, which mean they only test so many rare cases - and they have no way of knowing what rare cases there are in particular units and how to trigger them anyway. More users means more variations in usage patterns.

I'm with those who say unit tests should be written as part of the programming process - one of the programmers responsibilities. As a rule, code gets written faster that way, as you get fewer and less complex bugs to track down as you go, and you tend to find out about them when you're still familiar with the code that has the bug.

Steve314
+3  A: 

Pro post facto unit testing:

  • Get documentation you can trust.
  • Improve understanding of the code.
  • Push toward refactoring and improving the code itself.
  • Fix bugs that lurk in the code.

Con post facto unit testing:

  • Waste time fixing bugs you can live with. (If you wrote 27KLOC, we hope it does something, right?)
  • Spend time understanding and refactoring code you don't need to understand.
  • Lose time that could go into the next project.

The unasked question is just how important an asset is this code to your organization, long term? The answer to this question determines how much you should invest. I have plenty of (successful) competitors where the major purpose of their code is to get out numbers to evaluate some new technique or idea. Once they have the numbers, the code is of little marginal value. They (rightly) test very carefully to make sure the numbers are meaningful. After that, if there are fifty open bugs that don't affect the numbers, they don't care. And why should they? The code has served its purpose.

Norman Ramsey
This is production code, not prototyping code but I understand your point.
scope_creep
+2  A: 

Depending on how many bugs "manual testing" turns up, you could simply do test-driven bug fixing which in my experience is far more effective than simply driving up code coverage by writing "post-mortem" unit tests.

(Which is not to say writing unit tests afterwards is a bad idea, it's just that TDD is almost always a better idea.)

Epaga
I agree. I would never take on another product development of this size without TDD.
scope_creep
A: 

If development is "done" I would say that there is not too much point in unit testing.

sixtyfootersdude