Back to Course
REST ASSURED · CUCUMBER 7 · GHERKIN · EXTENT REPORTS · MAVEN

API Testing with BDD Complete Syllabus

Build a production-ready Java API test automation framework using REST Assured, Cucumber 7, Pico Container DI, and Extent Reports — from first request to full CI/CD pipeline.

10+
Days of Training
12
Modules
70+
Topics Covered
100%
Job-Focused

 What You Will Learn

This course builds a complete, enterprise-grade API test automation framework in Java — from scratch. You will implement BDD feature files with Cucumber 7, write REST Assured request/response flows, manage POJO serialization/deserialization with Jackson, inject dependencies using Pico Container, and publish professional Extent Reports — all integrated with Maven for CI/CD.

✅ REST Assured 5.x ✅ Cucumber 7 + Gherkin ✅ POJO Serialization / Jackson ✅ Pico Container DI ✅ Extent Reports 5 ✅ Maven + Surefire Plugin ✅ Environment Config Management

🚀 Your Learning Journey

From framework design to a fully automated, reportable BDD API test suite.

1Framework & BDD Setup
2Request / Response
3Advanced Patterns
4Reports & CI/CD
🏆Job Ready!
MODULE 01  Framework Fundamentals & Architecture
WHY THIS MODULE

Every company that does API automation asks "how did you design your framework?" in interviews. Getting the architecture right from Day 1 — pom.xml, folder layout, and dependency versions — saves hours of debugging later and shows senior-level thinking from the start.

  • What is a test automation framework and why it matters — standardization, reusability, and team consistency
  • Framework benefits: one structure everyone follows means less rework and faster onboarding of new team members
  • BDD frameworks vs. traditional automation — BDD bridges the gap between developers, testers, and business stakeholders
  • BDD approach overview — write tests in plain English that both humans and machines can understand
  • Maven project setup — pom.xml structure, project layout, and standard directory conventions
  • Initial dependencies — REST Assured 5.3.0, Cucumber 7.11.1, and JUnit 4 for running tests
  • Eclipse IDE setup with the Cucumber plugin for syntax highlighting and navigation
  • Framework folder hierarchy — src/test/java, src/test/resources, and the features/ directory
MODULE 02  REST API Basics & REST Assured Introduction
WHY THIS MODULE

You can't test what you don't understand. Before writing a single line of REST Assured code, you need to know what an API actually does — how requests travel, what status codes mean, and why given().when().then() reads almost like plain English. This is the foundation every test you write will stand on.

  • HTTP protocol fundamentals — GET fetches data, POST creates, PUT/PATCH update, DELETE removes
  • Request-response lifecycle — the journey from your test sending a URL+method to the server replying with data
  • Status codes and what they tell you — 200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Server Error
  • REST Assured library basics — the fluent given().when().then() pattern that makes API tests readable
  • Making your first API calls — .get() and .post() with a base URI configured once for all tests
  • Request logging — .log().all() prints everything you send, invaluable when debugging failures
  • Response logging — .then().log().all() prints exactly what the server sent back
  • Basic assertions — statusCode(200) and body("field", equalTo("value")) to confirm the API behaved correctly
MODULE 03  BDD Framework Setup & Cucumber Integration
WHY THIS MODULE

Gherkin feature files are the reason BDD frameworks are valued in agile teams — a product manager can read them and know exactly what is being tested. Setting up Cucumber correctly with @CucumberOptions and a proper Runner class determines how every test in the entire project is discovered and run.

  • Behavior-Driven Development (BDD) — a collaboration style where developers, testers, and business write test scenarios together before coding begins
  • Gherkin language — Feature, Scenario, Given, When, Then, And, But keywords in plain English
  • Feature files — .feature extension, stored in src/test/resources/features/, one feature per API endpoint group
  • Cucumber 7.11.1 setup — adding cucumber-java and cucumber-junit to pom.xml
  • Eclipse Cucumber plugin — syntax highlighting, step definition navigation, and auto-complete for Gherkin steps
  • Writing scenarios that test one API behavior per scenario — keeps failures easy to diagnose
  • Runner class setup — @RunWith(Cucumber.class) tells JUnit to hand control to Cucumber
  • @CucumberOptionsfeatures path, glue package, plugin reporters, dryRun flag, and monochrome for cleaner console output
