Skip to main content

Command Palette

Search for a command to run...

Do not put assertions in Page Objects, why?

It is not a good practice when placing assertions in Page Objects.

Published
3 min read
Do not put assertions in Page Objects, why?

If you search for best practices for page object model in automation tests, you will find that many people suggest not using verify commands in Page Object (PO) methods. However, there are no any details' explanation to the reasons. Even the post on https://martinfowler.com/bliki/PageObject.html doesn’t clarify the issue.

I favor having no assertions in page objects. I think you can avoid duplication by providing assertion libraries for common assertions — which can also make it easier to provide good diagnostics. [3]

3: One form of assertions is fine even for people like me who generally favor a no-assertion style. These assertions are those that check the invariants of a page or the application at this point, rather than specific things that a test is probing.

My goal with this post is to clarify the reasons behind this suggestion based on my experience and to help you to understand it more clearly.

Bullet No. 1

We should define a specific responsibility for each layer in our automation project architecture. According to my last post, assertion commands are normally placed in the test layer. However, if they are also placed in the page object layer, there is a mixture of verification functions in 2 layers. That situation should be avoided.

Test layer and Business Layer

Bullet No. 2

You can consider methods implemented at Page Objects like APIs that communicate between client (test scenario) and server (System Under Test — SUT). These methods are usually carrying the requests (and parameters) from test layer, to automatically interact with SUT. Then they can get values from SUT and return to test layer for verification purpose. Obviously, you have never seen any APIs contains verification, don’t you? Page object methods like APIs

Bullet No. 3

The last reason is also a complicated case that you might encounter if you put assertions at the PO level. Problem

Since PO methods are reusable, let’s consider the case where 2 tests use the same PO method, but that method contains verification commands for only 1 test. If that verification is failed, what will happen to these test cases? Both are failed, but:

  • Test01 is fine because the test purpose is covered.
  • For Test02, it’s not fine because its checkpoints are not checked. Main checkpoints may come after another PO method is called. Therefore, the checkpoints for Test02 are not covered, and we will waste time checking whether the failure is related to Test02.

Solution

To resolve Test02 problem, we should put assertion commands in proper test cases. As the result, we will have below advantages:

  • Tests are atomic: each test has its own checkpoints
  • The checkpoints are all visible at the test level so that a reviewer can see the whole test without digging into the lower layers.
  • Reduce execution time: if the verification needs to get data from the SUT, time will vary based on the number of times the PO method is used, and the connection between the test and cloud services.

Summary

With the 3 bullets above, hopefully now you have a much better understanding of why assertion commands should be placed outside of Page Objects. In addition, it’s vital to remember that separated responsibility applies not just to methods, but also to layers in architecture.

Cover Photo by freestocks on Unsplash

R

Bullet No. 1: If you place verification functions in the Page object, They will still be used/called in the test layer.

You can either implement your assertions in the PO or in some utils folder. Both cases you still only call those methods in the test layer. So there's never a mixture of verifications functions in 2 layers.

Implementing verifications functions in the test layer is more bad practice. Bloated code which makes the tests difficult to read. Not really a PO issue.

Bullet No.2: I see verification functions in page object as an API's schema because when i access the PO i know these are the verification functions available to me on that page. Its more like an api schema, telling you what's available on that api.

Bullet No.3 A Page object verification is verifying something on a page. Not verifying a particular test. So you shouldn't have "verify for test01" in a PO, it should be "verify component01". Then use that verify in your test layer.

T
Tan Do3y ago

Thank you for your comments. It gives me more points of view in using assertions commands.

I would like to discuss with some of your opinions.

  • Mixture of verification is still there if you use assertions in both PO and Test level, even these assertions are wrapped in any utils method or class.
  • As I mention in my post(s), we should define a responsibility for each layer of our code. PO should have only its own responsibility, that is, to describe the business actions or flows.
  • You mentioned PO like API schema, I think it’s not appropriate. I think PO method like API, and its parameter should be like the API schema and returned values as the API responses.
  • "Verify component01" I’m not sure whether it is for a specific test case? If not, I think it should not appear in the code.
  • "verify for test01" means some lines of code will check according to the purposes of the test. And the purpose includes verifying something on a page, and others.

From my point of view,

  • Test will be presented like a user story (template “As a [persona], I [want to], [so that].”, or GIVEN WHEN THEN). Of course, it could include some additional information as well.
  • The assertions commands (or wrapped utils methods) would be the implementation of "so that" or "THEN" clause. It should be appeared on test level for easy understand and review.
  • If you put verification to lower layer, reviewers have to navigate to many places to understand fully your checkpoints of test case.
1
R

Hi Tan, I have a short article here of what i mean by PO being like a schema : medium.com/@rforjoe/cypress-pom-factory-557a979951c5

response in the test is just pass or fail. Doesn't return any data.

The verification in the PO or Util is just the method implementation. It doesn't do anything until it is called by a test.