Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

Zero-impact NUnit

So I'm working with a team of developers, and I want to use NUnit to start writing unit tests.  However, I only want to test public methods, and I don't want to have to add a reference to the NUnit framework in our software product (call it ProgramABC).  In other words, I want to implement this without having to change anything about our project or its structure.  What are my options?

(One thing I tried was creating a new project referencing both ProgramABC and NUnit, but ProgramABC compiles to an EXE, so VS .NET won't let me reference it in the new project.)

Kyralessa
Friday, May 13, 2005

The usual approach for testing public interfaces only is the one you tried, create a separate test assembly (class library) that references the components you are going to test.

Normally your EXE won't contain classes and methods which are intended to be public.  If you have marked any as public you could change them to internal without changing your app's behaviour.

Alternatively you could refactor some of the classes from your EXE to a class library that exposes them as public methods - then use NUnit to test this class library.

Joe
Saturday, May 14, 2005

You can reach any class and method in a given .NET assembly from any other assembly using reflection. It's a bit cumbersome but you could retrieve the required references just once, when your test suite is set up, and store them in private fields.

Chris Nahr
Saturday, May 14, 2005

The way I perform this kind of unit testing with VS .NET is by creating a new solution, and adding my application (ProgramABC) project to the solution, and building a new console app (TestApp) project to add to the solution.

Then I just reference the ProgramABC *project* and the NUnit DLLs in my TestApp.

Tharsan
Tuesday, May 17, 2005

For me it works the same way whatever you have the intentions to write tests for the serverside or clientside.

On the serverside you create a dll. Lets call it Server.dll. This dll hold everything that you would normally think of a business logic
"On top" of that dll you create asp or webservices. Lets call the webservices "ServerWebservices". The webservices is a thin wrapper, nothing more. This layer could also hold  loggin, validation etc.
For testing the server you create a project with a reference to NUnit and the Server.dll. Lets call the project "ServerTest.dll". You add all the serverside busniness tests here.

For the clientside you do almost the same. Yes i know that you normally have a exe to start the gui. But in my world the exe is just a boostrapper for the client. When you follow that idear, you end up with:
- Client.dll
- ClientTest.dll
- ClientGUI.exe

But testing the forms and controls in the client is hard. I would test the model and controllers in a model-view-controller setup and / or test the non-gui classes (loggin, agants, validators etc.).

A way to test forms and controls it to create a ClientGUITest.exe project as bootstrapper for the individual elements of the GUI.

Hope that you can use this simple idear.

Jesper F.
Monday, May 23, 2005

Here's an interesting idea I ran across the other day: put NUnit only in the Debug release through conditional compilation.

That is, I just enclose any Imports statements referencing NUnit, as well as any code blocks using any NUnit constructs, in #If DEBUG Then...#End If.  In theory, a Debug build would require NUnit, but a Release build wouldn't even care that it couldn't find a reference to it.

I've tested it a bit, and it seems to work OK; does anybody know any reason it wouldn't be a good idea?

Kyralessa
Wednesday, May 25, 2005

What's wrong with actually having the unit tests available in your live product?

theWeasel
Thursday, May 26, 2005

The danger of using #if DEBUG ... to only run unit tests on the debug build is that the existance of #if DEBUG means that the code in the release and debug can be different. By running NUnit only on the debug build, you're not actually testing the classes you ship with your product.

Jeff
Monday, June 13, 2005

As for shipping your unit tests, one reason not to is bloat. If you are testing all public methods of all your classes (you are, right?) how much does that add to the size of your exe? Plus there's the mock objects and fake objects that would add to the size of the exe too.

Plus, if you don't obfuscate your assemblies, shipping unit tests spells out exactly how to use your classes to anyone who bothers to look with a reflection tool. That's not so bad if your product is a class library for developers. But if you are shipping a shrisk-wrapped product that has intellectual property that your competitors might be interested in, you're giving too much away.

Jeff
Monday, June 13, 2005

*  Recent Topics

*  Fog Creek Home