MODULE 04  Step Definitions & Feature-to-Code Mapping
WHY THIS MODULE

Step definitions are where your English scenarios become real Java code. Interviewers frequently ask "how does Cucumber connect a feature file to Java?" — understanding @Given, @When, @Then annotations and parameter passing with {string} and {int} is the core skill that makes the whole BDD framework work.

  • Step definitions — Java methods annotated with @Given, @When, or @Then that execute when Cucumber matches a scenario step
  • Mapping feature file steps to Java — Cucumber scans the glue package for matching annotations using exact text
  • Regular expressions and Cucumber expressions — {string}, {int}, {word} placeholders capture values from Gherkin steps
  • Parameter passing — values captured in the step text are passed as Java method arguments automatically
  • Step definition class structure — package naming conventions and keeping related steps in the same class
  • Dry-run mode — dryRun=true validates every feature file step has a matching definition without actually running tests
  • Auto-generated step snippets — when a step has no definition, Cucumber prints the Java method signature for you to implement
  • Ambiguous step resolution — what happens when two step definitions match the same Gherkin text and how to fix it
MODULE 05  Request Building & Serialization
WHY THIS MODULE

Real APIs don't accept plain text — they expect structured JSON. Using POJO classes with Jackson's ObjectMapper instead of hand-crafting JSON strings means your tests adapt automatically when the data model changes. This is the professional approach that separates entry-level testers from automation engineers.

  • JSON file-based payloads — storing request bodies as .json files in src/test/resources/payloads/ keeps data separate from code
  • POJO (Plain Old Java Object) classes — create Java classes matching your API's data model, with fields and getters/setters
  • Jackson serialization — converting a POJO object to a JSON string using ObjectMapper.writeValueAsString()
  • @JsonProperty annotations — map Java field names to JSON keys when they differ (e.g., firstName vs first_name)
  • FileInputStream — reading JSON payload files at runtime so tests use real-world data files
  • .body(pojoObject) vs. .body(jsonString) — REST Assured accepts both; POJOs are cleaner for maintenance
  • Setting ContentType.JSON with .contentType(ContentType.JSON) — tells the server your request body is JSON
  • Building POST and PATCH requests — given().body(payload).when().post("/endpoint") as the standard pattern
MODULE 06  Response Validation & Deserialization
WHY THIS MODULE

Sending a request is only half the job — validating what comes back is the real test. RequestSpecBuilder and ResponseSpecBuilder let you define reusable base configurations so every test inherits the same headers and expected response format, cutting duplicate code by 80% in real projects.

  • Inline body validation — .body("field", equalTo("value")) uses Hamcrest matchers to assert specific JSON fields
  • JsonPath extraction — .extract().path("data.id") pulls a value out of the response for use in the next test step
  • POJO deserialization — .as(PojoClass.class) converts the JSON response body into a Java object automatically
  • Response header validation — .header("Content-Type", "application/json") confirms the server is sending the correct format
  • ResponseSpecBuilder — define once (status code, content type, common fields) and reuse across all tests via .spec()
  • RequestSpecBuilder — centralises base URI, authentication headers, and content type so you don't repeat them in every test
  • Chaining extracted values — capture the id returned by a POST and use it in the subsequent GET or DELETE request
  • Hamcrest matchers — equalTo(), containsString(), hasItems(), notNullValue() for expressive assertions
MODULE 07  Advanced Routing & Data-Driven Testing
WHY THIS MODULE

