QA Engineering Challenge: Build It. Then Break It.
This is a combined development and test automation assessment. You will build a small but real working application β a Clinic Appointment System called QueueCare β and then write a full automated test suite against your own code.
This is intentional. Real QA engineers understand systems well enough to break them. That is what we are testing here.
Build a simplified clinic appointment system with the following features:
- Register a new user (name, email, password, role)
- Login and receive a token (JWT or session-based)
- Protect all endpoints β unauthenticated requests must be rejected
- Create an appointment
- View all appointments
- View a single appointment by ID
- Update an appointment (date, reason, doctor)
- Cancel / delete an appointment
- Automatically assign a queue number when a booking is created
- View today's queue ordered by queue number
- Allow staff to mark a patient as served
- Patient β can only manage their own appointments
- Staff / Admin β can view and manage all appointments, and mark patients as served
Keep it simple. A clean REST API with basic HTML pages is perfectly fine. You do not need a polished UI. Spend your energy on correctness and test quality.
Write automated tests against the application you just built. You are testing your own code β we expect you to know where the weak spots are.
You must cover all three categories:
Happy Path
- Register β Login β receive valid token
- Create appointment β verify queue number is assigned
- Fetch all appointments β verify role-based filtering works
- Fetch single appointment by ID
- Staff marks patient as served β verify status updates
Negative Cases
- Login with wrong password β expect
401 - Login with non-existent email β expect
401 - Create appointment with missing fields β expect
400 - Access protected endpoint with no token β expect
401 - Access protected endpoint with invalid token β expect
401 - Patient accesses another patient's appointment β expect
403 - Patient tries to mark a patient as served β expect
403 - Fetch appointment with non-existent ID β expect
404
Edge Cases
- Book an appointment in the past β should be rejected
- Duplicate booking on the same day for the same patient β should be rejected
- Invalid date format submitted β should return a clear error
- Reschedule to a past date β should be rejected
- Cancel an already-cancelled appointment β should be handled gracefully
- Mark an already-served patient as served again β should be handled gracefully
- Re-book on the same day after a cancellation β should be allowed
Automate the following flows through the browser:
- Login flow β valid credentials, invalid credentials, empty form submission
- Create appointment β fill and submit the form, verify the booking appears
- Form validation β empty fields, invalid input formats
- Update or cancel β make a change and verify it is reflected in the UI
UI tests must be stable. Use meaningful selectors β data attributes, labels, or accessible roles. Avoid relying on CSS classes or element positions. Flaky tests are a red flag.
Write a short, honest report. This is not a formality β we read it carefully.
| Section | What to Cover |
|---|---|
| What You Built | Your stack, architecture, and key decisions |
| What You Tested | Which parts you covered and which you skipped, and why |
| What You Automated | Which scenarios are automated vs manual, and why you drew that line |
| Bugs Found | Any bugs or unexpected behaviour you found in your own system |
| What You Would Improve | Given more time β what would you test, fix, or refactor |
β οΈ Strong candidates find bugs in their own systems. If your report says "no bugs found", that is almost always a sign of incomplete testing β not perfect code.
Use whatever you know best. The following are suggestions only.
| Option | Notes |
|---|---|
| Node.js + Express | Fast setup, large ecosystem |
| Python + FastAPI | Built-in validation, auto docs |
| Python + Flask | Lightweight, minimal boilerplate |
| Java + Spring Boot | Strongly typed, good if you know Java |
| Go + Gin / Fiber | Fast, good to demonstrate Go experience |
| Ruby on Rails | Rapid development |
| PHP + Laravel | Mature web API ecosystem |
| Option | Notes |
|---|---|
| SQLite | Zero setup, file-based, perfect for assessments |
| PostgreSQL | Production-grade, widely supported |
| MongoDB | Flexible schema, easy to start |
| In-memory (array/map) | Simplest option β perfectly valid for this assessment |
| Tool | Language |
|---|---|
| Jest + Supertest | JavaScript |
| Pytest + Requests / HTTPX | Python |
| RestAssured | Java |
| Postman + Newman | Any β GUI + CLI runner |
| Playwright (API mode) | JavaScript / Python / Java |
| Karate DSL | Any β Gherkin-style |
| Tool | Language |
|---|---|
| Playwright | JavaScript / Python / Java β recommended |
| Cypress | JavaScript |
| Selenium WebDriver | Java / Python |
| Puppeteer | JavaScript |
| Robot Framework | Python |
Plain HTML + JavaScript is completely fine. Other options:
- React.js or Vue.js if you prefer a structured frontend
- Server-side templates (Jinja, EJS, Thymeleaf, Blade)
- No UI at all β a documented Postman collection is acceptable
-
README.mdβ instructions to install, run, and test everything from scratch -
TEST_REPORT.mdβ your written test report
- Prerequisites (runtime versions, browser requirements, etc.)
- How to install dependencies
- How to start the application
- How to run API tests
- How to run UI tests
- Any environment variables needed
- Default test credentials (if applicable)
If a reviewer cannot run your project because of missing setup instructions, it will affect your score. Treat the README as part of the deliverable.
We are not just checking whether the tests pass.
| Dimension | What We Look For |
|---|---|
| Engineering Quality | Clean, readable code. Sensible structure. Simple is better than clever. |
| QA Thinking | Test coverage depth. Identification of edge cases and real failure modes. |
| Automation Skills | Stable, well-structured tests. Good assertions. Reusable helpers. |
| Honesty & Reflection | Accurate test report. Self-found bugs documented. Realistic coverage assessment. |
- A small, well-tested system beats a large, poorly-tested one every time
- Negative and edge case tests matter more than happy path tests β anyone can write a happy path test
- Acknowledging a known bug in your report is far better than pretending it does not exist
- If something does not work, document it and explain why
Good luck. Build something you are proud to explain.