Best practice, according to most sites I've seen, is to keep the asserts out of the page objects. One example is below from the Selenium docs.
http://www.seleniumhq.org/docs/06_test_design_considerations.jsp#page-object-design-pattern
There is a lot of flexibility in how the page objects may be designed, but there are a few basic rules for getting the desired maintainability of your test code.
Page objects themselves should never make verifications or assertions. This is part of your test and should always be within the test’s code, never in an page object. The page object will contain the representation of the page, and the services the page provides via methods but no code related to what is being tested should be within the page object.
There is one, single, verification which can, and should, be within the page object and that is to verify that the page, and possibly critical elements on the page, were loaded correctly. This verification should be done while instantiating the page object. In the examples above, both the SignInPage and HomePage constructors check that the expected page is available and ready for requests from the test.
The page object should return things like product name, product price, currently selected quantity, and so on. The test code would then assert that the returned string matches what is expected.
assert_message()
would become getMessage()
and return the message as a String
. See below.
public String getMessage()
{
return driver.findElement(messageLocator).getText();
}
(NOTE: read on for why I've changed the PageFactory
element to a locator here.)
and then in your test code, you would have
Assert.assertEquals(editPost.getMessage(), "Post published. View post");
Now you've kept the assert code in your test script and out of the page object.
Looking at your code, I would make some further recommendations.
I would suggest you read up on some Java naming conventions. There are a number of sites that have recommendations and I think there are a lot of similarities between them but here's the oracle recommendations to start with. Your method names should be
verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.
So assert_message()
would turn into assertMessage()
and so on. The _s make it look more like python.
Order of preference for locators: ID, CSS selector, and in rare circumstances, XPath. ID should always be your first choice because it (by W3C definition) should be unique on the page. CSS selector should be next because it's the fastest (in my testing faster than ID), has the best browser support, and is most consistently implemented across browsers. XPath should be reserved only for things that cannot be done by CSS seletors like finding an element by contained text. XPath locators are poor performers compared to CSS selectors and do not have the same level of support as CSS selectors. For example, your XPath locator can easily be converted to a CSS selector, "#message > p".
Here are some CSS selector references to get you started.
CSS Selectors reference
CSS Selector tips
Drop PageFactory
. Yes, it seems to make things easier but I think in many situations it causes more problems, like stale element exceptions and the like. Prefer instead to scrape the page as needed. Declare all locators at the top of the class and use them in methods when needed.
public class EditPost {
WebDriver driver;
By messageLocator = By.cssSelector("#message > p")
public EditPost(WebDriver editPostDriver)
{
this.driver = editPostDriver;
}
public String getMessage()
{
return driver.findElement(messageLocator).getText();
}
}
I know this is more than you asked but hopefully it's helpful.