In real projects, the same API endpoint must be tested with many different inputs — valid data, invalid data, boundary values. Scenario Outline with Examples: tables is Cucumber's answer: one scenario, many data rows, full coverage. This is what makes BDD test suites scale without writing hundreds of duplicate scenarios.

  • Scenario Outline — write a scenario once with placeholders, then drive it with an Examples: table for multiple data sets
  • Data tables in Gherkin — inline multi-row datasets directly in the feature file, passed to step definitions as a list
  • Testing positive, negative, and boundary cases in a single feature file without code duplication
  • Query parameters — .queryParam("key","value") appends search/filter parameters to GET requests
  • Path parameters — .pathParam("id", userId) inserts dynamic values into URL segments like /users/{id}
  • Combining positive and negative test cases in one Scenario Outline — one Examples table, multiple test behaviors
  • Background keyword — shared setup steps (like logging in) that run automatically before every scenario in a feature
  • Doc Strings in Gherkin — embed multi-line JSON payloads directly in the feature file as step arguments
MODULE 08  Tagging, Filtering & Execution Control
WHY THIS MODULE

Not every test should run on every code push. CI/CD pipelines need speed — run only @smoke tests on every commit, @regression overnight, and skip @wip tests still in development. Tagging is the feature that makes your framework production-ready and deployable into real Jenkins pipelines.

  • Cucumber tags — label scenarios or entire features with @smoke, @regression, @sanity to group them logically
  • Tag filtering with OR — tags = "@smoke or @regression" runs scenarios matching either tag
  • Tag filtering with AND — tags = "@smoke and @regression" runs only scenarios that have both tags
  • Negation tags — tags = "not @wip" excludes any scenario still marked as work-in-progress
  • Dry-run with tags — check that step definitions exist for all tagged scenarios without executing any tests
  • Feature-level tagging — tag an entire .feature file so all its scenarios inherit that tag automatically
  • Scenario-level tagging — apply different tags to individual scenarios within the same feature file
  • Running tag subsets via @CucumberOptions(tags=...) in the Runner class — no command-line changes needed
MODULE 09  Cucumber Hooks & Pre/Post Conditions
WHY THIS MODULE

APIs require authentication tokens before you can test them — @Before hooks generate that token automatically before every scenario, so you never have to put login logic inside a test. Hooks also handle cleanup after tests, which is what keeps your test environment from filling with stale data over time.

  • @Before — runs before each scenario; perfect for generating auth tokens, initialising connections, or resetting state
  • @After — runs after each scenario; use for cleanup, logging results, or capturing failure screenshots
  • @BeforeAll / @AfterAll — suite-level setup and teardown that runs once before or after the entire test run
  • Conditional hooks — @Before("@smoke") applies setup logic only to scenarios tagged with that specific label
  • Token generation hook — automatically call the login/auth API before tests so every scenario gets a valid bearer token
  • Database verification example — check database state after a scenario to confirm the API wrote the correct data
  • Hook ordering — the order parameter controls which hook runs first when multiple @Before hooks exist
  • Hooks as a separate class — keeps setup/teardown logic out of step definition files; relies on dependency injection to share state
MODULE 10  Dependency Injection & Multi-Class Architecture
WHY THIS MODULE

As your framework grows, step definitions split across many Java classes — but they all need to share the same response object or auth token. Pico Container solves this without static variables (which break parallel execution). Understanding constructor-based DI is the single most-asked advanced Cucumber topic in senior QA interviews.

  • Why DI is needed — when step definitions live in multiple classes, they can't access each other's variables without a sharing mechanism
  • Cucumber Pico Container — add the cucumber-picocontainer dependency; Cucumber handles the rest automatically
  • Constructor-based injection — declare a shared object in the constructor and Cucumber injects the same instance into every class that needs it
  • Base utilities pattern — create a TestContext or RestUtils class that holds shared state (response, request spec, extracted IDs)
  • Separating concerns — base classes, step definitions, and helper utilities in distinct packages for clean architecture
  • Avoiding NullPointerException — the most common crash in multi-class step definition setups, solved by proper DI
  • Sharing RequestSpecification and Response objects across classes so one class can build the request and another can validate it
  • Thread-safe design — using instance variables (not static) sets your framework up for parallel execution when the project scales
MODULE 11  Environment Management & Configuration
WHY THIS MODULE

