I know a bunch of people have not been too enthusiastic about the unit testing features built into VSTS. Some people have become infatuated to many of the features of mbUnit. They are cool. But I like VSTS because of the built in code coverage capabilities and the integration with TFS.
While working on my current project, I got to thinking about some of these missing features and sought out to fill in a couple of gaps. The result of a couple of nights of hacking and watching football is my VSTS framework. With it, you can create attributes to annotate test methods and somewhat extend the built in tools.
The source is here.
One caveat I must mention. Your test classes must derive from Newbrook.VSTS.UnitTestFramework.UnitTestBase. The derived class must also not provide methods annotated with [TestInitialize] or [TestCleanup]. UnitTestBase provides virtual OnInitialize and OnCleanup methods to get the same functionality, but took over those attributes to hook into the test infrastructure.
Some of the attributes I created were:
1. Rollback. Yes...inspired by Roy, I created a Rollback attribute that wraps the annotated test in a System.Transaction that always gets rolled back. Usage
[TestMethod]
[Rollback]
public void PerformSomeDatabaseTests()
{
//Make some databasebase calls...
}
2. RequiresFileFromResource. This is an interpretation of Chris Smith's idea. Basically, when you need some files for a test, just embed the file as a resource in the test assembly and then reference it by name like:
[TestMethod]
[RequiresFileFromResource("SampleTests.Properties.Resource", "Icon1", "MyIcon.ico")]
[RequiresFileFromResource("SampleTests.Properties.Resources", "Image1", "MyImage.bmp")]
public void PerformSomeTestOnMyIconAndMyImage()
{
}
or
[TestMethod]
[RequiresFileFromResource(null, "SampleTests.ResourceFile.htm", "ResourceFile.htm")]
public void PerformSomeTestOnResourceFile_HTM()
{
}
The first method shows two things. First off, you can have multiple RequiresFileFromResource attributes on a single test method. Secondly, this is how you would copy off a resource from the Resources mechanism in VS 2005.
The second method shows how you would copy a file that is in the project that has the Build Action set to Embedded Resource.
3. TimedTest. This attribute will cause a test to fail if the test takes longer than the timespan specified.
[TestMethod]
[TimedTest("00:00:05")]
public void ThisTestWillFail()
{
Thread.Sleep(new Timespan(0, 0, 6));
}
4. EnvironmentVariable. This attribute will alter an EnvironmentVariable for the scope of the annotated test.
[TestMethod]
[EnvironmentVariable("PATH", "%PATH%;E:\\")]
[EnvironmentVariable("MyTest", "Some Value")]
public void PerformEnvironmentVariableTests()
{
}
5. ParameterizedDataMethod. This is a complex attribute that needs to be used in conjuction with the DataSource attribute in VSTS. Let me setup the scenario. First off, I include a testfile.csv file in my project and add a setting in the .testrunconfig file to copy that file to the testdirectory (kind of hacky, but very handy.) My testfile.csv looks like:
Column1,Column2,Column3
Hello,-123,12/3/2006
World,42,12/31/2006
Then create a test like:
[TestMethod]
[DataSource("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=.;Extended Properties=\"text;HDR=Yes;FMT=Delimited\"", "testfile.csv")]
[ParameterizedDataMethodAttribute("RealTestMethod6")]
public void TestMethod6() { }
//This method gets called when TestMethod6 is called!!!
public void RealTestMethod6(string column1, int column2, DateTime column3)
{
}
In this scenario RealTestMethod6 gets called twice with the typed variables in the columns of the csv file.
<sidebar>
I haven't seen a whole lot of talk on the DataSource attribute. I love it. I use it alot for some black box testing of methods. I will typically use the first couple columns to pass parameters into the test. Then next column is my expected result and I include one additional column for ExpectedException. If you have 1 test and it is a DataSource test and it has 5 DataRows, then you will see a total of 6 tests pass/fail.
</sidebar>
Send me a line if this is beneficial or if you have some feedback or enhancements. If pepole like it and want to work with it, I'll stick it in CodePlex.