-
Notifications
You must be signed in to change notification settings - Fork 30
Nested steps
Let's pretend we have a test for some products ordering flow:
@Test
void orderProductsTest() {
final Integer productCount = 5;
final Double price = 3.0;
final Double totalPrice = price * productCount;
LOGGER.info("Main page displayed");
OrderingSimulator.logIn();
LOGGER.info("User logged in");
List<String> products = OrderingSimulator.getProducts();
LOGGER.info("Products page opened");
String product = OrderingSimulator.chooseProduct();
LOGGER.info("Product click event");
LOGGER.info(productCount + " products selected");
OrderingSimulator.addProduct(product, productCount);
LOGGER.info(productCount + " products added to the cart");
Assert.assertEquals(5, productCount.intValue());
OrderingSimulator.doPayment(totalPrice);
LOGGER.info("Successful payment");
OrderingSimulator.logOut();
LOGGER.info("User logged out");
}
After running this method with our listener we have next results on the Report Portal page:
Pretty much stuff with different logic is included in the one single test method. So we can move different operations to separate methods:
@Test
void orderProductsTest() {
final Integer productCount = 5;
final Double price = 3.0;
final Double totalPrice = price * productCount;
navigateToMainPage();
login();
navigateToProductsPage();
addProductToCart(productCount);
pay(totalPrice);
logout();
}
public void navigateToMainPage() {
LOGGER.info("Main page displayed");
}
public void login() {
OrderingSimulator.logIn();
LOGGER.info("User logged in");
}
public void navigateToProductsPage() {
List<String> products = OrderingSimulator.getProducts();
LOGGER.info("Products page opened");
}
public void addProductToCart(Integer count) {
String product = clickOnProduct();
selectProductsCount(count);
clickCartButton(product, count);
}
private String clickOnProduct() {
LOGGER.info("Product click event");
return OrderingSimulator.chooseProduct();
}
private void selectProductsCount(Integer count) {
LOGGER.info(count + " products selected");
}
private void clickCartButton(String product, Integer productCount) {
OrderingSimulator.addProduct(product, productCount);
LOGGER.info(productCount + " products added to the cart");
Assert.assertEquals(5, productCount.intValue());
}
public void pay(Double totalPrice) {
OrderingSimulator.doPayment(totalPrice);
LOGGER.info("Successful payment");
}
public void logout() {
OrderingSimulator.logOut();
LOGGER.info("User logged out");
}
Much better, but result on the Report Portal looks the same. So we grouped our logic by methods but we cannot see our grouping on the view. That's a problem. And we can solve it using @Step annotation.
------- Annotation description --------
In Report Portal Step
is a TestItem
without statistics that required for splitting large test methods on multiple parts to provide clear and concise view for them. Steps
have flexible structure and can be put under other Steps
. @Step
annotation consists of 4 fields:
String value() default "";
String description() default "";
boolean isIgnored() default false;
StepTemplateConfig templateConfig() default @StepTemplateConfig;
Field value
of type String
is required for TestItem
name creation using static part, templates provided by user and method arguments:
//static part - "My name is "
//user template - "{number}"
//parameter with name 'number' and for example value = 3
//result: "My number is 3"
@Step("My number is {number}")
public void randomMethod(String number) {
...
}
Field description
of type String
contains TestItem
description value.
Field isIgnored
of type boolean
allows to enable/disable Step
handling for the current method.
Field templateConfig
contains @StepTemplateConfig annotation and required for resulted value template configuration.
So now we can update our test with @Step
annotation and get a view that matches with our grouping:
@Test
void orderProductsTest() {
final Integer productCount = 5;
final Double price = 3.0;
final Double totalPrice = price * productCount;
navigateToMainPage();
login();
navigateToProductsPage();
addProductToCart(productCount);
pay(totalPrice);
logout();
}
@Step
public void navigateToMainPage() {
LOGGER.info("Main page displayed");
}
@Step
public void login() {
OrderingSimulator.logIn();
LOGGER.info("User logged in");
}
@Step
public void navigateToProductsPage() {
List<String> products = OrderingSimulator.getProducts();
LOGGER.info("Products page opened");
}
@Step("Add {count} products to the cart")
public void addProductToCart(Integer count) {
String product = clickOnProduct();
selectProductsCount(count);
clickCartButton(product, count);
}
@Step
private String clickOnProduct() {
LOGGER.info("Product click event");
return OrderingSimulator.chooseProduct();
}
@Step("{method} with {count} products")
private void selectProductsCount(Integer count) {
LOGGER.info(count + " products selected");
}
@Step("{productCount} products added")
private void clickCartButton(String product, Integer productCount) {
OrderingSimulator.addProduct(product, productCount);
LOGGER.info(productCount + " products added to the cart");
Assert.assertEquals(5, productCount.intValue());
}
@Step("Payment step with price = {totalPrice}")
public void pay(Double totalPrice) {
OrderingSimulator.doPayment(totalPrice);
LOGGER.info("Successful payment");
}
@Step
public void logout() {
OrderingSimulator.logOut();
LOGGER.info("User logged out");
}
Results on the Report Portal page:
Now we have a view where we can show/hide required steps by clicking on them.
- Callback reporting
- Nested steps
- Test item attributes
- Test case ID
- Multi-poccess execution