Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / DevOps / testing

Improved Facade Design Pattern in Automation Testing v.2.0

5.00/5 (3 votes)
11 Oct 2015Ms-PL4 min read 11.2K  
Explains in details how to use the Facade Design Pattern in automation tests so that its class to follow the dependency inversion principle.

Introduction

The today’s article is dedicated once again to the Facade Design Pattern. In my previous article on the matter, I showed you how you can utilize the pattern to build more readable tests. Here I am going to present you how to improve further the usage of the facade design pattern. The new version is going to follow the Dependency Inversion Principle. This way you can bring even more abstraction to your test framework and make your tests even more maintainable.

Image 1

Definition Recall

A facade is an object that provides a simplified interface to a larger body of code, such as a class library. It makes a software library easier to use and understand, is more readable, and reduces dependencies on external or other code.

How not to Use Facade Design Pattern

A couple of years ago when I started to use the facade design pattern, I didn’t apply it correctly. The main problem that my teammates and I tried to solve back then was the lack of code reuse in our tests. We succeeded in our quest, and our code started to follow one of the main superb programming principles- DRY Don’t Repeat Yourself.

Image 2

Don’t Repeat Yourself Principle (DRY)

The developer who learns to recognize duplication, and understands how to eliminate it through appropriate practice and proper abstraction, can produce much cleaner code than one who continuously infects the application with unnecessary repetition. Duplication results in increased probability of bugs and adds complexity to the system. Moreover, duplication makes the system more difficult to understand and maintain.

However, there was one significant problem with the initial version of our facades. Back then we were still not using the Page Object Pattern. As a result, the size of our facades’ files got enormous, like thousands of lines of code.

Image 3

In the presented example over 700 lines. This happened because all pages’ elements and framework’s stuff were hidden there.

Because of the large files we had to use a special language feature to solve this. This feature creates regions in the file that you can collapse or expand in the editor.

Initial Version Facade Design Pattern

Below you can find the previously presented example regarding the correct usage of the facade design pattern. The tests’ logic/workflow is encapsulated in the PurchaseFacade class.

C#
public class PurchaseFacade
{
    private ItemPage itemPage;
    private CheckoutPage checkoutPage;
    private ShippingAddressPage shippingAddressPage;
    private SignInPage signInPage;

    public ItemPage ItemPage 
    {
        get
        {
            if (itemPage == null)
            {
                itemPage = new ItemPage();
            }
            return itemPage;
        }
    }

    public SignInPage SignInPage
    {
        get
        {
            if (signInPage == null)
            {
                signInPage = new SignInPage();
            }
            return signInPage;
        }
    }

    public CheckoutPage CheckoutPage
    {
        get
        {
            if (checkoutPage == null)
            {
                checkoutPage = new CheckoutPage();
            }
            return checkoutPage;
        }
    }

    public ShippingAddressPage ShippingAddressPage
    {
        get
        {
            if (shippingAddressPage == null)
            {
                shippingAddressPage = new ShippingAddressPage();
            }
            return shippingAddressPage;
        }
    }

    public void PurchaseItem(string item, string itemPrice, ClientInfo clientInfo)
    {
        this.ItemPage.Navigate(item);
        this.ItemPage.Validate().Price(itemPrice);
        this.ItemPage.ClickBuyNowButton();
        this.SignInPage.ClickContinueAsGuestButton();
        this.ShippingAddressPage.FillShippingInfo(clientInfo);
        this.ShippingAddressPage.Validate().Subtotal(itemPrice);
        this.ShippingAddressPage.ClickContinueButton();
        this.CheckoutPage.Validate().Subtotal(itemPrice);
    }
}

In case the workflow of the test case is changed, it can be quickly updated only in a single place. Or if you want to add additional assertions, they can be added to the PurchaseItem method.

Improved Version Facade Design Pattern

The only issue of the previously presented code is that it doesn’t follow the Dependency Inversion Principle.

Image 4

Dependency Inversion Principle

It suggests that our high-level components (the facades) should not depend on our low-level components (the pages); rather, they should both depend on abstractions.

Find below, the code of the improved version of the facade that holds the logic related to the creation of purchases.

C#
public class ShoppingCart
{
    private readonly IItemPage itemPage;

    private readonly ISignInPage signInPage;

    private readonly ICheckoutPage checkoutPage;

    private readonly IShippingAddressPage shippingAddressPage;

    public ShoppingCart(IItemPage itemPage, ISignInPage signInPage, ICheckoutPage checkoutPage, IShippingAddressPage shippingAddressPage)
    {
        this.itemPage = itemPage;
        this.signInPage = signInPage;
        this.checkoutPage = checkoutPage;
        this.shippingAddressPage = shippingAddressPage;
    }

    public void PurchaseItem(string item, double itemPrice, ClientInfo clientInfo)
    {
        this.itemPage.Open(item);
        this.itemPage.AssertPrice(itemPrice);
        this.itemPage.ClickBuyNowButton();
        this.signInPage.ClickContinueAsGuestButton();
        this.shippingAddressPage.FillShippingInfo(clientInfo);
        this.shippingAddressPage.AssertSubtotalAmount(itemPrice);
        this.shippingAddressPage.ClickContinueButton();
        this.checkoutPage.AssertSubtotal(itemPrice);
    }
}

Through the usage of the pages’ interfaces, the façade follows the Dependency Inversion Principle. You can replace the version of some of the pages without changing even a single line of code in the façades.

The facade combines the different pages’ methods to complete the wizard of the order. If there is a change in the order of the executed actions you can edit it only here. It will apply to tests that are using the facade. The different test cases are accomplished through the various parameters passed to the facade’s methods. You can read how to create these types of pages in my article Page Objects That Make Code More Maintainable

These types of facades contain a much less code because most of the logic is held by the pages instead of the facade itself.

Finally, I want to allude briefly to the name of the facade. It doesn’t contain the word Facade in its name because it should not suggest that it is hiding a complex logic.

So Far in the "Design Patterns in Automated Testing" Series

  1. Page Object Pattern
  2. Advanced Page Object Pattern
  3. Facade Design Pattern
  4. Singleton Design Pattern
  5. Fluent Page Object Pattern
  6. IoC Container and Page Objects
  7. Strategy Design Pattern
  8. Advanced Strategy Design Pattern
  9. Observer Design Pattern
  10. Observer Design Pattern via Events and Delegates
  11. Observer Design Pattern via IObservable and IObserver
  12. Decorator Design Pattern- Mixing Strategies
  13. Page Objects That Make Code More Maintainable
  14. Improved Facade Design Pattern in Automation Testing v.2.0
  15. Rules Design Pattern
  16. Specification Design Pattern
  17. Advanced Specification Design Pattern

 

If you enjoy my publications, feel free to SUBSCRIBE
Also, hit these share buttons. Thank you!

Source Code

 

References:

 

The post Improved Facade Design Pattern in Automation Testing v.2.0 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)