Recently I was asked my opinion on creating object models for automated UI software testing – do I prefer LFM or POM? There is no right or wrong answer here – because I own a framework for automating Web UI, I’ll speak to this topic from that perspective. POM (Physical Object Model) style models expose the controls on the page and abstract away the details of how those controls are implemented. LFM (Logical Functional Model) style models expose methods that automate the actions the user can take and abstract away all of the details of how those actions are performed. Here is a concrete example that shows how one would write a test case to initiate a search on Bing’s home page:

 

LFM Style:

Logical.Bing.Search(“Michael Cartwright”);

 

POM Style:

Physical.Bing HomePage.SearchTextBox.Text = “Michael Cartwright”

Physical.Bing HomePage.SearchButton.Click();

 

I feel that the “best” object models expose both – what do I mean by “best?” The notion of best must start with the idea that the best object models are the ones that maximize the number of real product bugs found while minimizing the “cost.”  What are the major “costs” of an object model? There is:

 

Cost of an Object Model

1. Up-front cost of writing the model

2. Updating the model as the product changes

3. Writing test cases that use the model

 

The object models that minimize cost over time minimized all three costs - it is cheap to create them, keep them updated as the product changes, and its also cheap to write tests.   One approach to achieving this end is to first expose POM style controls classes that encapsulate all of the controls on a page.  Once all controls are automatable, take any actions that are taken in more than 1 test case and create a LFM style action-based method for that action.  The method will internally use the POM style controls so that  there is not code duplication. So what does this look like?

 

// A class to enable automating the BING home page

public class BingHomePage

{

// A method that will execute a search.  Multiple test cases perform

// this action, so we wrap it into a re-usable method

public void Search(string searchString)

{

this.SearchTextBox.Text = searchString;

this.SearchButton.Click();

}

 

// All of the controls on the Bing home page

public HtmlTextBox SearchTextBox { get; set; }

public HtmlButton SearchButton { get; set; }

}

 

How does this minimize cost over time?

 

2 ways:

1. No duplication of code

a. The two steps required to search are in one place - inside of the Search() method in the BingHomePage class

b. The code for finding the Search text box occurs in one place - its inside of the SearchTextBox property in the class BingHomePageControls

2. Resilient to product changes

a. If the search text box location changes, the only object model change will be to the controls class where the text box is defined. The test cases and action methods in the model will remain unchanged.

b. If the steps required to perform a search change, but the controls on the page do not change, then the tester will only need to update the body of the “Search” method, and all test cases using this method will remain unchanged.

 

Conclusion

While I know that there is no “right way” to write object models, I’ve used this style of model in the past and it served us well.  It was our approach to eliminate duplication of code.  The rule of thumb we followed was to use the reusable LFM style methods for any actions occurring more than once, and use the POM controls for 1-off actions that only occur once. There is significant cost in creating and maintaining this style of model but in my experience it minimizes long term maintenance cost my minimizing code duplication. Recently teams have been exploring ways to generate the controls classes in an automated way, saving tons of time. Please leave comments on this post as I would love to hear what style of object model your team uses, and what you think about this style.

 

Michael

 

Lots of good info in this post came from http://www.teknologika.com/blog/category/watin/