Modifying Generated Code in a Coded UI Test

Intro

This is part 8 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

 

Modifying Generated Code

I mentioned that we should not edit code found in the <Page>Map.Designer.cs file. What should we do if we want to customize our code (we will make our AssertQuantity more robust)? Double click on the uitest file that contains the code you want to modify. In the UI map editor highlight the method you want to change -> click the Move Code button -> click the save all button or ctrl + shift + S.

Now double click the ShoppingCartPageMap.cs and notice we have code. We can safely edit the code now without fear that the code generator will overwrite our changes.

image

Here is the AssertQuantity method before our changes:

public void AssertQuantity()
        {
            #region Variable Declarations
            HtmlEdit uIQuantityEdit = this.UIHomeTailspinToysWindWindow.UIHomeTailspinToysDocument.UIQuantityEdit;
            #endregion

            // Verify that 'Quantity' text box's property 'Text' equals '1'
            Assert.AreEqual(this.AssertQuantityExpectedValues.UIQuantityEditText, uIQuantityEdit.Text);
        }

We are going to modify the method signature and the highlighted expected value to accept a parameter rather than the constant 1 (so that we can validate quantities other than 1).

The altered code looks like this:

        public void AssertQuantity(string expectedValue)
        {
            #region Variable Declarations
            HtmlEdit uIQuantityEdit = this.UIHomeTailspinToysWindWindow.UIHomeTailspinToysDocument.UIQuantityEdit;
            #endregion

            Assert.AreEqual(expectedValue, uIQuantityEdit.Text);
        }

Once we make this change, our test case will no longer run because our call to AssertQuantity does not pass in a parameter.

image

 

To fix that we need to pass in the value we expect in the Quantity text box, a ?1?.

The altered code will look like this:

[TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            try
            {
                trUtility.HomePage.NavigateToTailspinToysSite();
                //On the home page click the Model Airplanes button
                trUtility.HomePage.NavigateToModelAirplanes();
                //From model airplane page, click the view fourth coffee flyer button
                trUtility.ModelAirplanePage.ViewFourthCoffeeFlyer();
                //From the fourth coffee Flyer details page, click add to cart
                trUtility.FourthCopyFlyerDetailsPage.AddFourthCoffeeFlyerToCart();
                //We should be at the shopping cart now
                //Validate the quantity
                trUtility.ShoppingCartPage.AssertQuantity("1");
                //Clean out the cart
                trUtility.ShoppingCartPage.RemoveItemFromCart();

            }
            finally
            {
                //close the browser
                trUtility.HomePage.CloseBrowser();
            }
        }

For fun, change the ?1? to a ?2? . Now when you run the test (not debug), we should see the test fail and we should still see the browser close which is the behavior we want.


Posted by: Tim Star
Posted on: 8/26/2011 at 3:08 PM
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Deleting actions when recording with the Coded UI Test Builder

Intro

This is part 7 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

If during the course of recording your actions in the Coded UI test builder you interact with something you don?t want recorded (like you send an instant message or an email) you can delete those actions from the recording by clicking on the Show Recorded Steps button

image

A list will display of all actions that have been recorded since you last generated code:

image

You may delete items from this list by highlighting the item or items you want removed, right clicking and selecting Delete.


Posted by: Tim Star
Posted on: 8/26/2011 at 2:56 PM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Coded UI: Editing/Changing Recorded Method Names

This is part 6 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Editing/Changing Recorded Method Names

If you are unhappy with the name of your asserts or methods, you can double click the <page>Map.uitest file to open the UI Map editor -> highlight the method you want to change and press the F2 key or click the rename toolbar button

image

Changing the actions in a Recorded Method

If you have recorded something that needs to change, because the application changed or you recorded some action that shouldn?t be in the test, you may rerecord the actions and replace the old method.

First open the browser and navigate to the page you want to modify.

Right click on the <page>Map.uitest file and select Edit with Coded UI Test Builder

image

Record your actions but this time we want to reuse the existing method. Click the drop down arrow and select your method

image

Notice the button becomes ?Replace and Generate?.

image


Posted by: Tim Star
Posted on: 8/1/2011 at 11:13 AM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (3) | Subscribe to this BlogRSS comment feed

Coded UI: Assembling the test

This is part 5 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Assembling the Test

