Click here to Skip to main content
15,881,173 members
Articles / Programming Languages / C#
Article

Design Pattern – Facade

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
26 Aug 2018CPOL3 min read 5K   3  
Design pattern - Facade

In the last article of this series, we learnt how to write tests using the Page Object Model design pattern. It allowed us to create a test with minimal code, keeping all the actions and element interactions in our page object class itself. This works brilliantly with web applications that have no set journey they have to follow, but in instances where you do have these journeys, it can often mean you start to lose the benefit of the Page Object Model inside your tests. To get around this, there is another design pattern that we can look at, the Facade pattern.

We touched upon it briefly in the very first article of the series, but let’s expand upon what it is by using an example. Take your favourite online retailer, whenever you add something to your basket and go to checkout, you pretty much always follow the same journey, no matter the site. Enter your details, your delivery details, your payment details, then finally confirm. Now if we were to write a test to make sure the checkout journey is working correctly, and we wanted to use the Page Object Model. Our page object classes would still be as efficient as before, but the trouble with this is that we are navigating across multiple pages, we now have to create an object for each of our pages, and then use different objects depending on the page we’re using. Suddenly, our nice and simple tests become a little more complicated. Let's look at a code example to see how this might look.

For this example, we have created a page object class for PersonalDetailsPage, DeliveryDetailsPage, PaymentDetailsPage and ConfirmationPage.

C#
[Test]
public void CustomerCanCompletePurchase()
{
	PersonalDetailsPage personalDetailsPage = new PersonalDetailsPage(this.Driver);
	DeliveryDetailsPage deliveryDetailsPage = new DeliveryDetailsPage(this.Driver);
	PaymentDetailsPage paymentDetailsPage = new PaymentDetailsPage(this.Driver);
	ConfirmationPage confirmationPage = new ConfirmationPage(this.Driver);
	
        personalDetailsPage.EnterPersonalDetailsAndProceed();
	deliveryDetailsPage.EnterDeliveryDetailsAndProceed();
	paymentDetailsPage.ChoosePaymentMethod(PaymentType.CreditCard);
	paymentDetailsPage.EnterPaymentDetails();
	Assert.IsTrue(confirmationPage.ConfirmOrderDetails(), 
                      "Order details did not match the expected ones");
}

As you can see, suddenly we are having to create four objects just for our test to be possible, and then we switch between objects dependent on the page we’re currently on. We could, of course, break these tests into smaller tests for each page, but this becomes a very fragile set of tests when they all rely on each other.

So how does Facade get around this problem? Well, Facade doesn’t do anything radical, in fact, it will keep our individual page objects classes exactly as they are. We simply add a new class that wraps all these classes up into one that is designed to deal with this checkout journey.

C#
public class PurchaseFacade
{
    private PersonalDetailsPage personalDetailsPage;
    private DeliveryDetailsPage deliveryDetailsPage;
    private PaymentDetailsPage paymentDetailsPage;
    private ConfirmationPage confirmationPage;

    public PersonalDetailsPage PersonalDetailsPage 
    {
        get
        {
            if (personalDetailsPage == null)
            {
                personalDetailsPage = new PersonalDetailsPage();
            }
            return personalDetailsPage;
        }
    }

    public DeliveryDetailsPage DeliveryDetailsPage
    {
        get
        {
            if (deliveryDetailsPage == null)
            {
                deliveryDetailsPage = new DeliveryDetailsPage();
            }
            return deliveryDetailsPage;
        }
    }

    public PaymentDetailsPage PaymentDetailsPage
    {
        get
        {
            if (paymentDetailsPage == null)
            {
                paymentDetailsPage = new PaymentDetailsPage();
            }
            return paymentDetailsPage;
        }
    }

    public ConfirmationPage ConfirmationPage
    {
        get
        {
            if (confirmationPage == null)
            {
                confirmationPage = new ConfirmationPage();
            }
            return confirmationPage;
        }
    }

    public bool CompletePurchase()
    { 	
	    personalDetailsPage.EnterPersonalDetailsAndProceed();
	    deliveryDetailsPage.EnterDeliveryDetailsAndProceed();
	    paymentDetailsPage.ChoosePaymentMethod(PaymentType.CreditCard);
	    paymentDetailsPage.EnterPaymentDetails();
	    return confirmationPage.ConfirmOrderDetails();
    }
}

I’m sure you’ve noticed that our CompletePurchase method looks identical to our test, but that’s the beauty of Facade in a situation like this. Suddenly, we have a method to deal with our whole journey, so in our test we have to simply call this one method using a single object of our PurchaseFacade class. And now, we’re right back to having a simple test like we had in the previous article.

But just to stress how simple it is, here’s our new test. Doing the exact same thing as the previous test using four objects, but now using our Facade class.

C#
[Test]
public void CustomerCanCompletePurchase()
{
	PurchaseFacade purchaseFacade = new PurchaseFacade(this.Driver);

	Assert.IsTrue(purchaseFacade.CompletePurchase(), 
                      "Order details did not match the expected ones");
}

Isn’t it simple?

The beauty of Facade is that it can condense tests that navigate across multiple pages into a single class. But I’m going to stop short of recommending it all the time. I think the use case has to warrant a Facade design pattern. There’s no point having Facade classes for every possibly journey a customer might follow in your system, as then you start having overlap in your classes and it just becomes bad design. Think of the scenarios that it might benefit from the most. Journeys like a customer purchase, sign up to a website or applying for a service. These are a few examples where it makes sense and could be used.

But now you understand what Facade is and how it can benefit your tests. In the next article, we’ll look at the Factory design pattern and how that can work to handle dynamic content in tests.

The post Design Pattern – Facade appeared first on Learn Automation.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO Steed Solutions Ltd
United Kingdom United Kingdom
I’ve been in the software industry for over 10 years now. Graduating from university with a 1st in Computer Science, I accidentally found myself in a software testing career instead of the development career I intended. But that was no bad thing… I quickly learned that via test automation, I still got to do all the coding and technical things that I loved. And I’ve loved it since.

My first role was developing test scripts in VB in a QTP framework, and from there, quickly moved in to roles where I was developing frameworks in C# for companies that had no previous automation in place. Fast forward to where I am now and I am freelancing as an automation consultant, going in to companies to build frameworks or provide support and expertise to those who already have automation in place.

Comments and Discussions

 
-- There are no messages in this forum --