Testing the page object for an ASP.NET site


Using ASP.NET unit tests, you can test classes and methods that are part of an ASP.NET web site. This is often very similar to testing anything else, since you 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. That doesn’t mean you can’t test it, though. The example below and following comments show how to access the current page for an ASP.NET unit test, call methods on it, and use its controls. Note that the attributes for ASP.NET unit tests are slightly different now than in Beta 2–if you’re using that release, the test method will also require a [WebServerType(WebServerType.Iis)] attribute.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
 
[TestClass]
public class UnitTest1
{
    private TestContext testContextInstance;
 
    public TestContext TestContext
    {
        get { return testContextInstance; }
        set { testContextInstance = value; }
    }
    
    [TestMethod]
    [HostType("ASP.NET")]
    [UrlToTest("http://localhost/TestSite")]
    public void TestMethod1()
    {
        Page page = testContextInstance.RequestedPage;          //1
 
        Button button = (Button)page.FindControl("Button1");    //2
        Label label = (Label)page.FindControl("Label1");
 
        PrivateObject po = new PrivateObject(page);             //3
        po.Invoke("Button1_Click", button, EventArgs.Empty);
        Assert.AreEqual("Button1 clicked", label.Text);
    }
}

1. 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 (see 3, below).

2. You can get the controls on the page using FindControl() or the Controls collection. Note that you may need to dig down a couple levels if some controls are within a container, as happens when you use master pages.

3. When you generate tests against classes in the App_Code directory, private accessors are created that allow you to reference those types and call their methods. As mentioned above, we can’t generate code for the page class, so private accessors can’t be created either. However, you can use PrivateObject to access members of the page that aren’t normally available through the Page object. In my example I use this to call Button1_Click(button, EventArgs.Empty), which is defined in default.aspx.cs.

Once you have the page object, you can use the standard Page methods and properties to work with it and its controls as you need. With a PrivateObject providing access to nonpublic members, you can essentially test the page just like you would any other class.

Kevin Cogger

SDET, Visual Studio Team System


Comments (11)

  1. .Net in Samples – Free eBook [Via: Ohad Israeli ]

    A Customizable Login Server Control [Via: Bilal Haidar…

  2. .Net in Samples – Free eBook [Via:

    Ohad Israeli

    ]

    A Customizable Login

    Server Control [Via: Bilal…

  3. Rob Caron – How To Get Team Foundation Functionality in Visual Studio

    Rob confirms that you have to…

  4. stefan.kowalewski says:

    are there any working examples of being able to unit test ASP.NEt pags/classes??

    reading the blog and this post (http://msdn2.microsoft.com/en-us/library/ms182526.aspx), i’ve tried to write an ASP.NET unit test.  the problem i am having is running the test – it can’t find the page/site.  i’m trying to run the tests in the development server mode (and maybe this is my problem).  i’ve set the port on the web project and set the "dynamic" property to false – so that the port is always the same when i run the site/pages.

    i’ve decorateed the unit test with the UrlToTest attribute, including the port number (http://localhost:12345/AspnetWebSite).  however, when i run the test i created, from the test manager, the tests attempt to access the site/pages on a different port.  each time i run the test (from test manager), it runs on a different port.

    i’m wondering if any one has any working examples/code for sucessfully running ASP.NET unit tests.

    thanks…

  5. stefan.kowalewski says:

    regardinng my comment above, my problem was a configuration setting.  in the "Hosts" setting for the localteestrun.testrunconfig configuration file, i wasn’t properly setting the "Web application root:".  i had all the other setting correct…

  6. Cois says:

    The [UrlToTest] attribute specifies the initial page to test. But is it possible to change the page within the same method?

    Or, more specifically, what happens if the page I need to test can only be accessed after going to a login page and entering credentials?

  7. We recently ran a bootcamp for some of our internal teams on the testing capabilities of Visual Studio

  8. RSS It All says:

    We recently ran a bootcamp for some of our internal teams on the testing capabilities of Visual Studio

  9. snkscore says:

    Is anything happening with asp.net unit tests?

    This post is almost 2 years old and it is one of the only pieces of info out there of value when it comes to creating ASP.NET Unit Tests.

    Is there no documentation?  No examples?  No best practices or anything?

    Is this an abandoned product?

  10. ulu says:

    Asp.Net testing is also possible with Ivonna:

    http://sm-art.biz/Ivonna.aspx

    ulu