Time to ?assemble our test scenario?. Best practice dictates we rename CodedUITest1.cs so right click on file in solution explorer -> rename. Enter TailspinToysTest.cs (It is important to keep the .cs extension and click yes if prompted).

Now double click on the file name. In the editor pane you should see the following:

image

Change the highlighted method to something meaningful like AddOneCoffeFlyerToCartTest

image

Now add a using to the top of the TailspinToysTest class referencing the namespace in the TestRunUtility class.

image

Now we are ready to assemble the test.

In the AddOneCoffeeFlyerToCartTest instantiate an instance of the TestRunUtility.

        [TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();

        }

The first thing our test should do is launch IE and navigate to the home page.

Enter the following code to accomplish this

        [TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            trUtility.HomePage.NavigateToTailspinToysSite();
        }

Now run the test and see if we get a new instance of IE launched and it navigates to TailspinToys correctly.

You can run or debug a single test by placing your mouse cursor in the test method and clicking the Run or Debug tests in current context buttons highlighted below:

image

Now that we are successfully launching the browser and navigating to TailspinToys we need to navigate through our pages until we get to the shopping cart. Implement the following code. The lines beginning with ?//? and are colored green are comments. You do not need to enter comments.

        [TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            trUtility.HomePage.NavigateToTailspinToysSite();
            //On the home page click the Model Airplanes button
            trUtility.HomePage.NavigateToModelAirplanes();
            //From model airplane page, click the view fourth coffee flyer button
            trUtility.ModelAirplanePage.ViewFourthCoffeeFlyer();
            //From the fourth coffee Flyer details page, click add to cart
            trUtility.FourthCopyFlyerDetailsPage.AddFourthCoffeeFlyerToCart();
            //We should be at the shopping cart now

        }

Run the test method again and validate that the browser is launched and we navigate all the way to the shopping cart.

We only have 3 steps left, adding the validation, cleaning out the cart, and closing the browser. The code for that is as follows

        [TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            trUtility.HomePage.NavigateToTailspinToysSite();
            //On the home page click the Model Airplanes button
            trUtility.HomePage.NavigateToModelAirplanes();
            //From model airplane page, click the view fourth coffee flyer button
            trUtility.ModelAirplanePage.ViewFourthCoffeeFlyer();
            //From the fourth coffee Flyer details page, click add to cart
            trUtility.FourthCopyFlyerDetailsPage.AddFourthCoffeeFlyerToCart();
            //We should be at the shopping cart now
            //Validate the quantity
            trUtility.ShoppingCartPage.AssertQuantity();
            //Clean out the cart
            trUtility.ShoppingCartPage.RemoveItemFromCart();
            //close the browser
            trUtility.HomePage.CloseBrowser();
        }

When the run is complete you should see the following in your test result window. The Green icon indicates our test passed.

image

One final improvement, if we are running a test and the test fails, the browser will be left open. We could either wrap the code in a using statement or put in a try-Finally. The code looks like this:

        [TestMethod]
        public void AddOneCoffeFlyerToCartTest()
        {
            TestRunUtility trUtility = new TestRunUtility();
            try
            {
            trUtility.HomePage.NavigateToTailspinToysSite();
            //On the home page click the Model Airplanes button
            trUtility.HomePage.NavigateToModelAirplanes();
            //From model airplane page, click the view fourth coffee flyer button
            trUtility.ModelAirplanePage.ViewFourthCoffeeFlyer();
            //From the fourth coffee Flyer details page, click add to cart
            trUtility.FourthCopyFlyerDetailsPage.AddFourthCoffeeFlyerToCart();
            //We should be at the shopping cart now
            //Validate the quantity
            trUtility.ShoppingCartPage.AssertQuantity();
            //Clean out the cart
            trUtility.ShoppingCartPage.RemoveItemFromCart();
            
            }
            finally
            {
                //close the browser
                trUtility.HomePage.CloseBrowser();
            }
        }

Now if our test fails we will still close the browser window.

That is it!  We have used the multiple-ui map technique to create a robust maintainable coded UI test.  In our next few posts we will learns some techniques to help us maintain and enhance these tests.


Posted by: Tim Star
Posted on: 7/21/2011 at 8:50 AM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

CodedUI - Adding a UI Map to the TestRunUtility

This is part 4 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Creating the TestRunUtility

