Overview of VSTS
Visual Studio Team System (VSTS) comes along with inbuilt testing tools, which provide more effective and efficient ways to write test scripts for both Windows and web applications.
VSTS is for management of large projects. In order to use the system, we have to set up a server and install it and maintain access to all users, and if they are in remote locations, we need to open the firewall to access it.
VSTS also allows a developer to aggregate multiple tests which have already been written, so that they can be executed by automated test agents to simulate up to a thousand users for load testing. Several agents can be run concurrently to increase the load in multiples of about a thousand. This whole process allows a team to reuse the work that was initiated for the various kinds of tests.
This also makes it easier for the developers themselves to execute a load test based on the Unit Tests of the individual code modules, so that they can identify problems at an earlier stage, saving time, and learning how to write better code.
Using ASP.NET Unit Tests, we can test classes and methods that are part of an ASP.NET website. This is often very similar to testing anything else, since we can use code generation on classes that are within the App_Code directory for the site. Unfortunately, it's not possible to generate tests for the page class itself (the one defined in the .aspx and .aspx.cs files for the page), due to differences in how Visual Studio handles these files:
VSTS supports five key types of tests:
- Unit Testing, in which we call a class and verify that it is behaving as expected.
- Manual testing.
- Generic testing that uses an existing test application that run as part of the biggest test.
- Web testing to ensure the HTML apps function correctly.
- Load testing to ensure the app is scalable.
Sample
using Microsoft.VisualStudio.QualityTools.UnitTesting.Framework;
using System;
namespace Test
{
[TestClass()]
public class LogonInfoTest
{
private TestContext testContextInstance;
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestInitialize()]
public void Initialize()
{
}
[TestCleanup()]
public void Cleanup()
{
}
[TestMethod]
public void ChangePasswordTest()
{
}
}
}
The test setup and cleanup methods are decorated with TestInitializeAttribute
and TestCleanupAttribute
, respectively. Within each of these methods, we can place any additional code that needs to be run before or after every test. This means that before each execution of ChangePasswordTest()
corresponding to each record within the LogonInfoTest table, both Initialize()
and Cleanup()
will be executed. The same is true each time NullUserIdInConstructor
and EmptyUserIdInConstructor
execute.
Such methods can be used to insert default data in a database and then clean up the data at the end of the test. It would be possible, for example, to begin a transaction within Initialize()
and then rollback the same transaction during cleanup such that, assuming the test methods use the same connection, the data state would be restored at the end of each test execution. Similarly, test files could be manipulated.
During debugging, it is possible that the TestCleanupAttribute
decorated method will not run simply because the debugger was stopped before the cleanup code executed. For this reason, it is often a good practice to check for cleanup during test setup and execute the cleanup prior to the setup as necessary. Other test attributes available for initialization and cleanup are AssemblyInitializeAttribute
/AssemblyCleanupAttribute
and ClassInitializeAttribute
/ClassCleanupAttribute
. The assembly related attributes run once for an entire assembly, while the class related attributes run once each for the loading of a particular test class.
Approach
In order to use VSTS for unit testing a sample application and to resolve the HttpContext and Session related issues, we should follow the steps mentioned below. The below sample pseudo code on the sample application emphasizes the steps involved:
Pseudo code for Sample.aspx.cs
using System.Diagnostics;
using System.Web.Hosting;
using System.Web;
using System.IO;
using System.Security.Permissions;
using System.Web.SessionState;
HttpContext Object Initialization
private TestContext testContextInstance;
public TestContext TestContext
{
get { return testContextInstance; }
set { testContextInstance = value; }
}
The Page
object is available through the RequestedPage
property of the TestContext
object for the class. Since the actual type of the page is dynamically generated when the page is loaded, we can only provide this as an object of type Page
, but it’s still possible to access members of the specific subclass of the page.
Session initializing and calls:
[AspNetHostingPermissionAttribute(SecurityAction.InheritanceDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermissionAttribute(SecurityAction.LinkDemand,
Level = AspNetHostingPermissionLevel.Minimal)]
public interface IRequiresSessionState { }
[TestInitialize]
public void TestInit()
{
HttpContext.Current = new HttpContext(new HttpRequest("",
"http://localhost", ""),
new HttpResponse(new System.IO.StringWriter()));
System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext(
HttpContext.Current, new HttpSessionStateContainer("",
new SessionStateItemCollection(), new HttpStaticObjectsCollection(),
20000, true, HttpCookieMode.UseCookies, SessionStateMode.Off, false));
}
[TestMethod()]
[DeploymentItem("Application.Web.dll")]
public void LoadTest()
{
Test target = new Test ();
TestProject1.ObjectName accessor = new TestProject1.ObjectName (target);
}
Sample test case project
[TestClass()]
public class _DefaultTest
{
private TestContext testContextInstance;
[TestInitialize]
public void TestInit()
{
HttpContext.Current = new HttpContext(new HttpRequest("",
"http://localhost", ""),
new HttpResponse(new System.IO.StringWriter()));
System.Web.SessionState.SessionStateUtility.AddHttpSessionStateToContext(
HttpContext.Current, new HttpSessionStateContainer("",
new SessionStateItemCollection(), new HttpStaticObjectsCollection(),
20000, true, HttpCookieMode.UseCookies, SessionStateMode.Off, false));
}
public TestContext TestContext
{
get
{
return testContextInstance;
}
set
{
testContextInstance = value;
}
}
[TestMethod()]
[UrlToTest("http://localhost")]
[DeploymentItem("SampleProject.dll")]
public void Page_LoadTest()
{
_Default_Accessor target = new _Default_Accessor();
object sender = null;
EventArgs e = null;
target.Page_Load(sender, e);
}
[TestMethod()]
[DeploymentItem("SampleProject.dll")]
public void SetSessionTest()
{
_Default_Accessor target = new _Default_Accessor();
target.SetSession();
}
}
Regarding Web.config
Web.config will not be supported while Unit Testing with VSTS. So, we should copy all the contents of Web.config except system.web
and paste into App.config. App.config should then be placed in the test project folder.
Debug the test case
Use System.Diagnostics.Debugger.Break();
to debug the application.
Void TestMethod()
{
System.Diagnostics.Debugger.Break();
}
In VS2008, just right click and generate the test case. It automatically generates the test case for all the methods/selected methods, and also handles session issues with attributes.