For Java programs, I recommend that the unit tests be placed in the same package as
the code being tested.
This allows you to test not only the public methods, but also the protected and package
friendly methods.
Of course, in Java, you may create multiple Jar files in a way that two classes belonging
to the same
package may reside in two different Jars. So, you may place your class in a Jar and
the test code in another
Jar. This makes it convenient for you to deploy the code and hold back the tests if
you desire.
What about .NET? In .NET, the access control of internal is at the project/assembly
level. In order to be
able to test the non-public methods of a class, I
had suggested in the past that you put the test code in the
same assembly/project as the code to be tested. The disadvantage of this approach
is that it is hard to hold
back the test code if you don?t want to release it. You will have to find ways to
exclude your tests from
your build when you intent to release your assembly for others to use.
In .NET 2.0 you can declare an attribute InternalsVisibleTo() in
your AssemblyInfo file. Using this
attribute, you may specify the name of the assembly which is allowed to access the
internal members (or
protected internal members) of your class in the declaring assembly.
This leads to the possibility of keeping your test code in a separate assembly/project.
In fact, this is a much
better option than putting the test code in the same assembly as the code being tested.
You can write as
many test assemblies as you like. Different developers may write their own test assemblies
of their choice.
These can be maintained and managed separately. You can selectively run different
tests from different
assemblies. These don?t get released unless you do so with intent.
One concern is that InternalsVisibleTo() may be abused
to open up access to internal methods in your
assembly. The developer?s good judgment hopefully kicks in at this point.
Another concern I have about InternalsVisibleTo() is
that it only takes the name of an assembly. I was
hoping it would allow me to specify the fully qualified name for the assembly, that
is, the name of the
assembly, the version number, its strong name and culture. Unfortunately, it does
not (at least not in Beta
2). I am concerned if this would leads to some possible hacks by others who can write
assembly with the
same name and gain access to internal methods? Am I just being paranoid here?
Leaving these concerns apart for a minute, and focusing on unit testing, I like the
idea of this
InternalVisibleTo() attribute. It allows me to separate my unit test physically from
the code it is testing. I
am all for it.