{"id":3579,"date":"2019-11-28T20:00:25","date_gmt":"2019-11-28T18:00:25","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=3579"},"modified":"2019-11-28T15:24:41","modified_gmt":"2019-11-28T13:24:41","slug":"data-driven-unit-tests-for-managed-code","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/","title":{"rendered":"Data-driven unit tests for managed code"},"content":{"rendered":"<p>The Microsoft unit testing code for managed code allows to create test methods that are executed with data automatically fetched from an external data source. This is very helpful because we can extend the data sets without modifying the test code. An external data source can be an SQL database, a CSV file or Excel document, an XML document, or anything else for which a provider for .NET exists. In this article, I will show how you can define test data using all these types of source and execute unit testing methods with it.<\/p>\n<div class=\"important-icon-lite\">\nThis feature is available only for .NET Framework.<br \/>\nAt this time, data-driven unit testing from a data source is not supported for .NET Core.\n<\/div>\n<p><!-- more --><\/p>\n<div class=\"tip-lite\">\nDemo test project source:<br \/>\n<div class=\"wp-block-button\">\n<a  data-e-Disable-Page-Transition=\"true\" class=\"dlm-download-link dlm-download-default wp-block-button__link wp-element-button\" title=\"\" href=\"https:\/\/mariusbancila.ro\/blog\/download\/3628\/?tmstv=1792605429\" rel=\"nofollow\" id=\"download-link-3628\" data-redirect=\"false\" >\n\tDataDrivenTestsDemo.zip\t(<span class=\"dlm-download-count-value\">3999 downloads<\/span>\n\t)\n<\/a>\n<\/div>\n\n<\/div>\n<p><\/p>\n<p>To understand how this works, let us consider the following implementation of complex numbers. The arithmetic operators are overloaded for the <tt>Complex<\/tt> type so we can perform operations such as additions, subtractions, and multiplications. <\/p>\n<pre class=\"lang:c# decode:true \" >public struct Complex : IEquatable&lt;Complex&gt;\r\n{\r\n  public static readonly Complex Zero = new Complex(0, 0);\r\n  public static readonly Complex One = new Complex(1, 0);\r\n  public static readonly Complex ImaginaryOne = new Complex(0, 1);\r\n\r\n  public double Real { get; }\r\n  public double Imaginary { get; }\r\n\r\n  public Complex(double r, double i)\r\n  {\r\n     Real = r;\r\n     Imaginary = i;\r\n  }\r\n\r\n  public override string ToString() =&gt; $\"{Real}+{Imaginary}i\";\r\n\r\n  public bool Equals(Complex other)\r\n  {\r\n     return Real.Equals(other.Real) &amp;&amp; Imaginary.Equals(other.Imaginary);\r\n  }\r\n\r\n  public override bool Equals(object obj)\r\n  {\r\n     Complex other = (Complex)obj;\r\n     return Real.Equals(other.Real) &amp;&amp; Imaginary.Equals(other.Imaginary);\r\n  }\r\n\r\n  public override int GetHashCode()\r\n  {\r\n     return Real.GetHashCode() * 13 + Imaginary.GetHashCode();\r\n  }\r\n\r\n  public static Complex operator +(Complex a, Complex b) =&gt;\r\n     new Complex(a.Real + b.Real, a.Imaginary + b.Imaginary);\r\n  public static Complex operator -(Complex a, Complex b) =&gt;\r\n     new Complex(a.Real - b.Real, a.Imaginary - b.Imaginary);\r\n  public static Complex operator *(Complex a, Complex b) =&gt;\r\n     new Complex(a.Real * b.Real - a.Imaginary * b.Imaginary,\r\n                 a.Real * b.Imaginary + a.Imaginary * b.Real);\r\n}<\/pre>\n<p>For the purpose of this article, we will consider testing the multiplication operator.<\/p>\n<p>Typically, for testing the multiplication, you would write code as the following:<\/p>\n<pre class=\"lang:c# decode:true \" >[TestMethod]\r\npublic void Test_Multiply()\r\n{\r\n   Assert.AreEqual(new Complex(0, 0),\r\n                   new Complex(1, 2) * new Complex(0, 0));\r\n   Assert.AreEqual(new Complex(1, 2),\r\n                   new Complex(1, 2) * new Complex(1, 0));\r\n   Assert.AreEqual(new Complex(-2, 1),\r\n                   new Complex(1, 2) * new Complex(0, 1));\r\n   Assert.AreEqual(new Complex(-5, 10),\r\n                   new Complex(1, 2) * new Complex(3, 4));\r\n}<\/pre>\n<p>However, this has the drawback that data is hard coded and the more tests you want to write the more lines like these you need to add. Moreover, every time you want to add new or remove or change existing tests you need to modify the test method.<\/p>\n<p>The alternative for this is data-driven unit tests with the data fetched from an external data sources. When writing a data-driven unit test you have to do the following:<\/p>\n<ul>\n<li>Create the source of data for your tests.<\/li>\n<li>Add a public property called <tt>TestContext<\/tt> of the type <tt><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/microsoft.visualstudio.testtools.unittesting.testcontext\" rel=\"noopener noreferrer\" target=\"_blank\">TestContext<\/a><\/tt> to your test class. The framework will automatically set a reference to the context object that contains information for the unit test such as various directory paths (deployment dir, test dir, results dir, etc.), but also the current row of data in a data-driven unit test.<\/li>\n<li>Create a test method and mark it with the <tt><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/microsoft.visualstudio.testtools.unittesting.datasourceattribute\" rel=\"noopener noreferrer\" target=\"_blank\">DataSourceAttribute<\/a><\/tt> specifying a provider name, connection string, table name, and data access method. The data access method specifies how data is read from the source. The options are <tt>Sequential<\/tt> and <tt>Random<\/tt> (which should be self explainable), the latter being the default if none is specified.<\/li>\n<li>In the test method, use the <tt>TestContext<\/tt> object and its <tt><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/microsoft.visualstudio.testtools.unittesting.testcontext.datarow\" rel=\"noopener noreferrer\" target=\"_blank\">DataRow<\/a><\/tt> property to access the data for the current execution of the method. The test method is executed once for every row in the data source.<\/li>\n<\/ul>\n<p>Let us see how we can do this with various external sources of data.<\/p>\n<h2>SQL Server databases<\/h2>\n<p>Let us start by creating a database that we will call <em>ComplexTests<\/em>. In this database, we add a table called <em>Multiply<\/em> that has six columns, representing the real and imaginary parts of three complex numbers. The first two numbers are the ones that we multiply (<tt>ar + ai*i<\/tt> and <tt>br + bi*i<\/tt>) and the third one is the expected result (<tt>er + ei*i<\/tt>). We can put the data from the previous unit testing method in this table as follows:<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/sqldb.png\" alt=\"\" width=\"187\" height=\"121\" class=\"alignnone size-full wp-image-3583\" \/><br \/>\nHaving this, we can create the following data-driven test method:<\/p>\n<pre class=\"lang:c# decode:true \" >[TestClass]\r\npublic class ComplexUnitTest\r\n{\r\n   public TestContext TestContext { get; set; }\r\n\r\n   [DataTestMethod]\r\n   [DataSource(\"System.Data.SqlClient\",\r\n               \"Data Source=&lt;servername&gt;;Initial Catalog=ComplexTests;Integrated Security=True\",\r\n               \"Multiply\",\r\n               DataAccessMethod.Sequential)]\r\n   public void Test_Multiply_DataSource_SQL()\r\n   {\r\n      var ar = Convert.ToDouble(TestContext.DataRow[\"ar\"]);\r\n      var ai = Convert.ToDouble(TestContext.DataRow[\"ai\"]);\r\n      var br = Convert.ToDouble(TestContext.DataRow[\"br\"]);\r\n      var bi = Convert.ToDouble(TestContext.DataRow[\"bi\"]);\r\n      var er = Convert.ToDouble(TestContext.DataRow[\"er\"]);\r\n      var ei = Convert.ToDouble(TestContext.DataRow[\"ei\"]);\r\n\r\n      Assert.AreEqual(\r\n         new Complex(er, ei),\r\n         new Complex(ar, ai) * new Complex(br, bi));\r\n   }\r\n}<\/pre>\n<p>We have specified the following parameters for the <tt>DataSource<\/tt> attribute:<\/p>\n<table class=\"simplefull\">\n<tr bgcolor=\"#eeeeee\">\n<td><strong>Name<\/strong><\/td>\n<td><strong>Value<\/strong><\/td>\n<td><strong>Comments<\/strong><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>providerInvariantName<\/strong><\/tt><\/td>\n<td>&#8220;System.Data.SqlClient&#8221;<\/td>\n<td><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>connectionString<\/strong><\/tt><\/td>\n<td>&#8220;Data Source=&lt;servername&gt;;Initial Catalog=ComplexTests;Integrated Security=True&#8221;<\/td>\n<td><tt>&lt;servername&gt;<\/tt> is a placeholder for the actual name of the SQL Server instance<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>tableName<\/strong><\/tt><\/td>\n<td>&#8220;Multiply&#8221;<\/td>\n<td><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>dataAccessMethod<\/strong><\/tt><\/td>\n<td>DataAccessMethod.Sequential<\/td>\n<td>Sequential order of access.<\/td>\n<tr>\n<\/table>\n<p>The execution of this test method will produce the following output in the Test Explorer:<\/p>\n<pre class=\"lang:default decode:true \" > Test_Multiply_DataSource_SQL\r\n   Source: ComplexUnitTest.cs line 121\r\n\r\nTest has multiple result outcomes\r\n   5 Passed\r\n\r\nResults\r\n\r\n    1)  Test_Multiply_DataSource_SQL\r\n      Duration: 646 ms\r\n\r\n    2)  Test_Multiply_DataSource_SQL (Data Row 0)\r\n      Duration: 28 ms\r\n\r\n    3)  Test_Multiply_DataSource_SQL (Data Row 1)\r\n      Duration: &lt; 1 ms\r\n\r\n    4)  Test_Multiply_DataSource_SQL (Data Row 2)\r\n      Duration: &lt; 1 ms\r\n\r\n    5)  Test_Multiply_DataSource_SQL (Data Row 3)\r\n      Duration: &lt; 1 ms<\/pre>\n<p>If any test fails, it will be reported so, but the test method will be called again with data from the other rows in the source.<\/p>\n<pre class=\"lang:default decode:true \" > Test_Multiply_DataSource_SQL\r\n   Source: ComplexUnitTest.cs line 121\r\n\r\nTest has multiple result outcomes\r\n   3 Passed\r\n   2 Failed\r\n\r\nResults\r\n\r\n    1)  Test_Multiply_DataSource_SQL\r\n      Duration: 611 ms\r\n\r\n    2)  Test_Multiply_DataSource_SQL (Data Row 0)\r\n      Duration: 80 ms\r\n\r\n      Message: \r\n        Assert.AreEqual failed. Expected:&lt;0+1i&gt;. Actual:&lt;0+0i&gt;. \r\n      Stack Trace: \r\n        ComplexUnitTest.Test_Multiply_DataSource_SQL() line 130\r\n\r\n    3)  Test_Multiply_DataSource_SQL (Data Row 1)\r\n      Duration: &lt; 1 ms\r\n\r\n    4)  Test_Multiply_DataSource_SQL (Data Row 2)\r\n      Duration: &lt; 1 ms\r\n\r\n    5)  Test_Multiply_DataSource_SQL (Data Row 3)\r\n      Duration: &lt; 1 ms\r\n<\/pre>\n<h2>XML documents<\/h2>\n<p>We can put the test data in an XML document, that we will called <em>TestMultiplication.xml<\/em>, like the following:<\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;?xml version='1.0' encoding='UTF-8' ?&gt;\r\n&lt;data&gt;\r\n    &lt;row&gt;\r\n        &lt;ar&gt;1&lt;\/ar&gt;\r\n        &lt;ai&gt;2&lt;\/ai&gt;\r\n        &lt;br&gt;0&lt;\/br&gt;\r\n        &lt;bi&gt;0&lt;\/bi&gt;\r\n        &lt;er&gt;0&lt;\/er&gt;\r\n        &lt;ei&gt;0&lt;\/ei&gt;\r\n    &lt;\/row&gt;\r\n    &lt;row&gt;\r\n        &lt;ar&gt;1&lt;\/ar&gt;\r\n        &lt;ai&gt;2&lt;\/ai&gt;\r\n        &lt;br&gt;1&lt;\/br&gt;\r\n        &lt;bi&gt;0&lt;\/bi&gt;\r\n        &lt;er&gt;1&lt;\/er&gt;\r\n        &lt;ei&gt;2&lt;\/ei&gt;\r\n    &lt;\/row&gt;\r\n    &lt;row&gt;\r\n        &lt;ar&gt;1&lt;\/ar&gt;\r\n        &lt;ai&gt;2&lt;\/ai&gt;\r\n        &lt;br&gt;0&lt;\/br&gt;\r\n        &lt;bi&gt;1&lt;\/bi&gt;\r\n        &lt;er&gt;-2&lt;\/er&gt;\r\n        &lt;ei&gt;1&lt;\/ei&gt;\r\n    &lt;\/row&gt;\r\n    &lt;row&gt;\r\n        &lt;ar&gt;1&lt;\/ar&gt;\r\n        &lt;ai&gt;2&lt;\/ai&gt;\r\n        &lt;br&gt;3&lt;\/br&gt;\r\n        &lt;bi&gt;4&lt;\/bi&gt;\r\n        &lt;er&gt;-5&lt;\/er&gt;\r\n        &lt;ei&gt;10&lt;\/ei&gt;\r\n    &lt;\/row&gt;\r\n&lt;\/data&gt;<\/pre>\n<p>A test method that is executed with data from this document should look as following:<\/p>\n<pre class=\"lang:c# decode:true \" >[DataTestMethod]\r\n[DataSource(\"Microsoft.VisualStudio.TestTools.DataSource.XML\",\r\n            @\"|DataDirectory|\\TestMultiplication.xml\",\r\n            \"row\",\r\n            DataAccessMethod.Sequential)]\r\npublic void Test_Multiply_DataSource_XML()\r\n{\r\n   var ar = Convert.ToDouble(TestContext.DataRow[\"ar\"]);\r\n   var ai = Convert.ToDouble(TestContext.DataRow[\"ai\"]);\r\n   var br = Convert.ToDouble(TestContext.DataRow[\"br\"]);\r\n   var bi = Convert.ToDouble(TestContext.DataRow[\"bi\"]);\r\n   var er = Convert.ToDouble(TestContext.DataRow[\"er\"]);\r\n   var ei = Convert.ToDouble(TestContext.DataRow[\"ei\"]);\r\n\r\n   Assert.AreEqual(\r\n      new Complex(er, ei),\r\n      new Complex(ar, ai) * new Complex(br, bi));\r\n}<\/pre>\n<p>We have specified the following parameters for the <tt>DataSource<\/tt> attribute:<\/p>\n<table class=\"simplefull\">\n<tr bgcolor=\"#eeeeee\">\n<td><strong>Name<\/strong><\/td>\n<td><strong>Value<\/strong><\/td>\n<td><strong>Comments<\/strong><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>providerInvariantName<\/strong><\/tt><\/td>\n<td>&#8220;Microsoft.VisualStudio.TestTools.DataSource.XML&#8221;<\/td>\n<td><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>connectionString<\/strong><\/tt><\/td>\n<td>@&#8221;|DataDirectory|\\TestMultiplication.xml&#8221;<\/td>\n<td><em>TestMultiplication.xml<\/em> is the name of the XML document, and <tt>|DataDirectory|<\/tt> is a placeholder for the data directory (see <a href=\"https:\/\/support.microsoft.com\/en-us\/help\/920700\/an-introduction-to-sql-server-2005-compact-edition\" rel=\"noopener noreferrer\" target=\"_blank\">this for details<\/a>). The <em>TestMultiplication.xml<\/em> file is located directly in the data directory, but can be in other location relative to it. The use of the substitution string <tt>|DataDirectory|<\/tt> avoids hard-coding paths. If you do not set a value for it, the data directory is the application directory. You can change that by calling <tt>AppDomain.CurrentDomain.SetData(\"DataDirectory\", path)<\/tt>.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>tableName<\/strong><\/tt><\/td>\n<td>&#8220;row&#8221;<\/td>\n<td>The name of the XML node that contains the data for a row.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>dataAccessMethod<\/strong><\/tt><\/td>\n<td>DataAccessMethod.Sequential<\/td>\n<td>Sequential order of access.<\/td>\n<tr>\n<\/table>\n<p>If you compare the two test methods we wrote so far you will notice that the only difference between them is the parameters supplied to the <tt>DataSource<\/tt> attribute.<\/p>\n<h2>CSV files<\/h2>\n<p>Using an XML document can be cumbersome because of all the tags you need to write. Having the data in a comma-separated values file is simpler, at least in the case of the kind of tests we are doing. The following is the content of a CSV file called <em>TestMultiplication.csv<\/em>:<\/p>\n<pre class=\"lang:default decode:true \" >ar,ai,br,bi,er,ei\r\n1, 2, 0, 0, 0, 0\r\n1, 2, 1, 0, 1, 2\r\n1, 2, 0, 1, -2, 1\r\n1, 2, 3, 4, -5, 10<\/pre>\n<p>The first line is the names of the columns. The others are rows of data, the same we had in the previous examples. This time, the test method will be as following:<\/p>\n<pre class=\"lang:c# decode:true \" >[DataTestMethod]\r\n[DataSource(\"Microsoft.VisualStudio.TestTools.DataSource.CSV\",\r\n            @\"|DataDirectory|\\TestMultiplication.csv\",\r\n            \"TestMultiplication#csv\",\r\n            DataAccessMethod.Sequential)]\r\npublic void Test_Multiply_DataSource_CSV()\r\n{\r\n   var ar = Convert.ToDouble(TestContext.DataRow[\"ar\"]);\r\n   var ai = Convert.ToDouble(TestContext.DataRow[\"ai\"]);\r\n   var br = Convert.ToDouble(TestContext.DataRow[\"br\"]);\r\n   var bi = Convert.ToDouble(TestContext.DataRow[\"bi\"]);\r\n   var er = Convert.ToDouble(TestContext.DataRow[\"er\"]);\r\n   var ei = Convert.ToDouble(TestContext.DataRow[\"ei\"]);\r\n\r\n   Assert.AreEqual(\r\n      new Complex(er, ei),\r\n      new Complex(ar, ai) * new Complex(br, bi));\r\n}<\/pre>\n<p>Again, the only difference is the parameters of the <tt>DataSource<\/tt> attribute, which are detailed below:<\/p>\n<table class=\"simplefull\">\n<tr bgcolor=\"#eeeeee\">\n<td><strong>Name<\/strong><\/td>\n<td><strong>Value<\/strong><\/td>\n<td><strong>Comments<\/strong><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>providerInvariantName<\/strong><\/tt><\/td>\n<td>&#8220;Microsoft.VisualStudio.TestTools.DataSource.CSV&#8221;<\/td>\n<td><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>connectionString<\/strong><\/tt><\/td>\n<td>@&#8221;|DataDirectory|\\TestMultiplication.csv&#8221;<\/td>\n<td>The <em>TestMultiplication.csv<\/em> file is located in the data directory.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>tableName<\/strong><\/tt><\/td>\n<td>&#8220;TestMultiplication#csv&#8221;<\/td>\n<td>The name of the table is the name of the file without extension followed by <tt>#csv<\/tt>.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>dataAccessMethod<\/strong><\/tt><\/td>\n<td>DataAccessMethod.Sequential<\/td>\n<td>Sequential order of access.<\/td>\n<tr>\n<\/table>\n<h2>Excel documents<\/h2>\n<p>An alternative to a CSV file is an Excel document. The advantage of an Excel file is that you can have multiple sets of different data in different sheets. For this article, however, we&#8217;ll only have one sheet, called <em>Multiply<\/em>, in a document called <em>TestMultiplication.xlsx<\/em>.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/exceldb.png\" alt=\"\" width=\"409\" height=\"176\" class=\"alignnone size-full wp-image-3597\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/exceldb.png 409w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/exceldb-300x129.png 300w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><br \/>\nThe test method will look as follows:<\/p>\n<pre class=\"lang:c# decode:true \" >[DataTestMethod]\r\n[DataSource(\"System.Data.Odbc\",\r\n            @\"Dsn=Excel Files;DriverID=790;dbq=|DataDirectory|\\TestMultiplication.xlsx\",\r\n            \"Multiply$\",\r\n            DataAccessMethod.Sequential)]\r\npublic void Test_Multiply_DataSource_Excel()\r\n{\r\n   var ar = Convert.ToDouble(TestContext.DataRow[0]);\r\n   var ai = Convert.ToDouble(TestContext.DataRow[1]);\r\n   var br = Convert.ToDouble(TestContext.DataRow[2]);\r\n   var bi = Convert.ToDouble(TestContext.DataRow[3]);\r\n   var er = Convert.ToDouble(TestContext.DataRow[4]);\r\n   var ei = Convert.ToDouble(TestContext.DataRow[5]);\r\n\r\n   Assert.AreEqual(\r\n      new Complex(er, ei),\r\n      new Complex(ar, ai) * new Complex(br, bi));\r\n}<\/pre>\n<p>The method is slightly changed this time, because columns in the data row are accessed by their index. Excel does not support renaming columns, so we cannot give them names like ar, ai, etc. as we did in the previous examples. The parameters for the <tt>DataSource<\/tt> attribute are the following:<\/p>\n<table class=\"simplefull\">\n<tr bgcolor=\"#eeeeee\">\n<td><strong>Name<\/strong><\/td>\n<td><strong>Value<\/strong><\/td>\n<td><strong>Comments<\/strong><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>providerInvariantName<\/strong><\/tt><\/td>\n<td>&#8220;System.Data.Odbc&#8221;<\/td>\n<td><\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>connectionString<\/strong><\/tt><\/td>\n<td>@&#8221;Dsn=Excel Files;DriverID=790;dbq=|DataDirectory|\\TestMultiplication.xlsx&#8221;<\/td>\n<td>The connection string to the Excel file. Properties such as <tt>DriverID=790<\/tt> or <tt>Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)}<\/tt> are optional.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>tableName<\/strong><\/tt><\/td>\n<td>&#8220;Multiply$&#8221;<\/td>\n<td>The name of the sheet following by the symbol $.<\/td>\n<tr>\n<tr>\n<td bgcolor=\"#eeeeee\"><tt><strong>dataAccessMethod<\/strong><\/tt><\/td>\n<td>DataAccessMethod.Sequential<\/td>\n<td>Sequential order of access.<\/td>\n<tr>\n<\/table>\n<h3>Troubleshooting<\/h3>\n<p>When your data source is an Excel document, make sure you have the driver that provides access to Excel documents properly installed. If the test fails with the following error message then either the path to the document is wrong or the driver is not installed.<\/p>\n<blockquote><p>The unit test adapter failed to connect to the data source or to read the data. For more information on troubleshooting this error, see &#8220;Troubleshooting Data-Driven Unit Tests&#8221; (http:\/\/go.microsoft.com\/fwlink\/?LinkId=62412) in the MSDN Library. Error details: ERROR [42S02] [Microsoft][ODBC Excel Driver] The Microsoft Access database engine could not find the object &#8216;Multiply$&#8217;. Make sure the object exists and that you spell its name and the path name correctly. If &#8216;Multiply$&#8217; is not a local object, check your network connection or contact the server administrator.&#8217;<\/p><\/blockquote>\n<p>In order to read data from an Excel document you need to have the <em>Microsoft Access Database Engine<\/em> installed on your machine. You can check that you have it from Control Panel > Programs > Programs and Features > Uninstall or change Program.<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/controlpanel.png\" alt=\"\" width=\"713\" height=\"343\" class=\"alignnone size-full wp-image-3610\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/controlpanel.png 713w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/controlpanel-300x144.png 300w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/controlpanel-700x337.png 700w\" sizes=\"auto, (max-width: 713px) 100vw, 713px\" \/><br \/>\nIf you don&#8217;t have it then you can download it from here: <a href=\"https:\/\/www.microsoft.com\/en-us\/download\/details.aspx?id=54920\" rel=\"noopener noreferrer\" target=\"_blank\">Microsoft Access Database Engine 2016 Redistributable<\/a>. This is available both as 32- and 64-bit.<br \/>\nHowever, if you try to install it, you might run into the following errors:<br \/>\n<img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/officeerror.png\" alt=\"\" width=\"402\" height=\"446\" class=\"alignnone size-full wp-image-3611\" srcset=\"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/officeerror.png 402w, https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/officeerror-270x300.png 270w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><br \/>\nThe reason for this is that this installation is conflicting with existing Office components. Office Click-to-Run Extensibility is a key component of the Office suite and cannot be uninstalled. Therefore, in order to bypass this error, you need to do the following:<\/p>\n<ul>\n<li>Open a comment prompt elevated as administrator.<\/li>\n<li>Run the redistributable executable with the <tt>\/quiet<\/tt> option:\n<pre class=\"lang:default decode:true \" >AccessDatabaseEngine.exe \/quiet<\/pre>\n<\/li>\n<li>Verify in Control Panel that the engine has been properly installed.<\/li>\n<\/ul>\n<h2>Defining data sources in App.Config<\/h2>\n<p>Rather than specifying the connection strings and the other data source parameters in code, we can actually put them in the application configuration file. To do so, you need to add a custom configuration section as follows:<\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;configuration&gt;\r\n   &lt;configSections&gt;\r\n      &lt;section name=\"microsoft.visualstudio.testtools\"\r\n               type=\"Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions\"\/&gt;\r\n   &lt;\/configSections&gt;\r\n   &lt;connectionStrings&gt;\r\n   &lt;\/connectionStrings&gt;\r\n   &lt;microsoft.visualstudio.testtools&gt;\r\n      &lt;dataSources&gt;\r\n      &lt;\/dataSources&gt;\r\n   &lt;\/microsoft.visualstudio.testtools&gt;\r\n&lt;\/configuration&gt;<\/pre>\n<p>Then, you need to add connection strings and data sources. For a connection string you must specify a name, the actual connection string, and a provider name. For a data source, you must specify a name, the name of the connection string defined in the other section that this source is using, a table name, and the data access method. For the four data sources used for the data test methods shown earlier, we can define the following data sources in <em>App.config<\/em>:<\/p>\n<pre class=\"lang:xhtml decode:true \" >&lt;?xml version=\"1.0\" encoding=\"utf-8\" ?&gt;\r\n&lt;configuration&gt;\r\n   &lt;configSections&gt;\r\n      &lt;section name=\"microsoft.visualstudio.testtools\"\r\n               type=\"Microsoft.VisualStudio.TestTools.UnitTesting.TestConfigurationSection, Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions\"\/&gt;\r\n   &lt;\/configSections&gt;\r\n   &lt;connectionStrings&gt;\r\n      &lt;add name=\"SQLConn\" \r\n           connectionString=\"Data Source=&lt;servername&gt;;Initial Catalog=ComplexTests;Integrated Security=True\" \r\n           providerName=\"System.Data.SqlClient\" \/&gt;\r\n      &lt;add name=\"XMLConn\" \r\n           connectionString=\"|DataDirectory|\\TestMultiplication.xml\" \r\n           providerName=\"Microsoft.VisualStudio.TestTools.DataSource.XML\" \/&gt;\r\n      &lt;add name=\"CSVConn\" \r\n           connectionString=\"|DataDirectory|\\TestMultiplication.csv\" \r\n           providerName=\"Microsoft.VisualStudio.TestTools.DataSource.CSV\" \/&gt;\r\n      &lt;add name=\"EXLConn\" \r\n           connectionString=\"Dsn=Excel Files;DriverID=790;dbq=|DataDirectory|\\TestMultiplication.xlsx\" \r\n           providerName=\"System.Data.Odbc\" \/&gt;\r\n   &lt;\/connectionStrings&gt;\r\n   &lt;microsoft.visualstudio.testtools&gt;\r\n      &lt;dataSources&gt;\r\n         &lt;add name=\"SQLDataSource\" \r\n              connectionString=\"SQLConn\" \r\n              dataTableName=\"Multiply\" \r\n              dataAccessMethod=\"Sequential\"\/&gt;\r\n         &lt;add name=\"XMLDataSource\" \r\n              connectionString=\"XMLConn\" \r\n              dataTableName=\"row\" \r\n              dataAccessMethod=\"Sequential\"\/&gt;\r\n         &lt;add name=\"CSVDataSource\"\r\n              connectionString=\"CSVConn\"\r\n              dataTableName=\"TestMultiplication#csv\"\r\n              dataAccessMethod=\"Sequential\"\/&gt;\r\n         &lt;add name=\"EXLDataSource\"\r\n              connectionString=\"EXLConn\"\r\n              dataTableName=\"Multiply$\"\r\n              dataAccessMethod=\"Sequential\"\/&gt;\r\n      &lt;\/dataSources&gt;\r\n   &lt;\/microsoft.visualstudio.testtools&gt;\r\n&lt;\/configuration&gt;<\/pre>\n<p>Having these data sources defined like this, we can pass their names to the constructor of the <tt>DataSource<\/tt> attribute. The implementation of the methods is the same, therefore, for simplicity, it&#8217;s skipped it in the next listing:<\/p>\n<pre class=\"lang:c# decode:true \" >[DataTestMethod]\r\n[DataSource(\"SQLDataSource\")]\r\npublic void Test_Multiply_DataSource_SQL()\r\n{\r\n   \/\/ ...\r\n}\r\n\r\n[DataTestMethod]\r\n[DataSource(\"XMLDataSource\")]\r\npublic void Test_Multiply_DataSource_XML()\r\n{\r\n   \/\/ ...\r\n}\r\n\r\n[DataTestMethod]\r\n[DataSource(\"CSVDataSource\")]\r\npublic void Test_Multiply_DataSource_CSV()\r\n{\r\n   \/\/ ...\r\n}\r\n\r\n[DataTestMethod]\r\n[DataSource(\"EXLDataSource\")]\r\npublic void Test_Multiply_DataSource_Excel()\r\n{\r\n   \/\/ ...\r\n}<\/pre>\n<h2>References<\/h2>\n<p>For further readings on the topic of data-driven unit testing with the Microsoft unit testing framework see:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/test\/how-to-create-a-data-driven-unit-test?view=vs-2019\" target=\"_blank\" rel=\"noopener noreferrer\">How to: Create a data-driven unit test<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/test\/creating-a-data-driven-coded-ui-test?view=vs-2019\" target=\"_blank\" rel=\"noopener noreferrer\">Create a data-driven coded UI test<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/visualstudio\/test\/walkthrough-using-a-configuration-file-to-define-a-data-source?view=vs-2019\" target=\"_blank\" rel=\"noopener noreferrer\">Walkthrough: Using a configuration file to define a data source<\/a><\/li>\n<li><a href=\"https:\/\/www.codeproject.com\/Tips\/629895\/Data-Driven-Testing-by-Excel-Named-Region\" target=\"_blank\" rel=\"noopener noreferrer\">Data Driven Testing by Excel Named Region<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/ObjectivityLtd\/Ocaramba\/wiki\/MsTest-DataDriven-tests-from-Xml-and-CSV-files\" target=\"_blank\" rel=\"noopener noreferrer\">MsTest DataDriven tests from Xml and CSV files<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>The Microsoft unit testing code for managed code allows to create test methods that are executed with data automatically fetched from an external data source. This is very helpful because we can extend the data sets without modifying the test code. An external data source can be an SQL database, a CSV file or Excel document, an XML document, or anything else for which a provider for .NET exists. In this article, I will show how you can define test data using all these types of source and execute unit testing methods with it.<\/p>\n<div class=\"important-icon-lite\">\nThis feature is available only for .NET Framework.<br \/>\nAt this time, data-driven unit testing from a data source is not supported for .NET Core.\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[13,11,10],"tags":[454,451,506,55],"class_list":["post-3579","post","type-post","status-publish","format-standard","hentry","category-net","category-csharp","category-visual-studio","tag-net","tag-c","tag-testing","tag-visualstudio"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\"c#,.net,visualstudio,testing,c++\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Data-driven unit tests for managed code\" \/>\n\t\t<meta property=\"og:description\" content=\"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-11-28T18:00:25+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-11-28T13:24:41+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Data-driven unit tests for managed code\" \/>\n\t\t<meta name=\"twitter:description\" content=\"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#article\",\"name\":\"Data-driven unit tests for managed code\",\"headline\":\"Data-driven unit tests for managed code\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/11\\\/sqldb.png\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#articleImage\",\"width\":187,\"height\":121},\"datePublished\":\"2019-11-28T20:00:25+02:00\",\"dateModified\":\"2019-11-28T15:24:41+02:00\",\"inLanguage\":\"en-US\",\"commentCount\":1,\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#webpage\"},\"articleSection\":\".NET, C#, Visual Studio, .NET, C++, testing, VisualStudio\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"name\":\".NET\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"position\":4,\"name\":\".NET\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/csharp\\\/#listItem\",\"name\":\"C#\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/csharp\\\/#listItem\",\"position\":5,\"name\":\"C#\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/csharp\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#listItem\",\"name\":\"Data-driven unit tests for managed code\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/#listItem\",\"name\":\".NET\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#listItem\",\"position\":6,\"name\":\"Data-driven unit tests for managed code\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/net\\\/csharp\\\/#listItem\",\"name\":\"C#\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/\",\"name\":\"Data-driven unit tests for managed code\",\"description\":\"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2019\\\/11\\\/28\\\/data-driven-unit-tests-for-managed-code\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2019-11-28T20:00:25+02:00\",\"dateModified\":\"2019-11-28T15:24:41+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Data-driven unit tests for managed code","description":"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/","robots":"max-image-preview:large","keywords":"c#,.net,visualstudio,testing,c++","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#article","name":"Data-driven unit tests for managed code","headline":"Data-driven unit tests for managed code","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/mariusbancila.ro\/blog\/wp-content\/uploads\/2019\/11\/sqldb.png","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#articleImage","width":187,"height":121},"datePublished":"2019-11-28T20:00:25+02:00","dateModified":"2019-11-28T15:24:41+02:00","inLanguage":"en-US","commentCount":1,"mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#webpage"},"articleSection":".NET, C#, Visual Studio, .NET, C++, testing, VisualStudio"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","name":".NET"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","position":4,"name":".NET","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/csharp\/#listItem","name":"C#"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/csharp\/#listItem","position":5,"name":"C#","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/csharp\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#listItem","name":"Data-driven unit tests for managed code"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/#listItem","name":".NET"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#listItem","position":6,"name":"Data-driven unit tests for managed code","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/csharp\/#listItem","name":"C#"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/","name":"Data-driven unit tests for managed code","description":"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2019-11-28T20:00:25+02:00","dateModified":"2019-11-28T15:24:41+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Data-driven unit tests for managed code","og:description":"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.","og:url":"https:\/\/mariusbancila.ro\/blog\/2019\/11\/28\/data-driven-unit-tests-for-managed-code\/","article:published_time":"2019-11-28T18:00:25+00:00","article:modified_time":"2019-11-28T13:24:41+00:00","twitter:card":"summary","twitter:title":"Data-driven unit tests for managed code","twitter:description":"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs."},"aioseo_meta_data":{"post_id":"3579","title":"Data-driven unit tests for managed code","description":"Learn how to write data-driven unit tests using the Microsoft unit testing framework and the following data sources: SQL Server database, XML, CSV, Excel docs.","keywords":[{"label":"C#","value":"C#"},{"label":".NET","value":".NET"},{"label":"VisualStudio","value":"VisualStudio"},{"label":"Testing","value":"Testing"}],"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:03:35","updated":"2025-12-12 07:53:21","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":1,"uagb_excerpt":"The Microsoft unit testing code for managed code allows to create test methods that are executed with data automatically fetched from an external data source. This is very helpful because we can extend the data sets without modifying the test code. An external data source can be an SQL database, a CSV file or Excel&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/\" class=\"advgb-post-tax-term\">.NET<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/csharp\/\" class=\"advgb-post-tax-term\">C#<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">Visual Studio<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">.NET<\/span>","<span class=\"advgb-post-tax-term\">C#<\/span>","<span class=\"advgb-post-tax-term\">Visual Studio<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">.NET<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">testing<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">VisualStudio<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">.NET<\/span>","<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">testing<\/span>","<span class=\"advgb-post-tax-term\">VisualStudio<\/span>"]}},"comment_count":"1","relative_dates":{"created":"Posted 7 years ago","modified":"Updated 7 years ago"},"absolute_dates":{"created":"Posted on November 28, 2019","modified":"Updated on November 28, 2019"},"absolute_dates_time":{"created":"Posted on November 28, 2019 8:00 pm","modified":"Updated on November 28, 2019 3:24 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-VJ","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3579","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=3579"}],"version-history":[{"count":45,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3579\/revisions"}],"predecessor-version":[{"id":3631,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3579\/revisions\/3631"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=3579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=3579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=3579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}