Have a look at this test:
HomePage homepage;
ResultsPage resultsPage;
@AfterMethod
public void after() {
resultsPage.close();
}
@BeforeMethod
public void before() {
homepage = new HomePage();
homepage.open();
assertTrue(homepage.isValidPage());
}
@Test
public void totalPriceTest() {
homepage.typePostalCode(postalCode);
homepage.selectRadius(radius);
homepage.selectNearlyNew(selectNearlyNew);
homepage.selectNew(selectNew);
homepage.selectMake(make);
homepage.selectModel(model);
homepage.selectTotalPrice();
resultsPage = homepage.submitSearch();
assertTrue(resultsPage.isValidPage());
assertTrue(resultsPage.countContains(homepage.searchCount()));
assertTrue(resultsPage.isRadiusSelected(radius));
assertTrue(resultsPage.isPostalCode(postalCode));
assertTrue(resultsPage.isMakeSelected(make));
assertTrue(resultsPage.isModelSelected(model));
assertTrue(resultsPage.carFiltersContain(homepage.selectedCarFilters()));
resultsPage.selectTotalPriceLowest();
assertTrue(resultsPage.isSortOrderDescending(false));
}
The test uses a home page that is opened in some way.
In the homepage, multiple fields are populated and then a search is executed.
The test then continues using a results page.
The before() method creates the home page object, opens the home page and checks if it is displayed.
The after() method closes the results page.
The before() and after() methods works for a test that starts on the home page and ends on results page.
But what if we have a test that starts on the home page and ends on details page?
Or starts on the login page and ends on the checkout page?
Because before() opens the home page, all tests must start with the home page.
Because after() closes the results page, all tests must end on the results page.
This is too restrictive and should be avoided by removing any page objects from both test fixture methods (before() and after()).
Lets remember that before() and after() methods should just prepare the test environment so the tests can run in it and clear the test environment after the tests dont need it any longer.
Opening a home page means starting to interact with the application.
All interaction with the application should be in the test method.
before() and after() are test fixtures.
This is what they should do:
A test fixture is a fixed state of a set of objects used as a baseline for running tests. The purpose of a test fixture is to ensure that there is a well known and fixed environment in which tests are run so that results are repeatable. Examples of fixtures:
Preparation of input data and setup/creation of fake or mock objects;
Loading a database with a specific, known set of data;
Copying a specific known set of files creating a test fixture will create a set of objects initialized to certain states.
from https://github.com/junit-team/junit4/wiki/test-fixtures
The test would be better if assertEquals() is used instead of assertTrue.
So instead of
assertTrue(resultsPage.countContains(homepage.searchCount())); assertTrue(resultsPage.isRadiusSelected(radius)); assertTrue(resultsPage.isPostalCode(postalCode)); assertTrue(resultsPage.isMakeSelected(make)); assertTrue(resultsPage.isModelSelected(model));
it should use
assertEquals(resultsPage.count(), homepage.count()); assertEquals(resultsPage.radius(), radius); assertEquals(resultsPage.postalCode(), postalCode); assertEquals(resultsPage.make(), make); assertEquals(resultsPage.model(), model);
Some of the methods can look better.
Can you say what does it mean for a results page to be valid?
assertTrue(resultsPage.isValidPage());
Does valid mean that it can be displayed?
Or that it shows the proper info?
Or that it has results?
Or something else?
For the isSortOrderDescending() method,
assertTrue(resultsPage.isSortOrderDescending(false));
what is the purpose of the false parameter?
It is not clear why false is there so maybe it should not be used.
1. You took before and after from my BaseTest and rest from one of the tests that extend from it. The reason for these before and after in base so 2 test cases we had are separated into what is common between them ( BaseTest) and different (actual Test classes) and as ResultsPage and HomePage extend from same BasePage then one could call results page.close() or homepage.close() which would have same effect
2. isValidPage() is one of best alternatives to something like hasCorrectPageLoaded() or containsPartialUrl()
3. false in last example you said if one looks at actual method header means is sort order descending or not for comparison
I agree my naming is not best
Also, imagine you have 20 test cases which start on some HomePage and end up in Results and there are just a few that end up on DetailsPage . Would you rather have a BaseTest class which handles common steps like opening HomePage or closing browser and have those Homepage->Results tests inherit from it and have Homepage->Results->Details be their own complete classes as exceptions or write each test complete classes thus making future changes lets say to one step in 20 different classes?
The scope of the Test code which I wrote is basically those 2-3 testcases that were assigned per homework not generalizations
before() and after() methods are meant for setting up and clearing the test environment.
creating the home page object, opening the home page, closing the results page is interaction with the application.
BasePage open() method opens browser window . close() closes browser window
HompePage extends from BasePage and has its own open method that adds navigation to the page itself.
I will make changes so no base test methods are used, but from my view it does make a little sense