In my last post I mentioned we could reference and call each of these maps individually and successfully test this scenario without a problem. The weakness in doing that is that we have quite a bit of duplicate code in our generated UI maps. Specifically if you do a file search for ?Home - Tailspin Toys? you will see we are using it in each of our generated maps.

image

This text is being used during by the test execution engine at runtime to search for the correct window that each of the controls reside in (top level ancestor). Imagine a developer changes the title of your window. Every UI map would be broken and must be regenerated to fix the problem. Rather than doing that we are going to create a new Class called TestRunUtility.

Go to solution explorer; right click the Utility Folder -> select Add -> select Class?

image

Type TestRunUtility.cs into the name field and click the Add Button

image

The following empty class is displayed:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyWebsiteCodedUITests.Utility
{
    class TestRunUtility
    {
    }
}

Modify the code so it looks like the following:

using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
    public class TestRunUtility
    {
        // Private fields for the properties
        private HomePageMap homePage = null;


        public TestRunUtility()
        {
            homePage = new HomePageMap();
        }

        // Properties that get each UI Map
        public HomePageMap HomePage
        {
            get { return homePage; }
            set { homePage = value; }
        }

    }
}

Adding a UI Map to the TestRunUtility

Now here comes the magic and what we are doing is boiler plate meaning we will repeat the following steps for our other 3 UI Maps AND any new map we add later.

Step 1) Add a using for the new UI Map to the top of the class:

using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
    public class TestRunUtility
    {

 

If you use default namespaces, here is how the using statement maps to the project (spaces are removed)

image

Next add a private field to access the new Map

using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
    public class TestRunUtility
    {
        // Private fields for the properties
        private HomePageMap homePage = null;
        private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;

        public TestRunUtility()
        {
            homePage = new HomePageMap();
        }

Next we will build and expose a property that will allow us to access the FourthCoffeeFlyerDetailsPage. This property will use the same top level window as our home page.

using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
    public class TestRunUtility
    {
        // Private fields for the properties
        private HomePageMap homePage = null;
        private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;

        public TestRunUtility()
        {
            homePage = new HomePageMap();
        }

        // Properties that get each UI Map
        public HomePageMap HomePage
        {
            get { return homePage; }
            set { homePage = value; }
        }


        public FourthCoffeeFlyerDetailsPageMap FourthCopyFlyerDetailsPage
        {
            get
            {
                if (fourthCopyFlyerDetailsPage == null)
                {

                    fourthCopyFlyerDetailsPage = new FourthCoffeeFlyerDetailsPageMap();

                    fourthCopyFlyerDetailsPage.UIHomeTailspinToysWindWindow.CopyFrom(
                        HomePage.UIBlankPageWindowsInteWindow);
                }
                return fourthCopyFlyerDetailsPage;
            }
        }



    }
}

 

Here is the mapping between the property and the private field we declared a moment ago (Case is very important!):

image

Repeat this for the other 2 UI Maps and the resulting class should be as follows:

using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
using MyWebsiteCodedUITests.UIMaps.ModelAirplanePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.ShoppingCartPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
    public class TestRunUtility
    {
        // Private fields for the properties
        private HomePageMap homePage = null;
        private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;
        private ModelAirplanePageMap modelAirplanePage = null;
        private ShoppingCartPageMap shoppingCartPage = null;
        public TestRunUtility()
        {
            homePage = new HomePageMap();
        }

        // Properties that get each UI Map
        public HomePageMap HomePage
        {
            get { return homePage; }
            set { homePage = value; }
        }


        public FourthCoffeeFlyerDetailsPageMap FourthCopyFlyerDetailsPage
        {
            get
            {
                if (fourthCopyFlyerDetailsPage == null)
                {

                    fourthCopyFlyerDetailsPage = new FourthCoffeeFlyerDetailsPageMap();

                    fourthCopyFlyerDetailsPage.UIHomeTailspinToysWindWindow.CopyFrom(
                        HomePage.UIBlankPageWindowsInteWindow);
                }
                return fourthCopyFlyerDetailsPage;
            }
        }

        public ModelAirplanePageMap ModelAirplanePage
        {
            get
            {
                if (modelAirplanePage == null)
                {

                    modelAirplanePage = new ModelAirplanePageMap();

                    modelAirplanePage.UIHomeTailspinToysWindWindow.CopyFrom(
                        HomePage.UIBlankPageWindowsInteWindow);
                }
                return modelAirplanePage;
            }
        }

        public ShoppingCartPageMap ShoppingCartPage
        {
            get
            {
                if (shoppingCartPage == null)
                {

                    shoppingCartPage = new ShoppingCartPageMap();

                    shoppingCartPage.UIHomeTailspinToysWindWindow.CopyFrom(
                        HomePage.UIBlankPageWindowsInteWindow);
                }
                return shoppingCartPage;
            }
        }

    }
}

