Share via


Using TestContext in Unit Tests

Most people don't know about the TestContext object, as it is not one regularly used. However, it can be very handy.

Data-Driven Unit Testing

The TestContext object's primary purpose IMO is for linking up a unit test with data rows from a data source. If you haven't checked out the data-driven unit test feature, take a look here. When it comes time to modify your code to pick up the data rows, you'll use the TestContext object as documented here.

It is important to create a private instance of the TestContext object in your TestClass. You'll also need to create a public property on that field, so the test harness can initialize it for you. If you create unit tests by way of Code Generation, then this object will be added for you automatically. Otherwise you will need to add it manually. That will look something like this (C#):
private TestContext m_testContext; public TestContext TestContext { get { return m_testContext; } set { m_testContext = value; } }

When you are ready to write your code, refer to the data through the TestContext object like (C#):
string firstParameter = m_testContext.DataRow[0].ToString(); string secondParameter = m_testContext.DataRow["SecondColumn"].ToString();
Note that you can refer to the column by index (zero-based) or by name.

Finding Files

Another great use for this object is determining where your tests and files have been deployed to. The TestContext.TestDeploymentDir property contains this information. There is also TestContext.TestLogsDir, TestContext.TestDir, and even TestContext.TestName. To see what these equate to, add a new unit test and add the following lines:
Console.WriteLine("TestDir: {0}", m_testContext.TestDir); Console.WriteLine("TestDeploymentDir: {0}", m_testContext.TestDeploymentDir); Console.WriteLine("TestLogsDir: {0}", m_testContext.TestLogsDir); Console.WriteLine("TestName: {0}", m_testContext.TestName);

Look at the test result details for that test to see the values.

Comments

  • Anonymous
    August 26, 2012
    This is terrible. It tells me nothing other than TestContext exists and I can do magic stuff with it.

  • Anonymous
    October 10, 2012
    I agree with Brady.  This article at least goes a little further - weblogs.asp.net/.../more-on-unit-testing-testcontext.aspx

  • Anonymous
    November 14, 2012
    Whats missing here is that you need to store a static member instance of the TestContext object that you get from a method marked with either AssemblyInitialize or CLassInitialize method like this; private TestContext _context; [AssemblyInitialize] public static void Initialize(TestContext context) {        _context = context; } [TestMethod, DataSource(etc etc)] public void some_test() {       var someValue = Convert.ToString(_context.DataRow["someVarcharColumn]); } Its amazing that practically every official MS example fails to explain this and hence none of them work. The other problem you run into is that in terms of Data Driven tests, only test classes with a methodmarked with AssemblyInitialize will be able to retrieve that data through the DataRow property. When you use ClassInitialize DatRow is always null. So as it stands you can only bind data to one test class in any test assembly.

  • Anonymous
    February 18, 2014
    phlaz, the reason they don't include that is because you are WRONG.  It is not necessary.  If you define the TestContext property as demonstrated in this post, it will work.   NO additional code is necessary.

  • Anonymous
    February 18, 2014
    The comment has been removed

  • Anonymous
    September 25, 2014
    Hi Darryl, You're wrong. The example didn't work as written. Without the method decorated with AssemblyInitialize, the TestContext property is never set. Wrong wrong wrong.

  • Anonymous
    November 13, 2014
    The comment has been removed

  • Anonymous
    January 14, 2016
    Make sure the "TestContext" property that you create is "Public", then you'll find that it will work. The same goes for the TestInitialize and TestCleanup methods.