Test Methods are neither Methods nor Tests

Put on your life vest & tankini. We’re heading off into the deep end again.

You’re doing TDD. You are happy with the results, enjoying the thrill of going fast.

As with most C# projects done test-first, you have some code that looks like this:

      class C

      {

            public int F() { return 7; }

      }

      [TestFixture]

      public class CTests

      {

            [Test]

            public void Test1()

            {

                  C c = new C();

                  Assert.AreEqual(c.F(), 7);

            }

      }

Find the unit test in this picture.   If you answered “Test1()” you probably feel pretty smart.

But you’re wrong! Test1() is a method that contains a test. The actual test is this stuff:

                  C c = new C();

                  Assert.AreEqual(c.F(), 7);

The rest is just a convenient, language-acceptable package for the test. TestFixtures aren’t classes, they’re just a convenient way to package up a set of related tests.

Still don’t believe me? Try this one: Who calls Test1()? You’re probably thinking the answer is “NUnit”, but you’re hesitant to say that because I was so mean to you last time. Good.

The answer is: “no one”. Really. No one calls Test1(), it just runs.

Seem absurd? Try this instead: Who calls Main()? You’re thinking “The system”, but will answer “No one” because you think that’s what I want to hear.

Yep, no one calls Main(), it just runs. When you step in to your program in the debugger, you expect to see Main() at the bottom of the callstack; nothing else. Your program gets launched by the debugger, and Main() just runs.

It’s magic.

To repeat: Test methods are just convenient containers for tests. No one calls them, they just magically run.

If you don’t believe me, read again from the start. If you’re tired of re-reading, then pretend you believe me so you can continue.

So, what does it mean to mark a test method (or test fixture class) as ‘public’? It’s pointless. I don’t want anyone to ever instantiate my test fixtures or call my test methods.

Similarly, it’s pointless that my test methods have a parameter list of “()”. () means the parameter list is empty, but test methods have no parameter list. It’s the difference between “null” and “no value”.

And, finally, test methods have to be marked with the return type ‘void’, which is again pointless.

The only part that has value is the name. I definitely want to give my tests names.

It’s interesting to me that NUnit forces your test methods & test fixtures to be marked ‘public’. Do the Simplest Thing that Could Possibly Work says that the checks for ‘public’ should simply be removed. Further, the check that the return type must be ‘void’ should be removed. If there was a way to remove the check for the parameter list, I’d do that to. (NUnit would actually provide additional value by forcing test methods to be ‘private’, so no one accidentally calls one.)