In the previous project to do unit testing has been using NUnit, this time to do a new project, the person responsible for unified use MSTest, the reason is that MSTest is Visual Studio built-in. Use it, I have no opinion. After two days, I found a big problem: MSTest does not support parametric testing (also called line testing).
What is parametric testing? Simply put, it is the same logic that gives different results depending on the input parameters. Because only the parameters are different, you do not want to write the test multiple times, but you want to test each parameter as a separate test case. For example, suppose I have a mathematical method of counting the numbers, and I want to show that this method is for positive, negative, and 0. In NUnit, you can use Testcaseattribute to provide parameters for your tests:
[TestCase (][testcase)(00)][testcase (-123, -246)]publicvoid testdouble (intint result) { assert.areequal (result, calc.double (value));}
However, there is no similar function in MSTest attribute. What do we do? The simplest and most brutal method of course is to write a loop to provide the parameters. But this is not the result I want, the first is to write loop traversal of the code is a bit pointless, more importantly, the loop can only be used as a whole test case to execute, if the error does not write their own information can not tell exactly which parameter error.
Search the Internet, found that people who ask similar questions really a lot. Basically the answer focuses on the following scenarios:
1. VS2012 Update1 provides the DataRow attribute later, but can only be used in Windows Store apps. (personally think this is wonderful, a test function is it necessary to special preferential treatment store users?) In short, we do the ordinary class library, this way does not apply.
2. Using Datasourceattribute, you can provide the OLE DB data source, XML, or CSV file as a data source according to the documentation. For simple parameter testing this scheme is a bit too heavy, and is it still a unit test to use a unit test that uses an external file or database as defined?
3. Extend the test by using the Postsharp enhanced code method. I probably looked at the program and gave up, after all, Postsharp is a relatively non-mainstream technology, and the use of it will significantly increase the complexity of the compilation process, the continuous integration is a bit unfriendly.
4. Follow the MSTest object model to write some extended properties. Honestly, before looking for a solution, I have been in the heart of the decision to go this way, and in accordance with the network example really write a few extended properties to test, compile is normal, but the test is dead or alive to run. A closer look at the instructions, the original to run the extension test in Visual Studio also modifies several registry keys .... Well, our development group of teenagers are going to toss the registry to test it, and let the little friends play together happily. In short this program is also pass.
It seems that there is no satisfactory way to look, the only viable thing is to use DataSource. Of course, I would not use a database such a heavyweight data source, that unit test is completely anti-aircraft anti-flak mosquito. In the case of documents, there are also problems with the idea of agile development, but the document is relatively easy to control after all. So I tested it with an XML file, passed, but there are a few pits to note, here to record.
The code example below, very simple, does not explain:
[Testclass][deploymentitem (@"Fixtures\add.xml")] Public classunittest1{ PublicTestContext TestContext {Get;Set; } [TestMethod] [DataSource ("Microsoft.VisualStudio.TestTools.DataSource.XML", @"| Datadirectory|\fixtures\add.xml","Row", dataaccessmethod.sequential)] Public voidTestMethod1 () {intA = Convert.ToInt32 (testcontext.datarow["a"]);intb = Convert.ToInt32 (testcontext.datarow["b"]);intexpected = Convert.ToInt32 (testcontext.datarow["expected"]);varresult =NewClass1 (). Add (A, b); Assert.AreEqual (expected, result); }}
The XML file used for the test:
<rows> <Rowa= "1"b= "2"expected= "3" /> <Rowa= "2"b= "-1"expected= "-1" /> <Rowa= "3"b= "0"expected= "3" /></rows>
There are a few things to note about testing:
- The test class must add a TestContext attribute;
- The copy to output directory of the XML file compilation attribute should be set to copy always or copy if newer;
- To test successfully on a remote server (such as a CI server), a Deployitem callout is required to indicate that the file is to be deployed to the test location along with the Assembly;
- The second parameter of DataSource is what DataDirectory refers to, and MSDN only takes the database as an example, without explaining the situation of xml/csv. From the results, it should be the location of the program output.
The results are available, but to be honest, such test code is far less elegant than nunit. I think Microsoft is not as complicated as the Visual Studio Test interface, so it's better to add some useful core functionality to MSTest. Of course, these are off-topic.
MSTest solutions that do not support parametric testing