Reputation: 19
I'm unit testing with console apps. So, anywhere I want to unit test i'm using compile conditionals like so
#if UnitTest
Console.WriteLine("Invoke: Method 1 Result");
#endif
This works great, but it makes for messy and ugly code. How bad would it be, how much of a resource hit would it be, for me to invoke something like below.
public static class UnitTest
{
public static void Add(string value)
{
#if UnitTest
Console.WriteLine(value);
#endif
}
}
and then, when ever I want to place a unit test, i simply call.
UnitTest.Add("Invoke: Method 1 Result");
Upvotes: 0
Views: 329
Reputation: 660455
You are so close.
The right way to do this is
public static class UnitTest
{
[Conditional("UnitTest")]
public static void Log(string s)
{
Console.WriteLine(s);
}
}
The compiler will remove all calls to UnitTest.Log()
in source code where UnitTest
is not defined.
Obviously, i'd be calling a method that does nothing.
That's the nice thing about the conditional attribute. The compiler removes the call entirely.
Incidentally, this is how Debug.Assert
works. If DEBUG
is not defined, the assertion is removed entirely.
This has the benefit of not littering your release version with calls to empty methods. It has the downside that if you are debugging the release version, you cannot put breakpoints on the removed methods. Also, remember that side effects are also removed; never do:
Debug.Assert(++x == 10);
Because the ++x
will not happen in the release version but will in the debug version.
Speaking of which, you might wonder, can I do this?
class C {
#if UnitTest
static int counter = 0;
#endif
...
UnitTest.Log("Logger logged " + (++counter) + " logs!");
Give that some thought. Should this work, or not? Remember, reason like the compiler writer.
Once you think you know what the compiler should do here, check your answer:
Upvotes: 4