The Power of Test Libraries in Automation (Part-1)

We all are aware of the test-library concept and might have implemented it in our line of work, but not many actually understand their power and how could they be leveraged for designing test-automation frameworks. In the following article, I am trying to walk you through the aspects and features of a test-library and it’s implementation.

The libraries are a crucial design element of any automation framework

What are Test Libraries ?

The concept of test-libraries state that you separate out product functionalities that are common in your tests and place it in shared placeholders so that the same could be used by other tests. This concept is primarily applied while designing automation frameworks for testing any software product and it has proved to be a crucial feature of any testing framework in regard to its re-usability and scalability.

A Library here could be a class containing certain common methods or even a package containing multiple classes with such methods.

For the rest of this topic, we will refer to its implementation in Java but this is a concept which is generic and therefore could be applied to any programming language.

Design

A Library here could be a class containing certain common methods or even a package containing multiple classes with such methods. The central idea here is to break the tests into separate reusable components and logically group them into classes containing methods based on product use-cases, behaviour and various other criteria.

The test library methods should not contain assertions or any sort of verification of data etc and should ideally return the response data or object back to the test-method to carry out the verification.

A Library and An Utility

Should your library contain generic and common functions such as reading/writing test data, connection to database etc. ? NO.

It is important to note that the library contains methods which are pertaining to the functionality of the product and not the helper routines which are ideally placed under utilities. For e.g. let’s say a common method to generate a current timestamp as a string or a routine to connect to a database and execute SQLs etc. are helper methods which are not directly related to the product functionality and which qualify as a utility. Therefore, they  definitely need not be part of a test library. A library method could use a utility method based on the need, but vice-versa should not be applicable.

Aspects

While designing such library methods, following are the key aspects that needs to be kept in mind, only then we can use the power of libraries in our framework –

A. Minimal – The implementation of a library method should be minimal in nature w.r.t the product functionality being implemented. The reason being, if a method is too complex or performs a complex product operation, chances of it being re-used by other tests become less likely as it may not serve the particular test’s objective. However, having said that, they still should be discreet and complete in their nature.

B. Self-Sufficient – The library methods would need to be self-sufficient. They could be using other helper utilities and may have a requirement to use other library methods as well. However, they should not ideally have a hard dependency on another library method, and even if it is unavoidable, it should be carried out carefully. Although this may not have an impact immediately, but one of the features of libraries include sharing of these methods as SDK jars (discussed later) and unforeseen issues could arise in that case.

One of the biggest advantages of libraries is that these libraries could be shared & published across different areas of the product, to different teams etc. 

C. Re-Entrant – The library methods need to be re-entrant in their behavior. They should leave the product or the environment back in the same state as before or an acceptable state that allows other tests also to enter and perform the operation. A method which does not meet this criteria is best suited to be placed outside the library.

D. Static Methods – Having a library method defined as a static function eases its use and removes the overhead of initializing or creating an instance every-time in the test. However, one may need to be careful in a multi-thread test execution environment, specially if there is any shared data or objects.

there should not be any cyclic dependency between the tests and library methods.

E. Assertions / Verification – The test library methods should not contain assertions or any sort of verification of data etc.. Instead, they should return the response data or object back to the test-method to carry out the verification. The library method is a reusable component which facilitates certain operation or action and thus it could be used by any test, which could be positive or a negative. Therefore, if assertions are placed from a positive standpoint, the method might not work for a negative test.

For e.g. if we define a method to get the status of micro-service and it asserts the value to be UP, such a method cannot be used for an use-case of checking if the micro-service is DOWN & then trying to bring it UP as the assertion will always generate an exception in the first place.

one of the aspects discussed above that can really enhance the re-usability is ‘overloading‘ of the library methods.

F. Overloading & Default behaviour – The test library methods in a class (library) could be overloaded frequently to provide an easier way of using the methods in the tests. After all, one of the objectives of a framework is to provide easy usage of common functionality and which could be achieved by assigning a default behaviour with zero or minimal inputs to the library methods.