What we have accomplished here is we set up a utility that told all of our UI Maps to use the same top level window as our Home Page. Now if a developer changes something, we only need to fix our home page. In My next post we will start assembling the coded UI test.

 

Posted by: Tim Star
Posted on: 7/21/2011 at 8:20 AM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Modifying an Existing Coded UI Map

Intro

This is part 3 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

 

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Modifying an Existing Coded UI Map

In our last post, we decided we needed to record the closing of the browser and that action belonged in our home page map.  We already created the HomePageMap so we now need to modify it to add another action.

In solution explorer, right click on the HomePageMap.uitest and select ?Edit with Coded UI Test Builder?.

image

The Coded ui Test builder is launched (Note: this is one of many actions that will cause the <PageName>.designer.cs to be regenerated.

Without recording, navigate to the home page.

Start Recording -> close the browser -> Click Generate Code -> Enter CloseBrowser for the name -> Click Add and Generate -> Close the Coded UI test Builder.

That is all there is to it.

What we have at this point is a bunch of disconnected actions and an assertion. Now we need to put it all together and this is where the Multiple UI map technique comes into play. We could reference and call each of these maps individually and successfully test this scenario without a problem. The weakness in doing that is that we have quite a bit of duplicate code in our generated UI maps. Specifically if you do a file search for ?Home - Tailspin Toys? you will see we are using it in each of our generated maps.  In my next post I will add some code and something called the TestRunUtility so we can start tying all of these UI maps together.


Posted by: Tim Star
Posted on: 7/13/2011 at 5:18 PM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Adding a New UI Map to a Coded UI Test

Intro

This is part 2 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Planning the maps

Imagine this is our test case:

? Navigate to the Tail Spin Toy Site

? Click The Model Airplane Link

? Click the View Plane button next to the fourth coffee flyer

? Click the Add To cart button

? Review the shopping cart

What we want to do now is record the UI actions for several different pages in the Tailspin Toys website. If we look at the Tail Spin Toys example website we are going to interact with the following pages:

Home page ?

image

Model Airplanes Page -

image

Fourth Coffee Flyer Details page -

image

The Shopping Cart Page -

image

The pages are pretty simple so we are going to create a UI Map for each page.  We could also create a UI Map for each control if our site reused many complex controls.

Adding a new UI Map

The first actions we want to record is Navigate to the home page and select the Model Airplanes button. So right click on the UI Maps folder and select Add -> New Item?

image

From the resulting dialog, select Coded UI Test Map, change the name to something meaningful like HomePageMap.uitest and click the Add button.

image

Notice the Coded UI Test Builder is launched and displayed in the lower right hand corner of your screen

image

The first thing we want to do is press record.

Then we will launch Internet Explorer

Type in the address: http://win-gs9gmujits8:8000 and click the enter key.

Click the show recorded steps button and you should see the following (note: if about:blank is not your home page, you may see a different initial web page and you could see differences if you click a short cut or use copy paste. Generally speaking you should type in the address for the recording)

image

Click the generate Code button and add a method name as NavigateToTailspinToysSite

, then click Add and Generate

image

Next click record again and click on the Model Airplanes button then click the Generate Code Button and enter NavigateToModelAirplanes

image

At this point we have generated a UI map for the things we are interested in on this ?home page?. If we take a look at the solution we will see 3 files.

HomePageMap.uitest ? this is an xml file that should only be edited by double clicking on this file and using the UI Map Editor (must have VS 2010 feature pack 2 to use the editor)

HomePageMap.cs ? This file contains custom code and may be hand edited. It will be blank right now.

HomePageMap.Designer.cs ? This file contains generated code. Do not edit this file as you changes will be overwritten any time visual studio regenerates this file.

image

Click here for the MSDN Documentation.

Now we want to generate the UI map for our Model Airplanes Page. The key here is that we do not want or need to launch internet explorer again so before recording we will open IE -> navigate to the tailspin toys site -> click on the Model Airplanes button. Your browser should look like this:

image

The only control we are really interested in here is the View Plane button for the Fourth Coffee Flyer.

To create the UI Map, right click on the UI Maps folder and select Add -> New Item?

image

From the resulting dialog, select Coded UI Test Map, change the name to something meaningful like ModelAirplanePageMap.uitest and click the Add button.

Again, the Coded UI builder is launched. Click the record button -> Click the View Plane button for the Fourth Coffee Flyer and click generate code.

image

Enter ViewFourthCoffeeFlyer and click Add andGenerate.

Close the coded UI Builder.

That brings us to the next page which I have chosen to call Fourth Coffee Flyer Details page. On this page we are interested only in adding a Fourth Coffee Flyer to the cart. Again go to solution explorer in visual studio, right click on the UI Maps folder and select Add -> New Item?

image

From the resulting dialog, select Coded UI Test Map, change the name to something meaningful like FourthCoffeeFlyerDetailsPageMap.uitest and click the Add button. Again, the Coded UI Test builder is launched.

Without recording we need to open IE -> navigate to the tailspin toys site -> click on the Model Airplanes button -> Click the View Plane button for the Fourth Coffee Flyer. Now we are on the Fourth Coffee Flyer Details page so we can click the record button -> Click the Add to Cart Button -> Click the Generate Code Button and type in the name AddFourthCoffeeFlyerToCart -> click Add and Generate.

image

Close the Coded UI test builder and your project in solution Explorer should now look like this:

image

We are almost done with the UI Map generation. For our final page we are going to validate some information on our Shopping Cart Page. Again go to solution explorer in visual studio, right click on the UI Maps folder and select Add -> New Item?

image

From the resulting dialog, select Coded UI Test Map, change the name to something meaningful like ShoppingCartPageMap.uitest and click the Add button. Again, the Coded UI Test builder is launched. Without recording we need to open IE -> navigate to the tailspin toys site -> click on the Model Airplanes button -> Click the View Plane button for the Fourth Coffee Flyer -> Click Add to Cart.

There is no need to press record this time as all we want to do is add an assertion. With your mouse pointer over the Assert button click and hold the left mouse button down while dragging the cursor over the text box that contains the quantity 1 outlined in blue then release the mouse button.

image

You should now see something similar to this in the lower left corner of your screen:

image

Scroll down until you see the text attribute, then highlight that row by clicking the word text and click the add assertion button.

image

Accept the defaults -> click OK.

image

Now click the generate code button and enter AssertQuantity and click the Add and Generate Button.

What we have just done is generated code that says ?validate that the quantity input box has a text value of ?1?.

Two more steps, first we are going to clear the cart so press Record on the Coded UI builder -> Click Remove -> Click Generate Code -> Enter RemoveItemFromCart for the name -> Click Add and Generate.

The final thing we want to do is close the Browser. This is important as eventually these tests should be automated and run as part of a build. During the test run we don?t want to have multiple browsers open 1) because eventually we will run out of memory and 2) this can really mess up our tests depending how the site manages session.

