Workflow Test Pattern
A workflow pattern enables to turn customer journies of the application into reusable workflows. Once the workflows are defined, adding test cases is as simple as calling a workflow and asserting the outcomes.
Page Object Model
Page Object Model provides an abstraction for a page (a webpage or mobile screen). The workflow pattern could then be leveraged on top of POM to build workflows that represent a user journey
The workflow pattern components
- UseCase
- WorkFlowDefinition
- WorkFlowDoc
UseCase
UseCase has two purposes
Acts as a data structure to store test data for the current test.
a. Exposes a method to add test dataaddToUseCase(Object data)
b. Exposes a method to retrieve test data<Q> Q getData(Class<Q> tClass)
Stores the current state of the application.
Workflow Definition
A workflow definition defines a portion of the customer journey. A workflow definition offers following functions
Get the page/screen object for the current work definition by means of
create()
methodDefine the criteria to go to the next workflow definition by means of
fulfillCondition()
- fulfillment criteria is to move to the next page/screen in the workflow / customer journeyProceed to the next workflow definition by means of
next()
method - next page/screen in the workflow / customer journey
WorkflowDoc
A workflow doc is the blueprint of your customer journey. It ties workflow definitions to construct end-to-end customer journies.
Sample app with workflow
A typical Buy a product worklow has below steps
- Login
- Add product to cart
- Navigate to cart to review products
- Checkout
- Order confirmation
Workflow test
A test with the workflow pattern looks like below code.
@Test(groups = "mobile")
public class PurchaseTests extends MobileTest {
@Inject LocaleClient localeClient;
@Inject private UseCaseGenerator useCaseGenerator;
public void purchaseProductAndValidate() {
UseCase happyPathCase = useCaseGenerator.happyPathCase();
new BuyAProductDoc(happyPathCase)
.confirmation()
.create()
.getConfirmationDetails()
.orderConfirmed(localeClient.getLocale("confirmation_messages",
ConfirmationDetails.class));
}
}
WorkflowDoc
The workflow doc for the above workflow.
public class BuyAProductDoc extends WorkflowDoc {
public BuyAProductDoc(UseCase useCase) {
super(useCase);
}
// Entry workflow
public LoginDefinition login() {
return new LoginDefinition(useCase);
}
// Keep building on top of that
public ProductsDefinition products() {
return login().next();
}
public CartDefinition cart() {
return products().cart();
}
public MenuDefinition menu() {
return products().menu();
}
public CheckoutDefinition checkout() {
return cart().next();
}
public ConfirmationDefinition confirmation() {
return checkout().next();
}
}
Workflow definition
A workflow definition for Login
public class LoginDefinition extends WorkflowDefinition {
public LoginDefinition(UseCase useCase) {
super(useCase);
}
protected FulfillCondition<LoginDefinition> loginCondition =
() -> {
create().login(useCase.getData(Credentials.class), LoginScreen.class);
return this;
};
@Override
public ProductsDefinition next() {
return proceedToNext(loginCondition, new ProductsDefinition(useCase));
}
@Override
public LoginScreen create() {
return Screen(LoginScreen.class);
}
}
Complete Code
The complete code is available here