Serenity BDD

website·Indexed 29 days ago

https://serenity-bdd.github.io/

A Java test automation library for writing clean, readable, and scalable acceptance tests. It features the Screenplay Pattern, living documentation, and detailed reporting. Supports integration with JUnit 4, JUnit 5, Cucumber, Selenium, Playwright, and REST Assured, with capabilities for parallel execution and CI/CD integration via GitHub Actions and Jenkins.

Tokens
102.6K
Snippets
543
Records
595
Agent score
75%

What's inside Serenity BDD

  1. Overview of Serenity BDD Page Elements

    Serenity Page Elements provide an intuitive alternative to CSS or XPath selectors for interacting with common UI components. They are located in the serenity-screenplay-webdriver module and are compatible with both Screenplay and Action Class-based tests. All Page Elements support the withNameOrId() method, which matches the id, name, data-test, or aria-label attributes.
  2. Overview of Serenity Playwright integration

    The serenity-playwright module integrates Playwright's modern browser automation (auto-waiting, network interception, mobile emulation, and cross-browser support for Chromium, Firefox, and WebKit) with Serenity BDD's reporting. Key benefits include automatic screenshot capture at each step, rich HTML reports, living documentation, and page source capture for debugging failed tests.
  3. Overview of Serenity BDD capabilities

    Serenity BDD is an open-source library designed to create 'living documentation' by producing illustrated, narrative reports from automated acceptance and regression tests. It tracks both which requirements have been tested and how they were tested, providing step-by-step details and optional screenshots.

    Serenity BDD provides built-in support for several testing methodologies and tools:

    • Web Testing: Integration with Selenium.
    • API Testing: Integration with RestAssured for REST APIs.
    • Design Patterns: Support for the Screenplay pattern to create scalable and maintainable tests.
    • BDD Frameworks: Support for Cucumber for executable specifications.
    • Testing Libraries: Compatible with JUnit 4 and JUnit 5.
    • Requirement Management: Supports directory-based requirement organization or integration with external tools like JIRA.
  4. Manage Actors in Cucumber using OnStage

    In Cucumber, actors are often referred to by name in scenarios. To manage this flexibly, Serenity provides the OnStage class and the concept of a Cast. A Cast provides actors with specific abilities (e.g., OnlineCast provides a WebDriver), and the Stage allows you to identify actors by name or track the active actor.

    To set up the stage at the start of a scenario:

    1. Call OnStage.setTheStage() with a specific cast.
    2. Retrieve a specific actor using OnStage.theActorCalled(name).
    3. Retrieve the last active actor using OnStage.theActorInTheSpotlight() for steps that use pronouns or implicit references.
    // Set the stage with a cast that provides WebDrivers
    OnStage.setTheStage(new OnlineCast());
    
    // Retrieve an actor by name
    Actor toby = OnStage.theActorCalled("Toby");
    
    // Retrieve the current active actor (the one in the spotlight)
    Actor currentActor = OnStage.theActorInTheSpotlight();
  5. Avoid common test architecture pitfalls

    To maintain a reliable test suite, follow these three principles:

    1. Avoid Interdependencies: Each test should be independent. Do not rely on the output of one test to feed into another.
    2. Fix Flakiness: Do not simply disable flaky tests. Replace arbitrary sleeps with specific condition waits, such as page.waitForLoadState(LoadState.NETWORKIDLE).
    3. Clean Up Data: Use @AfterEach blocks to delete any test data created during the execution to prevent state pollution.
    // Example of fixing flakiness
    @Test
    void fixedTest() {
        page.waitForLoadState(LoadState.NETWORKIDLE);
        // Now perform assertion
    }
    
    // Example of data cleanup
    @AfterEach
    void cleanup() {
        if (createdOrderId != null) {
            orderService.delete(createdOrderId);
        }
    }
  6. Verify system state using Questions

    In the Screenplay pattern, verification is handled by Questions. A Question is a class designed to retrieve a specific piece of information about the state of the application, such as a text field value, a REST API response, or a database query result, which can then be used to assert the expected behavior.
  7. Understand Living Documentation in Serenity BDD

    Living Documentation in Serenity BDD is a set of executable specifications that describe how an application works and its business rules in a way understandable to non-technical stakeholders. Unlike traditional test reports, which focus on pass/fail metrics for testers, Living Documentation is written collaboratively (by BAs, developers, testers, and product owners) before development starts and is automatically kept up-to-date by the test suite. It serves as a detailed, illustrated user manual and can be used for onboarding new team members or as evidence for auditors.
  8. Implement the Three-Layer Architecture with Serenity Playwright

    The Three-Layer Architecture separates concerns to keep tests readable and maintainable:

    1. Test Class: Focuses on business scenarios and uses @Steps to inject step libraries.
    2. Step Library: Orchestrates Page Object actions and uses @Step annotations to provide rich reporting.
    3. Page Object: Encapsulates locators and handles direct page interactions.
  9. Implement the Page Object Pattern with Serenity Playwright

    The Page Object Pattern is a traditional three-layer architecture where Test Classes define business scenarios, Step Libraries (using @Step annotations) provide reporting, and Page Objects encapsulate locators and page-specific logic. The @UsePlaywright annotation is used to automatically manage the browser lifecycle (Playwright, Browser, BrowserContext, and Page instances), while SerenityPlaywrightExtension ensures the Page is registered for automatic screenshot capture.
    @ExtendWith(SerenityJUnit5Extension.class)
    @ExtendWith(SerenityPlaywrightExtension.class)
    @UsePlaywright(ChromeHeadlessOptions.class)
    class SearchTest {
    
        @Steps
        WikipediaSteps wikipedia;
    
        @Test
        void shouldSearchForATerm(Page page) {
            wikipedia.openWikipedia(page);
            wikipedia.searchFor(page, "Playwright");
            wikipedia.verifyTitleContains(page, "Playwright");
        }
    }
  10. Improve Question error messages with Question.about()

    Use the Question.about() method to provide a descriptive name for the question. This ensures that if a test fails, the resulting error message is more meaningful and describes exactly what the actor was trying to find.
    Question<Integer> numberOfTodoItems() {
        return Question.about("the number of todo items")
                   .answeredBy(
                       actor -> BrowseTheWeb.as(actor).findAll(".todo-list li").size());
    }
  11. Create custom Screenplay Questions

    Reusable questions for domain validation are created using Question.about().answeredBy(). These can be used within Ensure assertions to validate state.
    public class TheOrderTotal {
    
        public static Question<BigDecimal> displayed() {
            return Question.about("the order total").answeredBy(actor -> {
                String totalText = BrowseTheWebWithPlaywright.as(actor)
                    .getCurrentPage()
                    .locator(".order-total")
                    .textContent();
                return new BigDecimal(totalText.replace("$", ""));
            });
        }
    }
    
    // Usage
    actor.attemptsTo(
        Ensure.that(TheOrderTotal.displayed()).isGreaterThan(new BigDecimal("100.00"))
    );