I think a more intuitive place to close the browser is from the home page so we are going to close the coded UI test builder and in the next post we will see how to modify an existing Coded UI Test Map.


Posted by: Tim Star
Posted on: 7/13/2011 at 5:07 PM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Coded UI Testing with Multiple UI Maps (Detailed)

 

Intro

This will be a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.

Part 1: Creating a new Coded UI solution

Part 2: Adding a New UI Map

Part 3: Modifying an Existing Coded UI Map

Part 4: Adding a UI Map to the TestRunUtility

Part 5: Assembling the test

Part 6: Changing Recorded Methods

Part 7: Deleting actions when recording with the Coded UI Test Builder

Part 8: Modifying Generated Code

Credits

This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx

http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx

http://msdn.microsoft.com/en-us/library/ff398056.aspx

Assumptions

My assumption is you have access to the Tail Spin Toys web site freely available on the Visual Studio RTM Virtual Machine (*Note: the VM expires every several months so this link may be stale after November 2011) I am also assuming you are logged in as the user Abu and that you have VS 2010 feature pack 2

Note, as the code is written in C#, casing of the code is important. strVariable is different than strvariable and this can give those new to c# programming fits so take care to match the exact naming conventions in the following examples.

 

Creating a New CUIT Solution

Open Visual Studio 2010 -

