From the course: Advanced Selenium: Page Objects and GUI Automation

What are abstractions?

From the course: Advanced Selenium: Page Objects and GUI Automation

Start my 1-month free trial

What are abstractions?

- [Instructor] Abstractions are an important concept for modeling with code, because that's what we're doing when we write automated execution code. We write automated execution code to assert unexpected conditions and we model the requirements that we're trying to meet as assertions. And we model the use of the application in the code that executes the application. To make our code absolutely precise, to make the code clear, easy to read, write, to maintain, we use abstractions. And if you only remember one thing from this course, remember this quote from Dijkstra, " The purpose of abstraction is not to be vague, " but to create a new semantic level " in which one can be absolutely precise." That will guide us through this entire course. Here's a quick example. I haven't shown you any real code or applications but you can probably tell what this test does. We're testing the requirement that we can create a list. And I have a TodoUser, which knows how to perform all the steps for creating a to-do list. Then I have a page object that I can use to check if the list contains the to-do list that I just created. All the implementation is encapsulated in the methods, but we don't really need to know how it is implemented when reading the test, and if we do, then we can just go and read the code. And you can see I have different types of objects, a user and a page object. I'm not trying to create one object to do everything. I want my object to be precise and readable. Here's some coding heuristics that you might have seen: DRY or don't repeat yourself, helps with maintainability. We want to change the code in one place. And abstractions help us do that by having specific objects with methods that we can reuse. For example navigate to a page, so we don't repeat the get methods throughout our tests. Composition over inheritance. You're not going to see much inheritance in the source code for this course. Most of our abstractions are going to rely on composition, creating objects which delegate to something else and are then used from another object. When automating, we need our abstraction layers to be flexible and combined in various ways that we might not anticipate when we first create them. YAGNI; you aren't going to need it. We're going to refactor to abstractions rather than create a framework from scratch. This way we only have what we need and what we have used. Refactoring is a key practice when creating abstractions that are flexible, and model the application we're testing. Readability; abstractions can support us in writing fluent and readable code. They exist so that we can write code at the appropriate level for the test, not so that we have methods and objects that we can reuse. Reuse is a side effect. Single responsibility is important because there will be a temptation to just keep adding methods to abstraction objects. But by reminding ourselves that these objects have a single responsibility, we keep our abstractions precise, and create new abstractions when necessary. A lot of our common abstractions are a result of single responsibility to help us manage drivers or to manage the locators used to find elements on a page, or to represent the actions on a page using page objects, or to represent the domain object like a user for the actions a user can perform on a page. Keeping the purpose tight means we only have to change code for one reason and that helps make the tests readable. Abstractions are used with all types of automating. You've probably used abstractions all the time without thinking about them. All our code from variable names upwards are abstractions. We want them to be readable and encapsulate some sort of semantics to model the application. WebDriver itself is an abstraction. It's an abstraction for a logical browser. We may not know how WebDriver does what it does but we know it models the actions we can use a browser to do. And WebDriver doesn't try to do everything. WebDriver is a logical abstraction which uses physical drivers that know how to interface with specific physical browsers. For example the FirefoxDriver or the ChromeDriver. Now we refactor to abstractions. We don't need to plan abstractions in advance. We will create the code we need, make sure it works and then refactor it to an appropriate abstraction layer. Deciding about how to refactor a code into other classes, is a decision making process. There're no rights and wrongs. Some teams will standardize on one approach, some on others. The aim of this course is to help you understand a range of different options, different approaches, see them in action and think through their pros and cons.

Contents