Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Starting UnitTesting on a LARGE project

Can anyone recommend some best-practices on how to tackle the problem of starting to UnitTest a large existing CodeBase? The problems that I'm currently facing include:

  • HUGE code base
  • ZERO existing UnitTests
  • High coupling between classes
  • Complex OM (not much I can do here - it's a complex business domain)
  • Lack of experience in writing UnitTests/TDD
  • Database dependency
  • External sources dependencies (Web services, WCF services, NetBIOS, etc)

Obviously, I understand that I should start with refactoring the code, to make it less coupled, and more testable. However, doing such refactoring is risky without UnitTests (Chicken and Egg, anyone?).

On a side note, would you recommend starting the refactoring and writing test on the Domain classes, or on tier classes (logging, utilities, etc)?

like image 873
SaguiItay Avatar asked Jan 20 '09 23:01

SaguiItay


People also ask

How do you add MS test to a project?

On the Create a new project page, type unit test into the search box. Select the project template for the test framework that you want to use, for example MSTest Test Project or NUnit Test Project, and then select Next. On the Configure your new project page, enter a name for your project, and then select Create.

How big should a unit test be?

There is no concrete rule for the size of a unit test obviously, but there are some heuristics people use when writing unit tests. A couple of them are that a unit test shouldn't exceed a dozen or so lines and a unit test shouldn't take more than a minute to write. Unit tests are supposed to be as short as possible.

How do you introduce unit testing?

To perform unit testing, you have to test every output of your code unit with their expected return value to confirm if they adhere to their contract. Run your tests to confirm if your code unit is working as expected. Now, say you were to change the expected output of your test to a wrong value.


3 Answers

First, I second the "Working Effectively with Legacy Code" recommendation Jeffrey Frederick gave.

As you stated in the question, you cannot change your code because you currently have no unit tests available to detect regressions, and you cannot add unit tests because your codebase is not unit-testable. In this situation, you can create characterization tests : end-to-end automatic tests that would help you detecting changes in the external behavior of your software. Once those are in place, you can start to slowly modify the code.

However, putting your HUGE code base under test is an enormous effort, highly risked, and you'll probably burn out the team doing this as they will have to produce strong efforts with low reward in terms of test coverage. Putting the entire code base under test is an endless effort.

Instead, develop new capability out of the code base, so that it won't hinder you. Once the new code is fully tested, integrate it in the code base.

Also try to create unit-tests every single time you fix a problem in the code base. It will be hard the first times, but it will get easier once you'll have some unit testing environment ready to be setup.

like image 111
philant Avatar answered Sep 30 '22 17:09

philant


Lack of experience in writing UnitTests/TDD

I think this is the most significant.

Standard advice is to start writing unit tests for all your new code first so that you learn how to unit test before you attempt to unit test your existing code. I think this is good advice in theory but hard to follow in practice, since most new work is modifications of existing systems.

I think you'd be well served by having access to a "player coach", someone who could work on the project with your team and teach the skills in the process of applying them.

And I think I'm legally obligated to tell you to get Michael Feather's Working Effectively with Legacy Code.

like image 21
Jeffrey Fredrick Avatar answered Sep 30 '22 18:09

Jeffrey Fredrick


There good advices in book Manage it! by Johanna Rothman.

I could also recoment the following:

  1. Use unit test on newly created source code fregment
  2. Create unit test for bugs
  3. Create unit test for the riskiest part of the application
  4. Create unit test for the most valuable part of the application.
  5. If the coupling is too high create test which are more module or integration tests but automated.

One single unit test will not help. But it is needed to start. After while there will be handfull of unit test on the most riskiest part of the application and that will help preventing bugs in those segments. When you get to this point most of the developers will realize how usefull unit tests are.

like image 37
takacsot Avatar answered Sep 30 '22 18:09

takacsot