Unit Testing

I'm converting an old legacy program to a new OOP design, and I'd like to include Unit Testing, since I've read that's so wonderful.

I'm realizing my OOP design is a huge tree structure of classes.

At top I have a Machine class.

The Machine class has a Model class, a View class, and a Controller class. Each of those classes contains numerous other classes, and those classes in turn contain other classes, and on and on.

It appears Unit Testing has to be done from the bottom up. I can only easily create a leaf class—a class which has no subclasses.

I can't easily create a Machine class, for instance, because the entire tree of other classes that are needed haven't been written yet.

Are OOP programs grown from the bottom up? I write the leaf classes first, write Unit Tests for those, then the classes that use those leaf classes, and work my way up?

I'd like to test how the controller writes to the screen, to see if that actually works, but to do that I need to instantiate a Controller class, and a Screen class, and the Machine class is what hooks them together, but I can't create a Machine class because the entire tree of other classes involved haven't been written yet.

So it's sounding like I can't test the design to see if it's viable until all the code has been written. How does one get around this?

For example (see attached UML diagram), to test if MainMenuController can put text on the screen, I have to create classes MainMenuController, MenuController, ScreenController, MachineController, Machine, MachineView, ScreenView, ScreenData. Plus I have to create dummy classes for MachineModel, BetaController, and possibly others. This seems like a lot of work for Unit Testing.

I also haven't found a good Unit Testing framework. I have Visual Studio 2010, and there is some Unit Testing capability in it. I've tried xUnit, but couldn't get it to work.
Who is Participating?
TommySzalapskiConnect With a Mentor Commented:
It's not that unit testing has to be done from the bottom up, OOP really has to be done from the bottom up. If you have a Machine class that contains a Model, then you need the Model to be defined before you can compile the Machine.

For the unit test, you don't need the Model to do everything it's supposed to do though. You just need it to do enough that the Machine class thinks it's working.

In fact, it is typical in unit tests to write fake classes for testing how your class will interact with other classes. For example, when you want to test your Screen class, if you do it "right", you don't need an actual Controller. You can make a TestController class that inherits from the same interface base class but only does very simple things that you can use to test the Screen class. Then you don't need to stand up an entire Machine just to get a Controller to send a string to the Screen class. You just send the string.

Of course, for all that to work, you'll need to have written "testable code." Check out how the folks at Google do theirs.
phoffricConnect With a Mentor Commented:
>> This seems like a lot of work for Unit Testing
I commented to a manager once that my UT were taking more time than my development code. He replied that UT is double the effort of the actual code being tested. (That is, if it takes 1 day to write a module, then you can expect to spend two more days to complete the UT.)

>> I'd like to include Unit Testing, since I've read that's so wonderful.
1) It is only as good as how deeply you understand the code being tested. If you inherit code and do not understand every line as if you had written it yourself, then there is a decent chance that your UT will not be so useful. UT should be tested against a written description of inputs, outputs, and side-effects ofa function; and not solely based upon the code you are looking at. You can always make a UT pass by forcing the UT to pass for a given code even if the code doesn't do what the written requirements says it should do.

2) I was surprised to learn that on one project they did no UT at all. They just skipped the UT and did system test. I guess it was ok for them since they were successful; but when we took their libraries for another project, it was a pain to start writing tests. For them, UT was considered not so wonderful, but a time-waster.

On a previous project, we used CPPUnit testing framework. On current project, I am learning to use Google Test  which was easy to get working on Ubuntu 12.04. I haven't tried it on VS 2010, and I see that there are some challenges to get it to work. But here is a link that tries to help you through the problems. Hope it helps.

UT are not supposed to test a function even if its dependencies are not available. (When the become available, you can then add Integration Tests to your regression test suite.) To handle the lack of code, you simply add stubs which can return different reasonable values on successive calls to get full test coverage. This requires that you have a written description of the api's for these functions that are not yet written.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.