Every real project has Dev, QA, Staging, and Production environments — each with a different base URL and credentials. Hard-coding these into test files is the #1 amateur mistake. A ConfigReader utility that reads .properties files means switching environments takes one flag in a Jenkins job — zero code changes.

  • Properties files — config.properties, dev.properties, qa.properties, staging.properties hold environment-specific settings outside the code
  • Global environment switching — changing one property value redirects the entire test suite to a different server
  • Base URI management — RestAssured.baseURI = prop.getProperty("baseURL") sets the root URL for all requests in one place
  • Why externalized config matters — hard-coded URLs and passwords break the moment a server URL changes or a password rotates
  • ConfigReader utility class — reads .properties files using FileInputStream and provides a clean getProperty(key) method
  • Environment selection via Maven — pass -Denv=qa on the command line; the ConfigReader loads the matching properties file
  • Credential management — usernames, passwords, and API tokens live in config files, never committed to version control
  • REST Assured global settings — RestAssured.baseURI, basePath, and port configured once for the entire test suite
MODULE 12  Reporting, Maven Integration & CI/CD
WHY THIS MODULE

A framework nobody can read the results of is useless. Extent Reports 5 generates beautiful HTML dashboards that managers and developers can open in any browser — no tools required. Integrating mvn test into Jenkins completes the picture: your tests run automatically on every code push and the report is there waiting.

  • Extent Reports 5 — ExtentReports, ExtentTest, and ExtentSparkReporter are the three core classes for building reports
  • Extent Cucumber 7 adapter — plug the ExtentCucumberAdapter into @CucumberOptions(plugin=...) and reports generate automatically
  • Spark HTML report — a rich, colour-coded pass/fail dashboard with scenario details, screenshots, and timing information
  • PDF report — ExtentPDFReporter produces an archivable PDF version ideal for sharing with stakeholders
  • Report folder structure — use date-time stamps in the output path to create a unique report for every test run
  • Maven test execution — mvn test compiles and runs all tests; mvn clean test clears previous output first
  • Surefire plugin — configure maven-surefire-plugin in pom.xml to control which Runner class executes and set JVM options
  • Parallel execution — Surefire's dataproviderthreadcount and parallel settings run multiple scenarios simultaneously
  • JDK version and Maven build path configuration — common setup issues resolved so your framework compiles correctly
  • CI/CD readiness — adding mvn clean test as a Jenkins build step or GitHub Actions workflow step automates the entire test pipeline
TIPS  Interview Tips

BDD vs. TDD vs. ATDD

BDD extends TDD by using Gherkin that every stakeholder can read. "Given-When-Then" scenarios serve as living documentation — they describe expected behavior AND verify it. ATDD focuses on acceptance criteria from the user's point of view. Cucumber bridges feature files (business-readable) with step definitions (developer-implemented).

REST Assured Syntax

Write from memory: given().spec(reqSpec).body(payload).when().post("/users").then().spec(resSpec).statusCode(201).extract().path("data.id"). Know RequestSpecBuilder for centralising base config and ResponseSpecBuilder for reusable assertions — these show framework-level thinking.

Dependency Injection

Answer confidently: "Cucumber doesn't allow sharing state through static variables — Pico Container injects shared objects via constructors. I create a TestContext class that holds the Response, extracted IDs, and request spec. Every step definition class receives the same instance through its constructor."

POJO Serialization

Explain clearly: "I create Java POJO classes with Jackson annotations. ObjectMapper.writeValueAsString(pojo) converts the object to a JSON string for the request body. On the response side, response.as(Pojo.class) maps JSON back to Java so I can access fields directly. No hand-crafted JSON strings in the code."

Tag-Based Execution

"I use @smoke, @regression, and @sanity tags in feature files. In Jenkins I pass -Dcucumber.filter.tags="@smoke" as a Maven parameter to run only the fast, critical tests on every commit. Full @regression runs overnight. not @wip keeps in-progress tests out of the pipeline entirely."

Framework Design

Walk them through your package structure: features/ holds all Gherkin scenarios, stepDefinitions/ holds the Java implementations, utilities/ has ConfigReader and RestUtils, payloads/ stores JSON request files, and pojo/ holds data model classes. This architecture is what gets you hired.