For e.g. a login routine for an application could be overloaded to provide a flexible way of invocation. Therefore a fellow automation engineer, could use any of the methods, mostly, the default credentials ones which remove the over-head of fetching the credentials first and passing it to the login routine if the credentials are mostly the same.

 //Using default credentials
public static void login(){}

//Using user-defined credentials
public static void login(String username,String password){} 

Tip: It’s always recommended that as an automation engineer, you could implement at least some of the overloaded methods right-away while scripting the tests based on your analysis of the requirements.

G. No-Cyclic Dependency – The test library methods need to be defined in such a manner that only the tests depend upon the library methods and not vice-versa i.e. there should not be any cyclic dependency between the tests and library methods.

cyclicdependency

Thus the test-library stands as a concept which is independent of the programming language, interface or the platform being used. The above aspects are not too hard and fast but are definitely recommended. It not only enhances certain features (discussed below) of the framework but they also set certain guidelines which if followed by the automation team members, helps maintain the quality of the framework.

A library method could use a utility method based on the need, but vice-versa should not be applicable.

How do the libraries power the framework

The libraries are a crucial design element of any automation framework. Some of the features mentioned below may exist in your framework but I am trying to illustrate here, how a correct implementation according to the aspects defined above can boost these features altogether –

A. Re-usability & Flexibility – This is a very fundamental principle of programming and I am quite sure that it might be already implemented in your framework in one or the other ways. However, one of the aspects that can really enhance the re-usability is ‘overloading‘ of the library methods. Often, engineers do write methods as a common routine but with a long argument list or mandatory inputs, which increases the over-heads at the test end. In such a case, for every test you may need to procure the input data and pass it to the library methods every time even if it is the same for all tests. This could be avoided if a default behaviour is associated with the methods, which could function for zero or very minimal inputs. Thus, your library could offer a number of overloaded methods which take zero as well as maximum inputs and thus offer a lot of flexibility for the automation engineer who is scripting the new test cases.

B. Scalability and Maintainability – The key to implementation of a library is its logical segregation of the code based on either the product functionality or any other factor applicable in your case. Thus, it allows a rapid turn around of scripting new test-cases since the common components are already made available in form of library methods, thereby improving the scalability of the framework too. From a long-term standpoint, since the common components are separate from the tests and laid out in a logical fashion, changes to the product are therefore centralised to the libraries only or in case of new features, library methods or classes could be updated accordingly.

C. Sharing & Publishing – One of the biggest advantages of libraries is that these libraries could be shared & published across different areas of the product, to different teams etc. as an SDK jar or it’s equivalent. For instance, they could be shared by a Functional QA team, System-testing team, Integration team, Performance team etc. as they are merely methods that facilitate an action/operation over the product and therefore they could be inter-operated and used by fellow members. An important aspect of the library which is ‘No Assertions/Verification‘ is key here since a team can have different objectives for the tests and therefore placing assertions in the library methods may hinder them from using your shared methods. Thus, assertions should be avoided in the lib-methods.

Part-Conclusion

I will be discussing about how these Libraries could be used for Web-Services Testing (REST) and GUI Testing in the 2nd part. However, I have tried to mention the essentials aspects and features of the test-library concept in an effort to provide certain recommendations that may be helpful while designing and implementing such a framework.

After all, it’s all in the design !!!

I welcome all suggestions and feedback, and please do write to me with your opinions and I would certainly try to improve this article. Thanks.

Even though I have written this article from my experience, research and knowledge, I have also observed that such concepts are very generic and act as a baseline only, as they absolutely depend upon case-to-case, product-to-product and therefore it’s the automation engineer’s decision that counts whether he/she is able to truly use these concepts to its potential – because after all, it’s all in the design. 🙂

GOOD LUCK !!!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: