Click here to Skip to main content
13,258,269 members (49,693 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

3.7K views
4 bookmarked
Posted 19 Mar 2017

Assessment System for Tests Architecture Design - Facade Based Tests

, 19 Mar 2017
Rate this:
Please Sign up or sign in to vote.
We will use the previously presented assessment framework to evaluate tests that use the Facade Design Pattern. Find the ratings and reasoning behind them.

Introduction

In my previous article, Assessment System for Tests & Architecture Design, I presented to you eight criteria for system tests architecture design assessment. To understand the system fully, I am going to use it to evaluate a couple of real-world examples, assign ratings to them for each criterion and tell you my reasoning behind them. The first type of tests that we will assess is the facade based tests. If you are not familiar with the Facade Design Pattern, you can check my article, Improved Facade Design Pattern in Automated Testing v.2.0.

Facade Based Tests

The initial versions of our tests framework utilized the facade design pattern. This is the first design that we are going to evaluate through the proposed assessment system. A facade is an object that provides a simplified interface to a larger body of code, such as a class library. It makes the software library easier to use and understand, is more readable, and reduces dependencies on external or other code.

Regions in Facades

There are not any real drawbacks, as it provides a unified interface to a set of interfaces in a subsystem. However, the biggest problem for us was the size of the facade files. They got enormous, like thousands of lines of code. We had to use regions inside to separate the different parts of the code. Regions let you specify a block of code that you can expand or collapse when using the outlining feature of the Visual Studio Code Editor. As depicted in the image, in the Billing facade, four different regions were used for separating the element map properties, the private fields, and the rest of the methods.

Improved Facade Design Pattern

This is the code of our shopping cart facade responsible for creating purchases. We decided to use the facade design pattern in a little different way. It combines the different pages' methods to complete the wizard of the order. If there is a change in the order of the executed actions, I can edit it only here. It will apply to tests that are using the facade. The different test cases are accomplished through the different parameters passed to the facade's methods. These types of facades contain much less code because most of the logic is held by the pages instead of the facade itself.

public class ShoppingCart
{
    private readonly ItemPage itemPage;
    private readonly PreviewShoppingCartPage previewShoppingCartPage;
    private readonly SignInPage signInPage;
    private readonly ShippingAddressPage shippingAddressPage;
    private readonly ShippingPaymentPage shippingPaymentPage;
    private readonly PlaceOrderPage placeOrderPage;

    public ShoppingCart(
        ItemPage itemPage,
        PreviewShoppingCartPage previewShoppingCartPage,
        SignInPage signInPage,
        ShippingAddressPage shippingAddressPage,
        ShippingPaymentPage shippingPaymentPage,
        PlaceOrderPage placeOrderPage)
    {
        this.itemPage = itemPage;
        this.previewShoppingCartPage = previewShoppingCartPage;
        this.signInPage = signInPage;
        this.shippingAddressPage = shippingAddressPage;
        this.shippingPaymentPage = shippingPaymentPage;
        this.placeOrderPage = placeOrderPage;
    }

    public void PurchaseItem(
        string itemUrl,
        string itemPrice,
        ClientLoginInfo clientLoginInfo,
        ClientPurchaseInfo clientPurchaseInfo)
    {
        this.itemPage.Navigate(itemUrl);
        this.itemPage.ClickBuyNowButton();
        this.previewShoppingCartPage.ClickProceedToCheckoutButton();
        this.signInPage.Login(clientLoginInfo.Email, clientLoginInfo.Password);
        this.shippingAddressPage.FillShippingInfo(clientPurchaseInfo);
        this.shippingAddressPage.ClickDifferentBillingCheckBox(clientPurchaseInfo);
        this.shippingAddressPage.ClickContinueButton();
        this.shippingPaymentPage.ClickBottomContinueButton();
        this.shippingAddressPage.FillBillingInfo(clientPurchaseInfo);
        this.shippingAddressPage.ClickContinueButton();
        this.shippingPaymentPage.ClickTopContinueButton();
        double totalPrice = double.Parse(itemPrice);
        this.placeOrderPage.AssertOrderTotalPrice(totalPrice);
    }
}

Usage in Tests

This is a sample usage of the facade in tests. First, we need to initialize all required parameters. After that, you simply call the main workflow's method.

[TestMethod]
public void Purchase_ShoppingCartFacade()
{
    var itemUrl = "/Selenium-Testing-Cookbook-Gundecha-Unmesh/dp/1849515743";
    var itemPrice = "40.49";
    var clientPurchaseInfo = new ClientPurchaseInfo(
        new ClientAddressInfo()
        {
            FullName = "John Smith",
            Country = "United States",
            Address1 = "950 Avenue of the Americas",
            State = "New York",
            City = "New York City",
            Zip = "10001-2121",
            Phone = "00164644885569"
        });
    clientPurchaseInfo.CouponCode = "99PERDIS";
    var clientLoginInfo = new ClientLoginInfo()
    {
        Email = "g3984159@trbvm.com",
        Password = "ASDFG_12345"
    };
    var shoppingCart = container.Resolve<ShoppingCart>();
    shoppingCart.PurchaseItem(itemUrl, itemPrice, clientLoginInfo, clientPurchaseInfo);
}

Facade Design Pattern Pros

  • Hide complex logic
  • Simplify tests' creation
  • Workflow's changes- single place

Facade Design Pattern Cons

  • Enormous files
  • Huge constructors
  • Not clear tests' workflow from test's body
  • Affect a large number of tests
  • Hard to orient- new people

Evaluate Facade Based Tests- Assessment System

Maintainability

public void PurchaseItem(
    string itemUrl,
    string itemPrice,
    ClientLoginInfo clientLoginInfo,
    ClientPurchaseInfo clientPurchaseInfo)
{
    this.itemPage.Navigate(itemUrl);
    this.itemPage.ClickBuyNowButton();
    this.previewShoppingCartPage.ClickProceedToCheckoutButton();
    this.signInPage.Login(clientLoginInfo.Email, clientLoginInfo.Password);
    this.shippingAddressPage.FillShippingInfo(clientPurchaseInfo);
    this.shippingAddressPage.ClickDifferentBillingCheckBox(clientPurchaseInfo);
    this.shippingAddressPage.ClickContinueButton();
    this.shippingPaymentPage.ClickBottomContinueButton();
    this.shippingAddressPage.FillBillingInfo(clientPurchaseInfo);
    this.shippingAddressPage.ClickContinueButton();
    this.shippingPaymentPage.ClickTopContinueButton();
    double totalPrice = double.Parse(itemPrice);
    this.placeOrderPage.AssertOrderTotalPrice(totalPrice);
}

The maintainability is Very Good (4). The troubleshooting and adding new features to the facades is straightforward. However, the rating is not marked as Excellent because you can easily introduce a regression in the existing tests with small changes in the facade.

 Facade Based Tests
Maintainability4
Readability-
Code Complexity Index-
Usability-
Flexibility-
Learning Curve-
Least Knowledge-

Readability

var shoppingCart = container.Resolve<ShoppingCart>();
shoppingCart.PurchaseItem(itemUrl, itemPrice, clientLoginInfo, clientPurchaseInfo);

The readability is evaluated as Poor (2). The tests contain much less code compared to all other solutions. However, as you call only a single method from the facade in the tests, it is not clear to the user what this method is doing under the hood. Further, due to their large sizes, the facades are relatively unreadable and it is not an easy job to find something inside them.

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index-
Usability-
Flexibility-
Learning Curve-
Least Knowledge-

Code Complexity Index

The facade classes have a poor (3) index because they are large in size and they depend on lots of other classes such as other facades and lots of pages. On the opposite, the tests' classes are fairly short in size and call only the facade itself.

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index3
Usability-
Flexibility-
Learning Curve-
Least Knowledge-

Usability

var itemUrl = "/Selenium-Testing-Cookbook-Gundecha-Unmesh/dp/1849515743";
var itemPrice = "40.49";
var clientPurchaseInfo = new ClientPurchaseInfo(
    new ClientAddressInfo()
    {
        FullName = "John Smith",
        Country = "United States",
        Address1 = "950 Avenue of the Americas",
        State = "New York",
        City = "New York City",
        Zip = "10001-2121",
        Phone = "00164644885569"
    });
clientPurchaseInfo.CouponCode = "99PERDIS";
var clientLoginInfo = new ClientLoginInfo()
{
    Email = "g3984159@trbvm.com",
    Password = "ASDFG_12345"
};

The usability is Very Good (4). The writing of new tests is straightforward. The rating is not Excellent just because the user has to initialize the tests context upfront.

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index3
Usability4
Flexibility-
Learning Curve-
Least Knowledge-

Flexibility

public void PurchaseItem(
    string itemUrl,
    string itemPrice,
    ClientLoginInfo clientLoginInfo,
    ClientPurchaseInfo clientPurchaseInfo)
{
    this.itemPage.Navigate(itemUrl);
    this.itemPage.ClickBuyNowButton();
    this.previewShoppingCartPage.ClickProceedToCheckoutButton();
    this.signInPage.Login(clientLoginInfo.Email, clientLoginInfo.Password);
    this.shippingAddressPage.FillShippingInfo(clientPurchaseInfo);
    this.shippingAddressPage.ClickDifferentBillingCheckBox(clientPurchaseInfo);
    this.shippingAddressPage.ClickContinueButton();
    this.shippingPaymentPage.ClickBottomContinueButton();
    this.shippingAddressPage.FillBillingInfo(clientPurchaseInfo);
    this.shippingAddressPage.ClickContinueButton();
    this.shippingPaymentPage.ClickTopContinueButton();
    double totalPrice = double.Parse(itemPrice);
    this.placeOrderPage.AssertOrderTotalPrice(totalPrice);
}

The flexibility is Very Poor (1). If you change some of the existing workflows, you will affect all existing tests and possibly create regression issues. If you need to create custom workflow you have to add custom public workflow method which makes the already large facade even bigger. You cannot change or customize the already constructed workflows on a test level.

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index3
Usability4
Flexibility1
Learning Curve-
Least Knowledge-

Learning Curve

var itemUrl = "/Selenium-Testing-Cookbook-Gundecha-Unmesh/dp/1849515743";
var itemPrice = "40.49";
var clientPurchaseInfo = new ClientPurchaseInfo(
    new ClientAddressInfo()
    {
        FullName = "John Smith",
        Country = "United States",
        Address1 = "950 Avenue of the Americas",
        State = "New York",
        City = "New York City",
        Zip = "10001-2121",
        Phone = "00164644885569"
    });
clientPurchaseInfo.CouponCode = "99PERDIS";
var clientLoginInfo = new ClientLoginInfo()
{
    Email = "g3984159@trbvm.com",
    Password = "ASDFG_12345"
};
var shoppingCart = container.Resolve<ShoppingCart>();
shoppingCart.PurchaseItem(itemUrl, itemPrice, clientLoginInfo, clientPurchaseInfo);

There are two tricky parts with the approach. First, you should know how to initialize the test context correctly. Secondly, if there are multiple public workflow methods, you should be aware which is the most appropriate to call.

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index3
Usability4
Flexibility1
Learning Curve3
Least Knowledge-

Least Knowledge

var itemUrl = "/Selenium-Testing-Cookbook-Gundecha-Unmesh/dp/1849515743";
var itemPrice = "40.49";
var clientPurchaseInfo = new ClientPurchaseInfo(
    new ClientAddressInfo()
    {
        FullName = "John Smith",
        Country = "United States",
        Address1 = "950 Avenue of the Americas",
        State = "New York",
        City = "New York City",
        Zip = "10001-2121",
        Phone = "00164644885569"
    });
clientPurchaseInfo.CouponCode = "99PERDIS";
var clientLoginInfo = new ClientLoginInfo()
{
    Email = "g3984159@trbvm.com",
    Password = "ASDFG_12345"
};
var shoppingCart = container.Resolve<ShoppingCart>();
shoppingCart.PurchaseItem(itemUrl, itemPrice, clientLoginInfo, clientPurchaseInfo);

The facade has access to the whole test context which is usually enormous in size. Not all methods need all of the information present in the test context. Because of that, the rating is marked as poor (2).

 Facade Based Tests
Maintainability4
Readability2
Code Complexity Index3
Usability4
Flexibility1
Learning Curve3
Least Knowledge2

In my next article from the series, I will use the assessment system to evaluate the behavior based tests.

You can watch my conference talk dedicated to the system or download the whole slide deck.

Design & Architecture

The post Assessment System for Tests Architecture Design- Facade Based Tests appeared first on Automate The Planet.

All images are purchased from DepositPhotos.com and cannot be downloaded and used for free.
License Agreement

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Anton Angelov
CEO Automate The Planet
Bulgaria Bulgaria
Anton Angelov is an IT Consultant and Quality Assurance Architect at Innovative Lab. He is passionate about automation testing and designing test harness and tools, having the best industry development practices in mind. In addition, he is an active blogger and the founder of Automate The Planet. He strives to make the site one of the leading authorities in Automation Testing by presenting compelling articles, inspiring ardent discussions amongst the community. He is also one of the most-rated-answer authors of questions about Test Automation Frameworks (WebDriver) on Stack Overflow.

You may also be interested in...

Comments and Discussions

 
QuestionSnippets Pin
Nelek19-Mar-17 20:57
protectorNelek19-Mar-17 20:57 
AnswerRe: Snippets Pin
Anton Angelov20-Mar-17 11:28
mvpAnton Angelov20-Mar-17 11:28 
GeneralRe: Snippets Pin
Nelek20-Mar-17 20:57
protectorNelek20-Mar-17 20:57 
GeneralRe: Snippets Pin
Anton Angelov20-Mar-17 23:58
mvpAnton Angelov20-Mar-17 23:58 
GeneralRe: Snippets Pin
Nelek21-Mar-17 2:32
protectorNelek21-Mar-17 2:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171114.1 | Last Updated 20 Mar 2017
Article Copyright 2017 by Anton Angelov
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid