Skip to content

Nested steps

Ivan edited this page Dec 4, 2019 · 11 revisions

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:

logs

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:

nested

Now we have a view where we can show/hide required steps by clicking on them.

Clone this wiki locally