C# Testing – How to Structure Unit Tests for a GUI App Using NUnit

cguinunittesting

I've been asked to do a small side-project to supply a simple application to one of our customers. Normally I would be working on back-end code where I have all of my testing needs figured out, and I've not yet had the dubious pleasure of writing tests for the GUI, so it's a little unclear to me how I should set up the testing code and tools for an EXE.

My first instinct was to simply include the tests with the application code, however that would require supplying a number of test-specific dependencies, which I have been instructed to specifically not ship to the customer. I am also unable to squeeze out any cash for a purpose built test tool, so I need to use the tools I have at hand (StoryQ, RhinoMocks, and NUnit), which really should be more than enough to test the behavior of a simple GUI app. So as far as I can see, this leaves me with trying to strike a good balance between keeping the design really simple, or purposefully over-engineering for the sake of the tests. It seems I'm either building the app with the business logic in a separate library and testing against the library as I usually would, or finding some other mechanism to allow me to the executable without breaking out additional modules that the application design doesn't really need.

Edit:
Please note that this question is about how to structure the relationship between NUnit and my executable – as opposed to a DLL – and not about how to separate presentation and business logic.
/Edit

So my question is:

  1. Is there a specific/recommended method for configuring a simple GUI application with unit tests to allow me to adequately check state and behavior, using the tools I have at hand, and without resorting to over-engineering?
  2. Have I missed something fundamental about the way NUnit should be invoked/configured when testing an EXE (as opposed to a DLL)?
  3. Can you provide or point me in the direction of examples of how achieve all of this?

I realize that there may be more than one way to do this so I'm looking for specific implementation guidelines based on your experience.

Best Answer

I mentioned in one of my comments to simoraman's answer that I had thought of a couple of ways to do this. One of my options was similar to the suggestion in Jalayn's answer to created a duplicate project and generate a DLL, while my other idea was to simply link to the files in the project where there was code I wanted to test. While both options could be made to work, they are less than ideal.

In the second case, I'd have a mess of unit dependencies to manage unless I could really tease apart the architecture to minimize dependencies. This is fine for smaller projects, but larger ones could easily become a real mess to manage. My biggest resistance to this option however is the sheer inelegance of it. Sure I could get it to work, but in doing so I effectively need to break encapsulation to test the internals of an assembly directly via source, rather than testing the via the public interfaces, which in my mind is a big no-no. Likewise having an additional project file would mean either duplicating efforts in two projects at a time, or finding a way to add project file settings automatically to two files at a time, or remembering to copy and rename the project field each time I build. This can be automated on the build server perhaps, but would be a pain to manage in the IDE. Again, it can work, but it's a kludge at best, and a nuisance at worse if you get it wrong.

The best way seems to be to do as whatsisname commented to my question, and to simply include the EXE as a reference in the test project. It turns out that an EXE is effectively treated the same way as a DLL in this case, and I am able to access all of my nicely layered classes to test whatever floats my boat.