Best Practice handling login and isolating tests?

So this was an issue also with plain TestNG and Selenium, when you were writing scripting your tests how to make them able to run on their own while debugging, and also how to run them say in a test suite with @beforesuit / test ect,

So If I always need to perform login so tests are not reliant on eachother and flaky. Should I just call it in each test case, so If I need to run the test case solo I can just click run and it should pass as expected leaving @beforesuite @beforetest at Suite level empty, besides maybe database stuff.

Or should I put the login at the suite level but then I won’t be able to run the tests fully in isolation, unless I implement test listener.

Thoughts on best practice and what everyone else is using?

Good question :slight_smile:

Of course, there’s never one “right” answer; it often comes down to preference.

I’ve always favored the hermetic approach to test automation, which in simple terms just means that every test case that you write is independent of all other test cases, so that, as you say:

If you structure your project using the Page Object Model, this kind of automation becomes very very easy:

LoginPage loginPage = new LoginPage();
loginPage.setField("Username", username);
loginPage.setField("Password", password);
loginPage.clickLoginButton();
1 Like

Yeah that’s what I decided to do, I’ve come to the conclusion of less is more especially maintenance complexity wise. Even pageobject actions started getting too abstract and annoying, like a whole action for clicking a button, where .click and the element is fine. I guess if you want human readability.

Where people can get crazy abstracting everything away to where you have to have 7 files open to make sense of anything lol

It’s not just about readability. The idea is that if you create a separate method to handle, say, clicking the login button, you can handle all three of the following in one place, and just call the same method in every script without having to worry about:

1.) Element location
2.) Element manipulation
3.) Wait conditions after element manipulation

For example, here’s how my loginPage.clickLoginButton() method from above is implemented:

public void clickLoginButton() {
	KeywordUtil.logInfo("Login Page: Clicking Login button");  // Custom logging
	WebElement element = driver.findElement(By.xpath("//input[@id='btnLogin']")); // Element location
	JQueryUtil.click(element); // Element manipulation (I use JQuery to click the button, in this case)
	WaitUtil.waitForAjax(); // Wait conditions after element manipulation (I wait for all AJAX requests to finish, in this case)
}

This approach (which you say is too abstract) is also far better from a maintenance standpoint. Consider the case when a developer, for whatever reason, changes the DOM, and your locator for the login button element breaks. If you don’t have this locator wrapped up in a page object, but instead locate that element each time in all of your scripts, you will then need to update ALL of your scripts. This is the major reason for using the page object model over any other approach.

The topic of Abstraction may seem like overkill, but over time, you will come to know the importance of it.

1 Like

Wasn’t talking about pageobjects in general just things like pageobject actions of clicking a button or getting text ect, when selenium already has an API for it.

If something break I just update the page object once and it’s updated in all the scripts.

Having clickloginbutton or findelementbyselector.click is the same.

It’s really really not the same, but that’s ok, it sounds like you’ve got a path, may as well stick with it :slight_smile: