Today, I like to mention about Page Object Model. It's very well known E2E UI automation framework design. And we can find lots of articles on the web. What I'm trying to discuss today is more about its API and how it evolves.
Page Object Model (POM) by itself has petty good attributes as a framework design. I've been using it for my E2E UI automation for web application and mobile application. I've found some useful things to consider when we start UI automation from scratch using POM and maximize the benefit of POM.
1. Maintain the loosely coupled structure
I think it is critical to make Page Objects loosely coupled with test code. Creation of Page object should be handled in other places and the only coupling test code should have is calling its function. This loosely coupled structure make it easy for PageObject classes adopting new device type or browser type. Strategy Pattern with Factory method is very common for this. This structure ensures new device type or browser type does not impact test case code. Also it helps to handle UI differences for different locale and market/country by using PageObject subclassing. I think this is one of the key aspects which test automation adopting business requirements
2. Do not remove Mix and Match capability
As the automation progresses, it's very common to refactor repeating code. But this refactoring work should not block the flexibility of POM which is Mix and Match. I see this as a very common issue in using POM. "Well, it's repeating many places and we should do it in one place." This actually in many cases makes harder to maintain the test code. I recommend suite level refactoring rather than test base class refactoring(refactor in similar group of test cases). Definitely similar test cases can have duplicate steps. These refactoring should happen in that suite since similar steps may required. If we put these refactored code in test base class for any tests to consume, these refactored code will normally gets more and more complex as new cases/logics are added. And it becomes a burden for maintenance. The beauty of POM is Mix and Match. Refactoring comes after Mix and Match is done when repeating code/steps are identified. Good indicator of this issue is checking the speed of writing a new test cases. Speed of writing new test case should remain pretty much same when Page Objects are well defined. Heavily refactored code make the test case writing slower and vulnerable to unintended side effect.
3. Use IKEA furniture building strategy for Page Object APIs
I got this furniture building strategy from this video. https://www.youtube.com/watch?v=llGgO74uXMI&t=3369s. And I think it has very interesting benefit of using this strategy. This normally benefits when you're in the early phase of developing UI automation using POM. In the early phase of the UI automation with POM, PageObject functions(methods) are implemented based on test cases selected at that time. And sometimes, it's hard to tell if the function defined is specific to that test cases or os generic. And in early phase, you can see some commonalities and duplication among PageObjects. We tend to think to refactor whenever we see duplication in the code. It just comes to us as a uncomfortable feeling not to refactor when we know there is duplicate code. I would say take a deeeeeeeep breath and let it go for a while. I know this can be hard. But try to let enough test cases covered and PageObject API implemented from those cases. And when you think most of important/mostly used APIs(functions) for each PageObject are implemented. No go back to the PageObject class and try to refactor. You'll be surprise how clear it is to refactor code with very clear logic. It's hard to tell how long we should wait. it's your call, but refactoring PageObject class API after a while really make straightforward and effective.
The furniture building strategy is metaphor the speaker used in the YouTube link I added. Basically, you do not want to tighten one side all the way when you build (maybe more correctly ASSEMBLE) the furniture. You let it wiggled a while and you tighten both ends little by little. And when it is pretty stable and clear, you tighten both ends all the way.
I like sharing three points per blog. Have a nice day!
2. Do not remove Mix and Match capability
As the automation progresses, it's very common to refactor repeating code. But this refactoring work should not block the flexibility of POM which is Mix and Match. I see this as a very common issue in using POM. "Well, it's repeating many places and we should do it in one place." This actually in many cases makes harder to maintain the test code. I recommend suite level refactoring rather than test base class refactoring(refactor in similar group of test cases). Definitely similar test cases can have duplicate steps. These refactoring should happen in that suite since similar steps may required. If we put these refactored code in test base class for any tests to consume, these refactored code will normally gets more and more complex as new cases/logics are added. And it becomes a burden for maintenance. The beauty of POM is Mix and Match. Refactoring comes after Mix and Match is done when repeating code/steps are identified. Good indicator of this issue is checking the speed of writing a new test cases. Speed of writing new test case should remain pretty much same when Page Objects are well defined. Heavily refactored code make the test case writing slower and vulnerable to unintended side effect.
3. Use IKEA furniture building strategy for Page Object APIs
I got this furniture building strategy from this video. https://www.youtube.com/watch?v=llGgO74uXMI&t=3369s. And I think it has very interesting benefit of using this strategy. This normally benefits when you're in the early phase of developing UI automation using POM. In the early phase of the UI automation with POM, PageObject functions(methods) are implemented based on test cases selected at that time. And sometimes, it's hard to tell if the function defined is specific to that test cases or os generic. And in early phase, you can see some commonalities and duplication among PageObjects. We tend to think to refactor whenever we see duplication in the code. It just comes to us as a uncomfortable feeling not to refactor when we know there is duplicate code. I would say take a deeeeeeeep breath and let it go for a while. I know this can be hard. But try to let enough test cases covered and PageObject API implemented from those cases. And when you think most of important/mostly used APIs(functions) for each PageObject are implemented. No go back to the PageObject class and try to refactor. You'll be surprise how clear it is to refactor code with very clear logic. It's hard to tell how long we should wait. it's your call, but refactoring PageObject class API after a while really make straightforward and effective.
The furniture building strategy is metaphor the speaker used in the YouTube link I added. Basically, you do not want to tighten one side all the way when you build (maybe more correctly ASSEMBLE) the furniture. You let it wiggled a while and you tighten both ends little by little. And when it is pretty stable and clear, you tighten both ends all the way.
I like sharing three points per blog. Have a nice day!