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

Framework – Your First Framework - Part 2

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
26 Aug 2018CPOL4 min read 3.9K   7   1
In this part, we’re going to look at our DriverSetup and our DriverDispose classes.

In part one, we built our Driver factory class that will allow us to create an instance of a browser driver, depending on the parameter we passed in. This was an important first step, as without this we would have to manually create our browser instance in our tests themselves. By doing it this way, we are able to keep this logic hidden away in our framework and then call our Initialise method with a parameter in either the test or a test setup class. It’s far cleaner and more efficient.

With part two, we’re going to look at our DriverSetup and our DriverDispose classes. This isn’t quite going to be another single class article but we’re not going to see anything too exciting yet, and I promise it’s the last time but we really need to make sure we understand these two classes. These are the two classes that we absolutely must have, after that, everything else we add is just a bonus and improving functionality.

In the following articles, we will look at these extra classes and learn how we can create a framework that will allow us to create brilliantly simple tests.

C#
using OpenQA.Selenium;

namespace AutomationFramework.Engine
{
    public static class DriverBase
    {
        private static IWebDriver WebDriver { get; set; }

        internal static IWebDriver Instance
        {
            get
            {
                if(WebDriver == null)
                {
                    throw new WebDriverException("Webdriver has not been initialised");
                }
                return WebDriver;
            }
            set { WebDriver = value; }
        }
    }
}

This is a simple class. Not really much to it but it’s going to be used virtually everywhere throughout our framework and tests so it’s important we understand it.

Our first line is creating an IWebDriver property that we are going to be using for another property, Instance which is also a IWebDriver. We could just use a single property with simple get and set methods, but because we want to do some exception handling, we’ll do it this way. We’re going to be doing a lot of exception handling throughout the framework. You might be wondering what the internal keyword is. Internal allows us to declare a property or method and use it through the assembly that it’s declared in. This is great for when you want to limit access to the rest of the solution but not be as restricted as you are with private, where it can only be used in the class it’s declared in.

When tests start failing, you want to make sure the cause of failure is as clear as possible, minimising the need to go through and debug every single line of code, which can be an extremely tedious and time consuming process. By adding proper exception handling, you’re able to pass clear messages describing exactly what the error is and what was happening, so when you look at the stack trace, you can straightaway see exactly where the test has failed.

The reason we have made this class static is so that we are able to reference it and the internal property throughout the entire Engine assembly without having to create an object instance. The use of static in this context allows for much cleaner code and given how many times we are going to be referencing our Instance property, it would be a real pain to have to create an object in any class we wanted to use it in.

C#
using OpenQA.Selenium;

namespace AutomationFramework.Engine
{
    public static partial class Driver
    {
        public static void Dispose()
        {
            DeleteCookies();
            Quit();
            DisposeExplicit();
        }

        public static void Close()
        {
            try
            {
                DriverBase.Instance.Close();
            }
            catch(WebDriverException)
            {
                throw new WebDriverException("Failed to close the current window");
            }
        }

        public static void DeleteCookies()
        {
            try
            {
                DriverBase.Instance.Manage().Cookies.DeleteAllCookies();
            }
            catch(WebDriverException)
            {
                throw new WebDriverException("Failed to clean up cookies");
            }
        }

        public static void Quit()
        {
            try
            {
                DriverBase.Instance.Quit();
            }
            catch (WebDriverException exception)
            {
                throw new WebDriverException($"Failed to quit the current instance of the Webdriver.
                                             Message: {exception.Message}");
            }
        }

        public static void DisposeExplicit()
        {
            try
            {
                DriverBase.Instance.Dispose();
            }
            catch (WebDriverException exception)
            {
                throw new WebDriverException
                        ($"Failed to dispose of the current instance of the Webdriver. Message: 
                        {exception.Message}");
            }
        }
    }
}

Just as important as having good setup and initialise methods, is having good dispose methods. We need to make sure that when we are done with our driver instance, that we clean up manage our resource usage, which if not done properly, can quickly mount up over the course of a whole test suite.

You’ve probably noticed the class is a partial class. This is because our Driver class will be split across many different partial classes dealing with many things from element interaction to script invoking. We will cover these in later articles.

These dispose methods are purely wrapper methods for the existing WebDriver methods, they are pretty self explanatory in what they are doing. You might be asking “what’s the point then?”, and it’s a valid question. Again, it’s all about exception handling. You can see in the method we are putting everything in a try catch statement, and then sending clear messages with the cause of failure and the exception messages.

It also allows us to easily access these methods via Intellisense when using our Instance WebDriver object. And that is one of the main goals of our framework of course, to make writing code for our framework, as well as our tests, as simple as possible. A lot of methods might seem like overkill that we cover in later articles, but when you see how they are used, it will all make sense, and you gain an appreciation for those wrapper methods.

So we have covered our basic classes, that are the must haves and the spine of our framework. I know part one and part two were lacking in any exciting code but it really was important that we covered these in detail, as we will be using them so much in the rest of our code that you might not have understood what was going on without that basic understanding. In the next article, we’re going to look at the rest of our partial classes for Driver, which will cover window handling, element interaction and script execution.

The post Framework – Your First Framework Part 2 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

 
QuestionOdd property design. Pin
Paulo Zemek26-Aug-18 11:45
mvaPaulo Zemek26-Aug-18 11:45 
I see that we have a private property WebDriver and an internal property Instance.
Before the { get; set; } construction was allowed, we always had to explicitly declare our fields.
In this particular case, if we make WebDriver a simple field (no get/set) [and maybe also rename it to webDriver, _webDriver or similar] we will do the job.

Usually properties should not be backed up by other properties (which in turn are backed up by fields, even if we don't declare them). Properties should be backed up by fields directly, and the WebDriver is clearly only used as a field, not as a property.

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.