State management in automation test scenario
The post will give a hint to manage state efficiently and well-organized
Along with well-organized code in a scenario, it is necessary to manage values, especially in End-2-End scenarios. Thus, this post will suggest a flow of those values inside an automation test case.

There are 2 main levels:
- Test level includes all steps related to behavior and verification. The values will be referred to as entities or DAOs.
- Page Objects level, as defined in Martin Fowler's post, includes methods inside a page or fragment/layout of a page.
State
The term state is related to the status of an application during execution. It can be represented by individual values or combined properties to form object(s). In a test case, it is usually created, transferred, updated for business actions, and checked for verification.
Example 01
Let's take a simple example:
@Test
public void happyCase(){
// Arrange
System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
WebDriver driver = new ChromeDriver();
CalculationPage page = new CalculationPage(driver);
int result;
int a = 4;
int b = 6;
int expected = 10;
// Actions
page.sum(a, b);
result = page.getResult();
// Assert
Assert.assertEquals(result, expected)
}
As can be seen from above code, the variables a, b and result are considered as states.
aandbare created and initialized in Arrange stage.- Then these variables are passed to the
sum()method ofCalculationPage - After method consumes variables, it will return
result. - The returned value is compared with the expected value.
Example 02
Let's create a more complicated example. Assume that we have to design a test case to test the payment flow. So let's create some classes below:
// using lombok annotation
@Setter
@Getter
public class TransactionInfo {
private String name;
private String id;
private double amount;
private String note;
private String currency;
}
Then we have test like this:
@Test
public void transactionTest() {
// Arrange
TransactionInfo txn = new TransactionInfo();
txn.setAmount(10000);
txn.setCurrency("USD");
txn.setNote("testing transaction");
WebDriver driver = new ChromeDriver();
TransactionPage txnPage = new TransactionPage(driver);
TransactionResultPage txnResultPage = new TransactionResultPage(driver); // this page will fully display all transaction info
// Act
String txnId = txnPage.make(txn);
txn.setId(txnId);
TransactionInfo actualTxn = txtResultPage.getTransaction();
// Assert
Assert.assertEquals(txn, actualTxn);
}
Now state contains properties of TransactionInfo object. As you can see:
- Some properties of
txnare defined first, in Arrange stage. - Then
txnvariable are passed to methodmake()to get back transaction id and set to theid. - Next is getting a new instance of transaction info in
txtResultPage.getTransaction(). - Finally, compare state
txnwithactualTxn. Because putting assert command in page object is not good practice, so we will get transaction from page object level to test level.
Summary
Hopefully, after observing the 2 examples above, you now have a clear view of state management in automation testing. There are some principles that you can follow:
- State values should live within only 1 test case, because all test cases should be independent of each other.
- State can be created at the beginning of a test case, and added or edited during the test steps.
- State can be shared between steps in a scenario, but should not be shared between pages directly. If you want to transfer state from page 1 (of step 1) to page 2 (of step 2), page 1 should return to step 1, and then step 2 will take state and pass it to page 2.
- Don't: page 1 -> page 2
- Do: page 1 -> step 1 -> step 2 > page 2
- Stage is normally provided by steps and consumed by pages. Sometimes, the state comes from returned values of page object like Example 2 getTransaction().