From the start menu select All Programs -> Microsoft Visual Studio 2010 -> Microsoft Visual Studio 2010

image

From the start page select File -> New -> Project

image

Highlight the Test Template -> select Test Project -> give the project a meaningful name -> select OK

image

In solution Explorer, right click UnitTest1.cs -> select delete -> Click the OK button on the warning dialog.

image

In solution explorer right click the project -> select Add -> select Coded UI test?

image

Select Cancel

image

Right click the solution -> select Add -> select New Folder -> Name the Folder Utility

image

Again right click the solution -> select Add -> select New Folder -> Name the Folder UI Maps

image

Your solution should now look like this (don?t worry about the yellow + icons, you will not see those if you are not using version control):

image

At this point we have an essentially empty solution and we are ready to start adding UI Maps.  In the next post we will do just that.


Posted by: Tim Star
Posted on: 7/13/2011 at 4:45 PM
Tags:
Categories: .NET | Visual Studio
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (1) | Subscribe to this BlogRSS comment feed

Visual Studio ALM Rangers Build Customization and Lab Management Guidance Published

A couple new Visual Studio ALM Rangers guidance packages became available out on codeplex yesterday.

Visual Studio Build Customization Guidance

I participated both as a reviewer and contributor on the build customization project. The guidance package includes several posters, a 180 page PDF reference, and a Hands On Lab (HOL).    Even though I had a fair amount of experience in working with the Team Foundation Build before joining the project, in reviewing the HOL I learned a couple nice debugging techniques, among other things, that I will definitely use moving forward.  Here is an outline of what is available in the download:

Project Description

This Visual Studio ALM Ranger project has the primary goal of delivering scenario based and hands-on lab guidance for the customization and deployment of Team Foundation Build 2010 activities such as versioning, code signing, and branching.

What is in the downloads?

  • Guidance contains scenario based practical guidance, frequently asked questions and quick reference posters
    • Selected PDF contains guidance and quick reference posters in PDF format only.
    • Complete contains guidance, quick reference posters and localization files in all available formats.
  • Hands-on Labs (HOL) includes:
    • HOL documents that provide walkthroughs of the technology, based on the guidance
    • HOL Package contains a HOL environment setup package allowing you to setup the HOL environment in your own environment
  • BRDLite Build Process Reference Template walk-through.
  • Samples contains sample build process templates used by the team as part of the guidance.
  • Videos which showcase the guidance in quick 5-10min videos.

The Epics included in the guidance are:

  • Practical guidance and tooling to simplify the customization of Team Foundation Build
  • Practical guidance to use Team Foundation Build process templates to automate build and non-build scenarios in Microsoft environments
  • Practical guidance to enable simple and flexible deployment of applications and their data stores
  • Practical guidance for Activities to empower developers and build engineers
  • Quality hands-on labs that complement the guidance and effectively guide the user through the features
  • Visualization of the guidance using quick reference posters

 

Visual Studio Lab Management Guidance

I didn?t have the bandwidth (or the Iron) to act as a reviewer on this project but I expect the quality of this guidance is as good as we have come to expect from the Internal (Microsoft) and External Rangers.

Project Description

This Visual Studio ALM Ranger project has the primary goal of delivering scenario based and hands-on guidance for the planning, setup, configuration and usage of Visual Studio Lab Management, backed by custom VM Template automation for reference environments.

Bookmark the Visual Studio Lab Management Guidance TOC blog and monitor the Visual Studio ALM Rangers blog, using tag tfslm, for the latest information on this project.

The Visual Studio 2010 and Team Foundation Server 2010 VM Factory project is a companion solution, which is focused on the Virtual Machine (VM) Factory, used by and referred to by this guidance.

The following Epics summarize the scope of the guidance which is designed for professional deployment of Lab Management in production environments.

  • Visualization of the guidance using quick reference posters
  • Advanced golden image management using the VM Factory for Lab Management
  • Provide guidance on setting up Test environments with respect to pre-defined personas
  • Provide Guidance to enable large and small teams to setup and configure both automated and manual tests
  • Provide practical guidance for managing and maintaining a Lab Management environment
  • Provide practical guidance to enable teams to quickly setup and configure their lab management environment

 

 

I expect both of these projects will continue to get attention from the Ranger team so go out and have a look at the material, run through the labs, and let us know what you think and what you want to see next.  On the home page, both projects give you visibility to the backlog and provide links for feedback and suggestions on their respective home pages.


Posted by: Tim Star
Posted on: 6/18/2011 at 8:45 AM
Categories: Visual Studio | .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed

Code Review Checklist: Consider Aggregation

This week I want to discuss another bullet from my code review checklist.   In a previous post I discussed favoring Composition over Inheritance.  Aggregation and composition are very similar concepts.  In fact it is really the same concept with a little different implementation in that they both combine multiple 'simple' objects into a larger more complex object.  With Composition the lifetime of the simple objects are controlled by the more complex class.  With aggregation the lifetime of the simpler objects are not controlled by the more complex class rather the consumer is responsible for managing the lifetime of these objects.   Talking in terms of concepts can be pretty confusing so let's look to the physical world for an example. 

When you buy a home theater sound system you can go two routes; buy a home theater in a box, or buy individual components and build your home theater.  With a home theater in a box you get the amplifier, receiver, digital media player, equalizer etc. all in one big unit.  Within this unit there are very likely several different circuit boards for the eq, receiver, dvd player etc. and the manufacturer is probably using this same component in different models.  As the consumer, setting up a home theater in a box system is relatively simple.  Plug in the speakers, connect it to the TV and plug it into the wall.  The down side of this is that it probably doesn't sound as good as if you would have bought the best of each component and if you want to start watching blue rays you have to replace the entire system. 

If you buy a componentized home theater the consumer has a lot more work to do to get things going.  Connect the DVD player to the TV and receiver, connect the TV to the receiver, connect the equalizer to the receiver, connect the amplifier to the receiver etc. then plug all of these units into a power supply.  Clearly the consumer has more work to do and the consumer also has to be more intelligent (from an AV standpoint) to setup and use this system.  The upside to this is if you want to replace the DVD player with a blue ray player, you can simply unplug the DVD component and plug in the new blue ray.

Let's look at what some really simplified sample code might look like:

 

Home Theater In A Box:

using System;
 
namespace TheaterInABox
{
    public class HomeTheater
    {
        private ISound _activeSoundDevice;
        private IVideo _videoDevice;
        public bool SystemPower { get; set; }
        public ActiveDevice DeviceSelector
        {
            set
            {
                switch (value)
                {
                    case ActiveDevice.Tv:
                        _activeSoundDevice = AudioIn;
                        break;
                    case ActiveDevice.Radio:
                        _activeSoundDevice = new StereoReceiver ();
                        break;
                    case ActiveDevice.DigitalMediaPlayer:
                        _activeSoundDevice = new Dvd();
                        if (_videoDevice == null)
                            _videoDevice = new Dvd();
                        break;
                    default:
                        throw new Exception("Device not supported");
                }
            }
        }
        public ISound AudioIn
        {
            private get { return _activeSoundDevice; }
            set { _activeSoundDevice = value; }
        }
        public IVideo DigitalMediaOut
        {
            get { return _videoDevice ?? new Dvd(); }
        }
 
        class StereoReceiver : ISound
        {
 
        }
        class Dvd : IVideo, ISound
        {
 
        }
 
    }
    public enum ActiveDevice
    {
        Tv,
        Radio,
        DigitalMediaPlayer
    }
    public interface ISound { }
    public interface IVideo { }
 
}

Consumer:

using System;
using TheaterInABox;
 
namespace Consumer
{
    public class SimpleConsumer
    {
        public void WatchMediaDevice()
        {
            var theater= new HomeTheater{};
            theater.SystemPower=true;
            theater.DeviceSelector = ActiveDevice.DigitalMediaPlayer;
        }
    }
}

 

To summarize:

The above code is an example of composition:

Composed object responsible for managing the lifetime of its simpler objects

Composed Object is responsible for constructing the simpler objects

Composed object is somewhat rigid.  You cannot, for example, watch a blue ray

Consumer code is less intelligent in that it doesn't need to understand how to instantiate the simpler objects

 

Componentized Theater:

using System;
 
namespace ComponentizedTheater
{
    public class HomeTheater
    {
        public HomeTheater( ISound soundDevice1,ISound soundDevice2,ISound soundDevice3)
        {
            _soundDevice1 = soundDevice1;
            _soundDevice2 = soundDevice2;
            _soundDevice3 = soundDevice3;
        }
 
