Tests aren't methods!

In the feedback section of one of my blogs, Aaron Junod wrote:

“In writing this, I just realized something. I think someone should draw a line between writing tests, and actual program code, and then offer different options based on that. They are totally diff coding paradigms, and really merit diff behaviors not only in the compiler, but the IDE.. Hmm.. think I gotta think about this more.”

I told him I wasn't going to respond and I'd let Jay get a chance to voice his opinion on this, and he has! (Hurrah!)   The issue arose when dealing with our frustration that NUnit forces both your TestFixture class (which is unnecessary) to be public (which is unnecessary) and requires that all tests in that class (which is unnecessary) to be public (which is unnecessary).  Wow.  That's a whole lot of unnecessary stuff.  What irked us was that when we were trying out the new VS Team System tools, they also had these restrictions.  Jay inquired into the reasoning behind these decisions and raised several good points for why this restrictions was a “Bad Thing”.  They were:

  1. Nothing about the concept of a unit test has anything to do with a method.  A unit test is just code that runs and tests something for you.  We package it in a method because a method is a convenient way of naming something and packaging a set of statements together. However, a method carries unnecessary overhead that just isn't necessary in a test. The concept of it having accessibility, input or output parameters is just meaningless and unnecessary.  Imagine if a unit test required you to take an integer as an argument.  It would be pointless and would just burden the programmer. Similarly, by forcing a test to be contained in a method which is public you are unnecessarily burdening the programmer.  This makes the test visible to people interacting with the system.  Which is completely unnecessary.  The test should only exist so that the engine can run them and report the results back.  Of course, if a user wants to make his tests publicly accessible, he can.  But he should not be forced to.
  2. Forcing the tests to be public goes against the XP philosophy of “do the simplest thing that could possibly work”.  In order to have this restriction someone had to go out of their way to prevent it from happening.  Why would you ever do that?  Why do extra work in order to limit what the customer wants to be able to do?  If you listen to the new Office System commercials, they espouse the philosophy of “Do more with less”.  But here we are doing the opposite.  We are doing extra work to make sure that you can't do something. 
  3. The Team System software isn't supporting a completely reasonable coding style.  With the team system method you will end up with a loosely couple system where you have “class MyClass” and a “public class MyClassTests”. Jay wants to code in the manner of “class MyClass{ class Tests {} }” so that he has tight coupling between the class and the code that tests that class. That way if he moves the class around, the tests stay with it. If he renames the class he doesn't have to worry about renaming the test class, and he doesn't have the redundancy of “MyClass” specified twice.

Note: Jay is not saying that everyone should test in his style.  He is saying that both styles can be supported with less work on the Team System team. 

I'd like to know your thoughts on this so I can take back some feedback on what the community thinks.  I would appreciate a discussion on why you think it's a good or bad idea to force tests to be public.  Addressing all of Jay's issues would be very useful, and if you can introduce points as to why limiting what the user can do here is a good thing, then we'd like to here them.  Remember, jay is not saying “force the test to be private”, he's saying “support this behavior which doesn't prevent anything that a user can currently do with the system”

Thanks!