Tuesday, May 1, 2012

3 Programming Patterns every Test Engineer should know.

I come from the belief that test automation should be as engineered if not more so than the actual code it's testing.  The reason for this is for every feature, you'll have many tests testing the various requirements and edge cases that that feature can experience.  And just like the code, it also needs to be maintained very well in order for those automated tests to prove valuable.

Here are the top 3 programming patterns I feel any automation engineer should know by heart.

1)   The Abstract Factory,
http://pages.cpsc.ucalgary.ca/~kremer/patterns/abstractFactory.html


Abstract factories is probably one of the most useful creation patterns many experienced test engineers will use in any structured framework testing.  This pattern is allows you to specify an interface, to your test, which contains the business flow, can remain the same, then on fixture end implement the small differences that makes the test work.  Many companies will have multiple flavors of the same product.  For example, a business might have a personal edition and a business edition of the same product.  The functionality is the same, but getting to it or the options it takes might be slightly different.

Say you're testing GMail's login.  There's a personal GMail, and a Corporate Gmail.  You can do something like.. Create a IGMailLoginPage interface, then create 2 implementations, 1 for Personal, and 1 for Corporate (they can even inherit from a base, or from each other if similar enough).   Then to instantiate your test fixture, you'll call something like a TestFixtureFactory.getLoginPage(), which will read your config file then return the corresponding test fixture based on your config setting.  From the actual test point of view,  you're just calling the interface, and based on config settings, you can run the same test across the 2 products.

2) The Decorator,
http://pages.cpsc.ucalgary.ca/~kremer/patterns/decorator.html


This programming pattern I have found useful in situations where we need to bolt on additional features and fields to a test fixture.  This is very useful when supporting backwards compatibility in your automated test.
Say you're testing a feature like posting images to a blog.  Then in version 2, they add the additional feature of allowing you to tag your images while you're posting the image.  You want 1 test to handle both version 1 and version 2.  This is where a decorator can be very helpful.  In conjunction with the Abstract factory above, you can use decorators to support the additional functionality introduced in the newer version, then when you want to run the same test on an older version, you can have your factory create the instance without the decorators.  As you create more concurrent versions you need to support, you can add on or subtract decorators as necessary to avoid re-coding shared functionality.

3) Flyweight,
http://pages.cpsc.ucalgary.ca/~kremer/patterns/flyweight.html


In testing, you'll encounter many screens that have shared groups such as a navigation panel or a preview panel.  This pattern allows you to reuse shared functionality between different screens by instantiating them once, and reusing them as much as possible.  This is good for heavy weight automation tools, like many off the shelf native application automation tools, that instantiate proxy objects for the objects they are automated.  This is a very costly operation and not only costs a lot in memory, but also CPU cycles monitoring the objects.  This pattern will allow you to share objects between different screens and avoid the high reinstantiasion costs.


References:
Programming Patterns Overview
http://pages.cpsc.ucalgary.ca/~kremer/patterns/
Contains common programming patterns.

Design Patterns : Elements of Reusable Object-Oriented Software

This was book I read during software engineering back in College.  It still is a useful reference I use as reference when I need a refresher.

No comments: