The previous seven chapters built every component of a Rest Assured framework one at a time: BDD chains, request building, response validation, auth, POJOs, framework architecture, data-driven tests, CI. The capstone puts them together against a realistic, end-to-end scenario — a library management API called BookVault. You'll build a complete test framework, from pom.xml to GitHub Actions, with at least 30 tests covering CRUD, auth, business workflows, validation, schema contracts, and data-driven cases. By the end you'll have a portfolio-quality project that demonstrates every skill the course covered. This lesson is the brief; the next lesson is the guided walkthrough; the third is review and stretch goals.
The scenario: BookVault
BookVault is a fictional library system. Three roles, three resources, one business workflow:
- Roles —
admin(full CRUD on everything),librarian(manage books and borrowings),member(view books, borrow, return). - Resources — books (title, author, ISBN, copies), members (name, email, membership level), borrowings (memberId, bookId, borrowedAt, returnedAt).
- Workflow — a member borrows a book; the system reduces available copies; later the member returns the book; copies are restored.
That's a small, plausible API. It exercises every Rest Assured feature you've learned without becoming a project that takes a week to build.
The endpoints
Imagine the API documents look like:
Auth
POST /auth/register — register a new member
POST /auth/login — get a bearer token
POST /auth/logout — invalidate the token
Books
GET /books — paginated list, filterable by author/genre
GET /books/{id} — single book
POST /books — create (admin/librarian)
PUT /books/{id} — replace (admin/librarian)
PATCH /books/{id} — partial update (admin/librarian)
DELETE /books/{id} — delete (admin only)
Members
GET /members — list (admin/librarian)
POST /members — create (admin)
GET /members/{id} — fetch
GET /members/{id}/borrowings — list a member's borrowings
Borrowings
POST /borrowings — borrow a book (member)
PUT /borrowings/{id}/return — return a borrowed book
GET /borrowings — list all (admin/librarian)
There's no live BookVault server you can hit — that's deliberate. Either stub the API with WireMock, Mockoon, or json-server, or replace BookVault with an API your team owns and adapt the resources. What matters is the framework you build, not the specific server it talks to.
Deliverables
By the end of the project you should be able to point at a Git repository containing all of the following — and run mvn test to see it work end to end.
1. Maven project (pom.xml)
Dependencies: rest-assured, rest-assured-json-schema-validator, testng, jackson-databind, lombok, javafaker, allure-rest-assured, allure-testng. Java 21 toolchain, Surefire plugin pointed at a testng.xml.
2. POJOs with Lombok (models/)
- Request:
CreateBookRequest,UpdateBookRequest,RegisterMemberRequest,LoginRequest,BorrowRequest. - Response:
Book,Member,Borrowing,LoginResponse,ApiResponse<T>(generic wrapper),ErrorResponse. - Every model:
@Data @Builder(toBuilder = true) @NoArgsConstructor @AllArgsConstructor. Response models also:@JsonIgnoreProperties(ignoreUnknown = true).
3. Test data factories (factories/)
BookFactory—random(),withTitle(String),withInvalidIsbn(),outOfStock().MemberFactory—random(),admin(),librarian(),withInvalidEmail(). Every factory uses Faker for realism and a UUID suffix for uniqueness.
4. Token management (auth/)
A TokenManager (Chapter 4) with login, expiry-aware caching, and a per-role cache (tokenFor("admin"), tokenFor("librarian"), tokenFor("member")). Reads credentials from Config (env vars or system properties).
5. Specs (specs/)
Specs.adminSpec,Specs.librarianSpec,Specs.memberSpec,Specs.guestSpec— request specs preloaded with the right bearer token.ResponseSpecs.ok,created,noContent,notFound,unauthorized,forbidden— response specs for the recurring shapes.
6. API helpers (helpers/)
BookApiHelper—createBook,getBook,listBooks,updateBook,deleteBook.MemberApiHelper—register,getMember,listBorrowings.BorrowingApiHelper—borrow,returnBook,listBorrowings.AuthApiHelper—login,logout,register. Every helper assumes happy-path; failure tests inline the call.
7. Tests (≥ 30, organised by package)
| Category | Count | Examples |
|---|---|---|
| CRUD | 8 | create/read/update/delete books, list pagination, filter by author |
| Authentication | 5 | valid login, invalid password, expired token, missing token, role check |
| Borrowing flow | 5 | borrow → reduces copies, return → restores, can't borrow if 0 copies, can't return what wasn't borrowed, borrowing history endpoint |
| Validation | 5 | empty title, invalid ISBN, invalid email, missing required field, oversized payload |
| Data-driven | 5 | book creation from JSON DataProvider with mixed valid/invalid rows |
| Schema validation | 2 | book and member responses validated against JSON Schema |
| Total | 30 | Each test in its own method, named for what it does |
8. Logging
enableLoggingOfRequestAndResponseIfValidationFails()globally.LogConfig.blacklistHeader("Authorization")to keep tokens out of logs.- Optional: a custom
TimingFilterthat flags slow requests.
9. Reporting Allure or ExtentReports configured. Every Rest Assured request attached to its test step. Report published to GitHub Pages from main.
10. CI/CD
A .github/workflows/api-tests.yml that runs on PR and main (smoke on PR, full on main, scheduled nightly). Secrets injected for credentials. Test results uploaded as artefacts; Allure report published to Pages.
How the deliverables map to the chapters
- – Maven + TestNG project layout
- – Given-When-Then chains
- – GET / POST / path & query params
- – Headers, content types, JSON bodies
- – JsonPath + GPath in helpers
- – Hamcrest matchers in tests
- – JSON Schema for Book & Member
- – TokenManager per role
- – Auth matrix tests (admin / librarian / member / guest)
- – Horizontal escalation tests
- – Request / Response POJOs
- – Lombok @Data + @Builder
- – ErrorResponse for negative tests
- BaseApiTest + Config –
- Specs + ResponseSpecs hub –
- Filters: logging + timing + Allure –
- Helpers + factories –
- DataProviders for parameterised cases –
- @AfterMethod cleanup hooks –
- GitHub Actions workflow –
Every chapter contributes one or two arrows. The capstone is the integration — proving that the patterns work together when applied at the same time, against the same domain.
Suggested project layout
bookvault-tests/
├── pom.xml
├── testng.xml
├── smoke.xml
├── .github/workflows/api-tests.yml
└── src/
└── test/
├── java/com/bookvault/tests/
│ ├── BaseApiTest.java
│ ├── auth/
│ │ ├── LoginTest.java
│ │ └── AuthorisationMatrixTest.java
│ ├── books/
│ │ ├── BookCrudTest.java
│ │ ├── BookSearchTest.java
│ │ └── BookValidationTest.java
│ ├── borrowings/
│ │ ├── BorrowReturnFlowTest.java
│ │ └── BorrowingHistoryTest.java
│ ├── datadriven/
│ │ └── BookDataDrivenTest.java
│ ├── schema/
│ │ └── SchemaValidationTest.java
│ ├── config/
│ │ ├── Config.java
│ │ └── TokenManager.java
│ ├── specs/
│ │ ├── Specs.java
│ │ └── ResponseSpecs.java
│ ├── filters/
│ │ └── TimingFilter.java
│ ├── helpers/
│ │ ├── AuthApiHelper.java
│ │ ├── BookApiHelper.java
│ │ ├── MemberApiHelper.java
│ │ └── BorrowingApiHelper.java
│ ├── factories/
│ │ ├── BookFactory.java
│ │ └── MemberFactory.java
│ └── models/
│ ├── request/
│ │ ├── CreateBookRequest.java
│ │ ├── LoginRequest.java
│ │ ├── BorrowRequest.java
│ │ └── ...
│ └── response/
│ ├── Book.java
│ ├── Member.java
│ ├── Borrowing.java
│ ├── ApiResponse.java
│ ├── ErrorResponse.java
│ └── ...
└── resources/
├── config.properties
├── schemas/
│ ├── book-schema.json
│ └── member-schema.json
└── testdata/
└── book-creation.json
Eleven directories, each with a single concern. The structure should already feel familiar — it's the layout from the framework chapter, scaled up to a multi-resource project.
Suggested order of work
A reasonable sequence over 4–8 sessions:
- Scaffold the Maven project and add dependencies. Write a single trivial test that hits
GET /booksand asserts 200. Commit. - Models. Build the request and response POJOs for
Book. WriteBookFactory.random()and a real CRUD test usingextract().as(Book.class). Iterate until the create-then-get works. - Auth. Add
TokenManagerandConfig. Write the four role specs. Write one test per role asserting the right access on/books. - Helpers. Extract
BookApiHelperfrom the CRUD test. Extract the auth code intoAuthApiHelper. Refactor existing tests to use them. - Members and borrowings. Repeat steps 2–4 for the other two resources. The shape is now familiar; the second and third resources should go faster.
- Borrowing flow. Write the multi-step business test: borrow → assert reduced count → return → assert restored count. This is where the framework pays back — each step is one helper call.
- Validation tests. Inline negative cases, including SQL-injection-style strings, oversized payloads, missing fields. Use the
ErrorResponsemodel. - Data-driven. Move 5–10 book-creation tests into a JSON
@DataProvider. Include both happy-path and rejection rows. - Schema validation. Write
book-schema.jsonandmember-schema.json. AddmatchesJsonSchemaInClasspathto one test per resource. - Reporting. Add Allure. Run the suite and read the report. Refine
@Stepannotations on helpers if the report feels sparse. - CI. Add GitHub Actions, secrets, the artefact uploads, the Allure publishing step. Push and watch the run.
Each step is one or two evenings of focused work. The whole project is one comfortable week.
Definition of done
You're done when:
mvn clean testruns all 30+ tests green from a fresh checkout.- A new contributor can clone, set three env vars, and run the suite — no laptop-specific config.
- Failing tests produce a complete request/response dump in the artefact, with auth headers redacted.
- The GitHub Actions run is green on every push and a clear red with linked artefacts on a regression.
- The Allure report (or chosen alternative) is published to a stable URL.
- A second engineer reading the test code can tell, within 30 seconds, what each test asserts.
That last bullet is the real test. The framework is in service of readable tests; if they aren't readable, the framework hasn't earned its keep.
What this lesson is not
This brief intentionally doesn't dictate every line. The next lesson is a guided walkthrough of the trickier components — POJOs with generics, the borrowing flow, the GitHub Actions wiring — but most of the work is your own composition of patterns you've already practised. The point of a capstone is the synthesis: every chapter's lesson, every chapter's practice, applied together for the first time.
A short reading sprint before you start: re-skim Chapter 6 (framework architecture) and Chapter 7 (data-driven and CI). Those two chapters provide ~80% of the moving parts the capstone assembles.
⚠️ Common mistakes
- Building everything before the first test runs. It's tempting to scaffold all the helpers, all the factories, all the specs, then write the tests. The result is hours of code that doesn't work yet. Do it the other way: write one test, then one helper, then one factory. Each green test proves the slice you just added.
- Cargo-culting from previous chapters. Don't add a filter, a spec, or a helper because the previous chapter mentioned it. Add it because this test needs it. The capstone framework should be exactly as elaborate as the tests demand — not an inch more.
- No cleanup. A 30-test suite that never deletes the books it creates pollutes the BookVault DB by a hundred rows per run. Write the
@AfterMethodcleanup early; it's much harder to retrofit.
🎯 Practice task
This is the project. Your "practice" is to spend 4–8 focused sessions building it.
- Today (45 min): scaffold the Maven project, add dependencies, write one trivial test (hit a known public API like JSONPlaceholder to confirm the toolchain works). Commit to a fresh repo.
- Tomorrow (90 min): add a stub server (WireMock standalone, Mockoon, or json-server) implementing
/booksand/auth/login. WireConfigto point at it. Write theBookPOJO andBookApiHelper.getBook(id). Get one passing test against the stub. - Session 3 (90 min): build the rest of the book CRUD endpoints in your stub. Write CRUD helper methods and 4 CRUD tests. Confirm green.
- Session 4 (90 min): add
TokenManager,Specsfor three roles, and the auth matrix test (3 roles × 4 endpoints = 12 cases via@DataProvider). - Session 5 (90 min): add members and borrowings. Write the borrowing flow integration test (borrow → check count → return → check count).
- Session 6 (90 min): add data-driven validation tests, schema validation, and
@AfterMethodcleanup hooks. - Session 7 (60 min): add Allure reporting, the GitHub Actions workflow, and Pages publishing. Push and watch the green run.
- Session 8 (review): open the next lesson — the guided walkthrough — and compare the trickier pieces against your implementation. Refactor what's worth refactoring; leave what's working alone.
The next lesson walks through the components most learners trip on. Read it whenever you're stuck — or after you've finished, as a sanity check.