Reputation: 11
Question: Is there a way to manually name a test method instead of taking the methodname?
Background: I'm currently active as a BizTalk developer and we use the BizUnit framework to test our projects.
To get these unit tests running we use the internal features for unit testing build in visual studio using c#, from which we call the bizunit framework to do the actual (biztalk specific) testing.
The annoying thing about this is that we need several lines of "boilerplate" code to create the testcases needed by BizUnit; the use of abstract classes which perform these steps facilitates the actual development we need to do. Furthermore abstract classes allows us to enforce some "internal policy" concerning the document structure (through the use of several template methods).
The abstract base class "IBaseTestScenario" contains the actual method which is called "test":
[TestClass]
public abstract class IBaseTestScenario
{
private enum Phases { describeTestCase, addSetupSteps, addExecuteSteps, addCleanupSteps, persistTestCase, runTestCase };
private Phases currentPhase
{
get;
set;
}
[TestMethod]
public void test()
{
// construct an empty testcase
TestCase testCase = new TestCase();
// loop each phase and perform the appropriately actions
foreach (Phases phase in Enum.GetValues(typeof(Phases)))
{
try
{
currentPhase = phase;
MethodInfo phaseMethod = this.GetType().GetMethod(currentPhase.ToString());
phaseMethod.Invoke(this, new object[] { testCase });
}
catch (Exception) { }
}
}
#endregion
#region Describe TestCase
public void describeTestCase(ref TestCase testCase)
{
// required descriptions
testCase.Name = getName();
testCase.Description = getDescription();
}
protected abstract string getName();
protected abstract string getDescription();
#endregion
...
}
Using this structure we can enforce the order in which steps are taken, we can "remind" developers to provide a decent name and description (since the methods are abstract, they would be forced to provide the info) and the actual code that does the testing (that is specific for each scenario) is split from the boilerplate code.
When we want to create a scenario we simply need to extend this base class and implement the abstract methods that contain the scenario-specific information.
[TestClass]
public class TestTest : IBaseTestScenario
{
protected override string getName()
{
return "TestSCTest: Testing the tests";
}
protected override string getDescription()
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("This is a test for testing the testinterface.");
sb.AppendLine("[SETUP]");
sb.AppendLine("-+-- Add a delay of 1 second");
sb.AppendLine("[EXECUTE]");
sb.AppendLine("-+-- Add a delay of 2 second");
sb.AppendLine("[CLEANUP]");
sb.AppendLine("-+-- Add a delay of 1 second");
return sb.ToString();
}
protected override void constructSetup(ref TestCase testCase)
{
DelayStep delay = new DelayStep
{
DelayMilliSeconds = 1000
};
add(delay);
}
protected override void constructExecute(ref TestCase testCase)
{
DelayStep delay = new DelayStep
{
DelayMilliSeconds = 2000
};
add(delay);
}
protected override void constructCleanup(ref TestCase testCase)
{
DelayStep delay = new DelayStep
{
DelayMilliSeconds = 1000
};
add(delay);
}
}
This all looks pretty neat until you run the tests...
In the test results window all tests are called "test" and you need to add the "Class name" column to the view to be able to tell them apart.
The quick (and rather dirty way) of solving this problem would be to remove the TestMethod-annotation in the interface, and put the following "invoker" in each single implementation
[TestClass]
public class TestTest : IBaseTestScenario
{
#region Invoker
[TestMethod]
public void GiveMeaningfulName()
{
test();
}
#endregion
...
}
Does anyone know a (better) way to change the name of the testmethods? Using the existing abstract method "getName()" of the interface would be ideal...
Kind regards,
Stijn
Upvotes: 1
Views: 271