        private readonly ISound _soundDevice1;
        private readonly ISound _soundDevice2;
        private readonly ISound _soundDevice3;
        private ISound _activeSoundDevice;
        public bool SystemPower { get; set; }
        public ActiveDevice DeviceSelector
        {
            set
            {
                switch (value)
                {
                    case ActiveDevice.Audio1:
                        _activeSoundDevice = _soundDevice1;
                        break;
                    case ActiveDevice.Audio2:
                        _activeSoundDevice = _soundDevice2;
                        break;
                    case ActiveDevice.Audio3:
                        _activeSoundDevice = _soundDevice3;
                        break;
                    default:
                        throw new Exception("Device not supported");
                }
            }
        }
 
 
    }
    public enum ActiveDevice
    {
        Audio1,
        Audio2,
        Audio3,
    }
    public interface ISound { }
 
}

Consumer:

using System;
using ComponentizedTheater;
namespace Consumer
{
    class ComplexConsumer
    {
        public void WatchDvd()
        {
            var theater = new HomeTheater (
                new StereoReceiver{SystemPower = false},
                new Tv{SystemPower = false},
                new Dvd{SystemPower = true} );
            theater.SystemPower = true;
            theater.DeviceSelector = ActiveDevice.Audio3;
        }
 
        public void WatchBlueRay()
        {
            var theater = new HomeTheater(
                new StereoReceiver { SystemPower = false }, 
                new Tv { SystemPower = false }, 
                new BlueRay { SystemPower = true });
            theater.SystemPower = true;
            theater.DeviceSelector = ActiveDevice.Audio3;
        }
    }
 
    class StereoReceiver : ISound { public bool SystemPower { get; set; } }
    class Tv : ISound { public bool SystemPower { get; set; } }
    class Dvd : ISound { public bool SystemPower { get; set; } }
    class BlueRay : ISound { public bool SystemPower { get; set; } }
}

 

This is an example of Aggregation

Composed object is not responsible for managing the lifetime of its simpler objects

Consumer class is responsible for constructing the simpler objects

Consumer code  must be more intelligent in that it needs to understand how to instantiate the simpler objects and manage their lifetime

Composed object is more flexible in that consumer may watch a Blue Ray.

 

Which do you use?  The answer of course depends.  If you need something quick or you will never need to modify your home theater, using composition is probably the better choice.  If you know you are going to want to support other devices in the future then take the time to design the system using aggregation.


Posted by: Tim Star
Posted on: 3/6/2011 at 12:56 PM
Categories: .NET
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Subscribe to this BlogRSS comment feed
Contact Us 651-994-8558 1-800-866-9884
Home | Training | Curriculum | Course Finder | Schedule | Enroll | Twin Cities Java User Group | Consulting | Foundation | Jobs | About Us | Our Story | Press Room | Instructors | President | Map & Directions | Sitemap

Java Training | JSF / Struts / Spring / Hibernate Training | Java Power Tools Training | .NET 4.0 & Visual Studio 2010 Training | Microsoft Web Development Training | Prism / MVVM / MEF Training | .NET 3.5 and Visual Studio 2008 Training | .NET 2.0 and Visual Studio 2003 Training | Cloud Computing Training | Ajax / Web Services / XML Training | Groovy and Grails Training | SQL Server 2008 Training | SQL Server 2005 Training | Mobile Development Training | SharePoint 2010 Training | SharePoint 2007 Training | Agile, Process, Analysis & Design Training | Arch/Design Patterns Training | Microsoft Official Curriculum Training | Web Development Training | Ruby Training | Rational Application Developer (RAD) Training | WebSphere Application Server Training | WebSphere Portal Training | WebLogic Training | Boot Camp Training | Project Management Training | C++ Training | Metro / WinRT / Windows 8 Development Training | Retired

Intertech delivers training on-site and virtually serving cities including Phoenix, AZ | San Francisco, CA | Los Angeles, CA | San Diego, CA | San Jose, CA | Washington, DC | Chicago, IL | Orlando, FL | Boston, MA | Duluth, MN | Minneapolis St. Paul, MN | Rochester, MN | Raleigh-Durham, NC | New York, NY | Philadelphia, PA | Austin, TX | Dallas, TX | Houston, TX | Seattle, WA.