Singleton
Singleton pattern is used in a case where you want to restrict the instantiation of a class to only one object.
The class should not require parameters for its construction. If the creation of a class requires significant resources then a singleton is a suitable solution. It is good that singletons are created when they are first needed, so-called lazy initialization.
Example
Most common usage of Singleton pattern is to limit WebDriver to only one object instance in the whole automation test project.
private static IWebDriver webDriver;
public static IWebDriver WebDriver
{
get
{
if (webDriver == null)
{
webDriver = new FirefoxDriver();
}
return webDriver;
}
}
Null object pattern:
The idea is to make the code simpler and safe by skipping checks for null reference of a given object.
Null object implements given interface and its methods are doing nothing. This makes the null object more predictable. You can safely invoke methods on the null object without the threat of a NullRefferenceException to break your application. This pattern is very well combined with singleton pattern where a null object is actually a singleton. In this case, you can check for reference or equality.
In this post:
I’m going to give slightly different usage example where Singleton is used along with Null object pattern. NullWebElement implements IWebElement interface so it must implement all methods and properties defined by the interface. This is done on lines 4 to 21. Properties are returning some values, but not null! Methods are doing nothing. From line 23 to 36 is the Singleton definition. If Singleton is an object you have defined then it should have a private constructor so no one is able to instantiate it. There is a private field which actually holds the reference to the singleton. NULL is a property which instantiates the singleton if not already instantiated and returns it.
There are two main benefits of code above. The first benefit comes from the Null object pattern. You can locate an element which doesn’t exist and call some of its methods without your tests to crash. You might say that comparing for null is not a big overhead, but in big having a null check before each action is a waste of time.
IWebElement element = null;
try
{
element = webDriver.FindElement(By.CssSelector("notExisting"));
}
catch
{
element = NullWebElement.NULL;
}
element.Click();
It might be a discussion whether it is better to silent this failure error with a null object or leave to a massive crash. My opinion is you must fail the test and if you put some logging into Click method of the NullWebElement then you can easily trace the issue. The real benefit is you will have only one failed test instead of the whole bunch failed because of the crash.
The second benefit comes from the Singleton pattern. You can easily compare some element against the NullWebElement.NULL. Most likely you will locate the element and use it safely because of null object pattern, but there might a case where you want to see if the element is actually not found.
if (element == NullWebElement.NULL)
{
Console.WriteLine("Element not found!");
}
Conclusion:
Singleton is a pattern that you definitely should know. A null object with a combination of Singleton can decrease the amount of code you write by skipping the checks for null. I would say if adopted those can simplify your code which is a benefit in big projects.
Building better QA for tomorrow
Comments