Assertions in a Page Object?

About assertions, the Selenium wiki says this:

[T]he tests, not the PageObjects, should be responsible for making assertions about the state of a page.

There’s a fine point here: the key concept is responsible for.

This means that only the test itself should cause an assertion to be made. But it does not mean that the assertion code must be in the test.

For example, a test might want to verify that the user data displayed in the web page is as expected. The test can do the assertion itself, thus:

# Assume that expected_user is already defined.
# Get actual user from page.
actual_user = user_page.get_user
# Use method in User class to verify.
User.assert_equal(expected_user, actual_user)

If the verification code is refactored into the page object (where it also becomes reusable), the test code can be simpler:

user_page.assert_user_equal(expected_user)

without having to fetch and pass the actual user data.

Cleaner and DRYer, right?

Moreover, when the expected data is static (e.g., table headers), that data would normally be defined in the page object itself, not the test.

So a test might verify table headers with something like:

user_page.assert_table_headers_correct

without having to pass any data (expected or actual) to the page object.

Now that’s really clean and DRY.

So the test framework (for the asserts) is in the Page Object itself or are you using other means to do those checks? How does this bubble up to test runners, like NUnit?

The example web UI testing that’s in my RubyTest project targets GitHub’s own web UI.

In that example framework, the base assert methods (corresponding to NUnit assert methods) are in the Log class. These methods are usually called either by a data object (such as Label) or a page object (such as LabelsPage).

The tests use Ruby gem minitest, and are launched by Rakefiles (Ruby ‘makefiles’).

In the examples, there’s a Tester Tour that includes an example web UI test. The tour begins here.