Add Result File with TestContext

This is the last post of the series regarding TestContext. The other posts of this series include:

On Unit Testing:

Usage of TestContext:

In this post, we discuss another member of TestContext called AddResultFile, which is defined as follows.

void AddResultFile(string filename)

Through TestContext.AddResulFile, additional files can be added with the test results. This additional files will be stored in the unique folder created for current test run, as mentioned. This might be useful in some cases, for example, if we are validating our objects with some external resource, like schema— we can store the schema with our test result so that we can validate our test result later on after test run.

Advertisement

TestContext in Data Driven Unit Tests

TestContext consolidates the support of Data Driven Unit Tests via mstest by allowing access to the datasource (e.g., database table), associated with the present code under test. This post describes this very feature of TestContext.

We illustrate this feature with a simple and contrived example (devised only for illustrative purpose), which verify CreateUser API of the application under test. So, we first create a datasource, which is a table that stores contact information.

UserContact Table Definition

After creating a table, we add few users data in the table: UserContact, as shown below.

Data in UserContact Table

Next, we show how TestContext enables us to access row stored in the UserContact table in the following unit test.

[DataSource("System.Data.SqlClient", "[path to MDF]";
Integrated Security=True;User Instance=True", "UserContact",
DataAccessMethod.Sequential), TestMethod()]
public void ShouldCreateUsers(){
string userLoginName = (TestContext.DataRow["LoginName"].ToString());
string userFirstName = (TestContext.DataRow["FirstName"].ToString());
string userLastName = (TestContext.DataRow["LastName"].ToString());
string userEmailAddress = (TestContext.DataRow["EmailAddress"].ToString());
string userDepartment = (TestContext.DataRow["Department"].ToString());
TestContext.WriteLine("Creating user - Login Name :{0} Name : {1} {2} EmailAddress : {3} ", userLoginName, userFirstName,userLastName, userEmailAddress);
bool successful = UserManger.CreateUser(userLoginName, userFirstName, userLastName, userEmailAddress, userDepartment);
Assert.IsTrue(successful);
}
view raw gistfile1.cs hosted with ❤ by GitHub

In this example, we can see that in (line 5 – 10 ), TestContext is providing us access to the current DataRow for which the unit test is getting executed. During execution, we can see the output of TestContext.Writeline(line 12), and the result of the unit test for each DataRow.

To sum up, in this post, we discussed the usage of TestContext in the context of Data Driven Unit Tests. It effectively allows us to access all the DataRows in the test Tables and hence, plays an instrumental role in this context. Thanks.

Related Posts

Other posts of the series are outlined below.

On Unit Testing:

Usage of TestContext:

Output additional information in Test Reports with TestContext

TestContext.WriteLine allows additional information to be added in test reports (.trx files) in a flexible manner. This features is particularly useful to report contextual information such as details regarding Test Environments, formal parameters and so on.

[TestMethod]
public void ShouldCreateUser(){
// ... Unit Test Codes....
}

[TestCleanup]
public void TestCleanup(){
    TestContext.WriteLine("{0} : {1}", TestContext.TestName ,TestContext.CurrentTestOutcome);
}

As such, above code-snippet shows the value CurrentTestOutcome after running a test–

Testreport

Hope it helps. Thanks.

Related Posts

Other posts in this series includes:

On Unit Testing:

Usage of TestContext:

Getting Directory of Current Context with TestContext

The current test run creates a unique directory for running tests and storing the generated reports (.trx) files.

TRX files

In effect, additional inputs and outputs (especially, in case of data driven unit tests) can be persisted in these unique directories during test runs. In addition, unit testing process has complete access in these directories. So, it would be consistent while running the tests in any machines (e.g., in build machines or in local development environments).

Using TestContext, we can get the path of the directory related to the current test run as follows.

string testDirectory = TestContext.TestDir;

We can get the deployment directory and the directory that contains logs as follows.

string deploymentDirectory = TestContext.TestDeploymentDir;
string logDirectory = TestContext.TestLogsDir;

To sum up, this post has described how we can get/set several important properties from TestContext. In the next post, we show how we can use it for performance measurement.

Related Posts

Other posts in this series includes:

On Unit Testing:

Usage of TestContext:

More on Unit Testing: TestContext

From empirical evidence, we know that improving code coverage by verifying all the boundary conditions, and ensuring quality of code-base significantly enhances maintainability and comprehensibility of complex software systems. Therefore, writing effective unit and integration tests has become one of the integral part in software development life cycle. In fact, development methodology such as TDD has been embraced rapidly due to these realized benefits.

In today’s post, we talk more about TestContext of mstest. In particular, we focus on its usage in devising effective unit tests. Before moving forward, we would like to outline the previous posts of the series regarding Unit Testing.

What is TestContext?

TestContext is an abstract class of Microsoft.VisualStudio.TestTools.UnitTesting namespace. It exposed several properties related to the current context (i.e., current test run). In addition, it provides following supports:

  • Get/set context-sensitive properties and instances, For instance,
    • During Asp.net unit tests, it stores server’s URL, and Page object.
    • For data driven unit tests, it provides access to the data rows.
  • Mechanism to measure performance of unit tests.

Following is the class definition of the TestContext class.

public abstract class TestContext
{
public const string AspNetDevelopmentServerPrefix = "AspNetDevelopmentServer.";
protected TestContext();
public virtual UnitTestOutcome CurrentTestOutcome { get; }
public abstract DbConnection DataConnection { get; }
public abstract DataRow DataRow { get; }
public abstract IDictionary Properties { get; }
public virtual System.Web.UI.Page RequestedPage { get; }
public virtual string TestDeploymentDir { get; }
public virtual string TestDir { get; }
public virtual string TestLogsDir { get; }
public virtual string TestName { get; }
public abstract void AddResultFile(string fileName);
public abstract void BeginTimer(string timerName);
public abstract void EndTimer(string timerName);
public abstract void WriteLine(string format, params object[] args);
}
view raw TestContext.cs hosted with ❤ by GitHub

How can we initialize TestContext?

To start using TestContext, we need to add a property in our unit test class, e.g., UserManagerTests, as illustrated below.

UnitTest class with a TestContext

As we run a unit test defined in UserManagerTests, we automatically get an instance of TestContext with the relevant properties configured according to the current context. Thus, we do not require to explicitly instantiate it. Using debug mode, we can verify that the instance of TestContext is an instance of UnitTestAdapterContext, which is, in fact, derived from TestContext abstract class.

TestContext

In addition, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter.dll assembly contains UnitTestAdapterContext class, which is located in the directory of private assemblies installed in <vs installation directory>\common7\IDE\PrivateAssemblies.

Note that the property TestContext is actually initialized after ClassInitialize and before TestInitialize gets invoked.

In this post, we discuss how we can initialize TestContext in a test class. As a continuation of this discussion, we outline several use-cases of TestContext in the following posts.

Conclusion

To sum up, in this series, we introduce TestContext and has discussed how we can utilize it in different scenarios to write effective unit and integration tests. We hope that it would help to devise more effective and maintainable unit tests. Lastly, we emphasize on designing test cases thoroughly, and mapping them essentially into unit and integration tests accordingly, because only "harnessing the power that is provided by the tool and utilizing it effectively and every possible way" could bring desirable result. We highly appreciate any comments or any suggestion regarding this series. Thanks.


Revisions

[R-1: 04-04-2013] Porting this blog-post from its weblogs.asp.net page.