5.14. Applying Automated UI Testing to the ASP.NET Family

You have learned that UI tests that are tightly coupled to the browser become hard to read and maintain if there are changes made to the application under test, and tests should be abstracted as far away from the browser as possible. The following section is intended to apply some of the techniques discussed in this chapter to specific technologies that fall under the ASP.NET family.

5.14.1. ASP.NET WebForms

The techniques that abstract the tests from the browser that have been discussed so far are all valid when testing against ASP.NET WebForms. Problems will occur if you are testing ASP.NET WebForm applications where the data access is not abstracted very well. The following example contains a set of tests to ensure a user can log in to a homepage of an order-processing system. You cannot tell from these tests that the application is using ADO.NET to return datasets to the WebForms to render the data:

using NUnit.Framework;
using WroxPizza.Orders.Tests.Integration.model;

namespace WroxPizza.Orders.Tests.Integration
{
    public class HomePageTests: BaseUITest
    {
        [Test]
        public void Should_Load_Load_The_Home_Page()
        {
            HomePage homePage = new HomePage(Browser);
            string expectedTitle = "wrox pizza shop | login";

            Assert.AreEqual(expectedTitle, homePage.Title.ToLower());
        }

        [Test]
        public void Should_Not_Login_With_An_Invalid_User()
        {
            HomePage homePage = new HomePage(Browser);
            homePage.LoginUser("Invalid_User_Name", "Invalid_Password");
            string expectedMessage = "Your login attempt was not successful. Please
try again.";

            Assert.AreEqual(expectedMessage, homePage.LoginStatus);

}

        [Test]
        public void Should_Login_With_A_Valid_User()
        {
            HomePage homePage = new HomePage(Browser);
            homePage.LoginUser("Invalid_User_Name", "Invalid_Password");

            Assert.That(homePage.MenuOptions.Exists(menuOption => menuOption
               .ToLower() == "Add Employee"));
        }
    }
}

Because mocking the data layer is nearly impossible, in this situation it's best to re-create the database from a known set of data for each Test fixture that is run. The abstract base class in the listing just shown introduces two new concepts. The first concept is restoring the database to a known state upon each Test fixture creation. In this listing, ADO.NET was used to call two stored procedures that were created in the database: one to create the set of known data (Test_Setup) and one to clear out the data (Test_Teardown).

You have learned that when running tests, the database should be in a known state. So, what happens in this example is that if you have a test that adds a record then the next test expects that a certain number of records exist. This is where the second concept comes into play. Pay attention to the BrowserSetup method, which is the test Setup method; this method is called before each individual test runs. You are creating a new transaction when the test starts, but you never commit the transaction. Because the data was not committed, the data is still in the known state:

[SetUp]
public void BrowserSetup()
{
    m_ts = new TransactionScope();

    Browser = BrowserFactory.Create(browserType);
    Browser.GoTo(URL);
}

The following code example will illustrate a technique on how to keep data in a known state.

using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Transactions;
using NUnit.Framework;
using WatiN.Core;
using WatiN.Core.Interfaces;

namespace WroxPizza.Orders.Tests.Integration
{
    public abstract class BaseUITest: CassiniWebServer
    {

public IBrowser Browser { get; set; }
        BrowserType browserType;
        private TransactionScope m_ts;
        private string m_conString =
ConfigurationManager.ConnectionStrings["WroxPizza"].ConnectionString;

        public BaseUITest()
        {
            browserType = BrowserType.InternetExplorer;
        }

        [TestFixtureSetUp]
        public void FixtureSetup()
        {
            TearDown();
            SetUp();
        }

        [SetUp]
        public void BrowserSetup()
        {
            m_ts = new TransactionScope();

            Browser = BrowserFactory.Create(browserType);
            Browser.GoTo(URL);
        }

        [TearDown]
        public void BrowserTeardown()
        {
            if (Browser != null)
                Browser.Dispose();

            m_ts.Dispose();
            m_ts = null;
        }

        private void SetUp()
        {
            ExecuteStoredProcedure("Test_Setup");
        }

        private void TearDown()
        {
            ExecuteStoredProcedure("Test_TearDown");
        }

        private void ExecuteStoredProcedure(string procedureName)
        {
            SqlConnection sqlConnection = new SqlConnection(m_conString);
            SqlCommand cmd = new SqlCommand(procedureName, sqlConnection);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.ExecuteNonQuery();
        }

}
}

5.14.2. Silverlight Testing

Silverlight 2 includes a unit test harness that enables you to perform both API and UI level unit testing. In 2008 when Microsoft released the source code for the Silverlight 2 controls, they also included roughly 2,000 unit tests to go along with them.

AssemblyPurpose
Microsoft.Silverlight.TestingUnit test framework
Microsoft.Silverlight.Testing.FrameworkBase classes and interfaces for test harnesses

Another tool that is available for testing Silverlight applications is Silvernium, which is based on the Selenium framework. The next listing shows a Silvernium test to test a Silverlight control:

using NUnit.Framework;
using Selenium;
using ThoughtWorks.Selenium.Silvernium;

namespace Account.Tests.UI
{
    [TestFixture]
    public class AccountTests
    {
        private const string URL = "http://localhost/SilverLightAccount";
        private const string OBJECTID = "Account";
        private const string SCRIPTKEY = "AccountCreation";

        private ISelenium selenium;
        private Silvernium silvernium;

        [SetUp]
        public void SetUp()
        {
            selenium = new DefaultSelenium("localhost", 4444, "*iexplore", URL);
            selenium.Start();
            selenium.Open(URL);
            silvernium = new Silvernium(selenium, OBJECTID, SCRIPTKEY);
        }

        [TearDown]
        public void TearDown()
        {
            selenium.Stop();
        }

        [Test]
        public void ShouldCommunicateWithSilverNibbleApplication()
        {

Assert.AreEqual("Create Accouunt", selenium.GetTitle());
            Assert.AreEqual(800, silvernium.ActualWidth());
            Assert.AreEqual(600, silvernium.ActualHeight());

            Assert.AreNotEqual("null", silvernium.Call("NewAccount", "564858510",
               "100"));

            Assert.AreEqual("100", silvernium.GetPropertyValue("Balance"));

            silvernium.SetPropertyValue("Balance", "300");
            Assert.AreEqual("300", silvernium.GetPropertyValue("Balance"));
        }
    }
}

Testing a Silverlight UI is very similar to testing other UIs — you just need to have the right tool for the job.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.226.120