views:

254

answers:

2

I have an existing VS 2005 Std .NET Compact Framework application that I want to do some major refactorings on. Currently there is no unit testing in place, but I want to add this before messing with the code. I have no practical experience with unit testing, even though I know the theory (just never got around actually implementing it; I know: shame on me :-)) Here are some questions I am pondering at the moment:

a) As a beginner, should I use NUnit or NUnitLite (which claims to be easier to use)?

b) Should I aim for running the tests on the mobile device or on the desktop (except for device-specific code of course)? Currently the desktop looks more appealing, especially for including the tests in automated builds...

c) How is the class that I want to test usually included in the test project? My application is a .EXE file, i.e. I can not just reference it like a .DLL assembly from the test project (or can I? Never tried this ...). I checked various NUnit tutorials but either found no mention of that, or one tutorial suggested to copy and paste the class that I want to test into the test project (yuk!). Should I link to the original source code file in my test project? What about private methods, or dependencies on other classes?

d) Should I start modifying my original code to allow better testability, e.g. make private methods public, decouple etc.? This is a bit like refactoring before being able to test, which does not sound good to me ... Or is it better practice to not touch the original code at all in the beginning, even if this means less code coverage etc.?

e) Should I look into any other tools or addons that most people use?

Thanks in advance for any answers (I also appreciate answers if they are only to one or some of the above items).

+5  A: 

First, I would recommend you a good book on unit testing: Pragmatic Unit Testing in C#.

It will introduce you to NUnit, but what's more important, the author will provide you a lot of advices how to write good unit tests in general. The xUnit test frameworks are not very complex and you'll get used to their API/workflow very quick. Challenging is the actual process of identifying boundary conditions, decrease coupling and design for testability. It's available as an eBook (PDF) or a printed copy.

Regarding your actual questions (the book will give you some answers, too):

  • @a) I've no experience with NUnit lite, thus I cannot give you any advice on this point.
  • @b) Unit tests are supposed to be very local in regard of their dependencies. You aim to test classes independent of each other, thus there would be no need to deploy it on a mobile device first. You won't run the full app, just test components in isolation. Hence, I would recommend to use your desktop machine as the target for your unit test environment. You'll get better turn-around times, too.
  • @c) You have to reference the assembly that contains the classes you want to test in your test project. The test project will be an assembly itself (DLL). A test runner executes this assembly and uses the stored meta information to run the contained test cases.
  • @d) It depends a lot on the state and design of your software. But in general I would use a divide and conquer strategy: Introduce interfaces between classes and start to refactor step by step. Write unit tests before you start to change the implementation. The interfaces keep the contracts up and running, but you can change the underlying implementation if necessary. Don't make private methods public just to make them testable. Private methods are internal helpers of the class that support public methods in doing their job. Since you test your public methods you'll assert that your private methods do the right thing.
  • @e) A helpful add in for Visual Studio is TestDriven.Net. It allows you to run NUnit tests directly from the IDE without changing to NUnit's GUI or console runner.
olli
+1 great book. Bought it based on the advice from someone on SO and haven't regretted it at all (specifically, the entire pragmatic starter kit)
SnOrfus
+2  A: 

@c) I haven't tried it, but I would think VisualStudio would let you add a project reference from your test assembly to your actual code assembly, even if its an exe.

As for private methods and such, generally I don't test private methods. In theory, all the private stuff should be used by public or internal methods, so testing those should indirectly test the privates.

I do test public and internals though. One thing I find very helpful is the InternalsVisibleTo attribute:

[assembly:InternalsVisibleTo("MyTestAssembly")]

which you can use to make the internals of one assembly visible to another. I use this attribute to expose the internals to my test assembly, so that it can directly reference them.

rally25rs