21. Write test cases for Amazon's Lightning Deal feature.
Identify and write test cases for the Lightning Deal feature in Amazon shopping.
I would test the Lightning Deal rules with fast unit tests and use controlled integration tests for the real pricing, inventory, cart, payment, order, and notification boundaries. The system under test is the Lightning Deal workflow. I would use a fake clock, a stub for pricing and eligibility, and a mock for the inventory reservation interaction. I would cover the active time window, correct deal price, customer eligibility, quantity limits, sold out behavior, reservation expiry, payment failure, cancellation, repeated requests, and simultaneous claims for the final unit. For every case, I would assert the customer visible result and the stock, reservation, order, and progress invariants. Unit tests give fast feedback, but the critical transaction and concurrency paths still need controlled integration tests.
The practical strategy is to test the Lightning Deal workflow at two main levels. I would use unit tests for the deal rules and controlled integration tests for real collaboration between pricing, inventory, cart, payment, order, and notification components.
- What behavior and test boundary should I cover?
- Which dependencies, environments, and test tools should I assume?
- Which failures, edge cases, and quality risks are most important?
The system under test is the Lightning Deal workflow. It decides whether a deal is active, whether a customer may claim it, which price is shown, whether one unit may be reserved, and whether that reservation is finalized or released. The unit test boundary contains the deal workflow and controlled test data. Real services and the real database remain outside that boundary.
For unit tests, I would replace only the dependencies needed by the workflow. A fake clock provides a controlled current time. A pricing and eligibility stub returns known values. An inventory reservation mock returns the configured result and records whether reserve or release was called. Each replacement must be applied where the Lightning Deal code looks up that dependency. These doubles make tests fast and deterministic, but they do not prove that the real integrations work.
I would use small function scoped fixtures so every test starts with fresh state. A deal factory would create a deal with a known original price, deal price, start time, expiry time, quantity limit, and stock amount. Customer data would clearly state whether the customer is eligible and how many units that customer has already claimed. Cart, reservation, and order state would also be explicit. Tests must not share mutable state or depend on execution order.
The normal test flow is arrange, act, assert, and cleanup. During arrange, I create the deal configuration, inventory state, reservation state, customer state, cart state, and controlled clock. During act, I perform one action such as viewing the deal, claiming it, adding it to the cart, attempting checkout, cancelling, removing the item, or advancing the clock past expiry. During assert, I check both the customer visible result and the system invariants. During cleanup, I reset the clock and test data. Integration tests also roll back or recreate their database and service state.
The first important test is the time boundary. Before the start time, the deal should be hidden or not claimable. At the exact start time, an eligible customer should be able to claim it. During the valid window, the deal should remain active. At the exact expiry boundary, new claims should be rejected and the deal should show the correct closed state.
The second test checks pricing. The product page should show the correct original price and deal price. The cart should keep the same deal price. A successful order should also use that price. The test should verify that the normal price does not replace the deal price during the valid reservation and checkout flow.
The third test checks eligibility and customer quantity limits. An eligible customer should be able to claim the allowed quantity once. An ineligible customer should be rejected. A customer who exceeds the configured quantity limit should also be rejected without reserving more stock.
The fourth test checks sold out and waitlist behavior. When no deal stock remains, a new claim should fail. The customer should see the defined unavailable or waitlist state. No extra reservation should be created, and available stock must not become negative.
The fifth test checks cart removal and reservation expiry. When a customer removes the item or the controlled clock passes the reservation expiry time, the reservation should be released exactly once. The unit should return to available stock. Reserved, sold, claimed, and progress values should follow the defined product rule and remain internally consistent.
The sixth test checks payment failure and cancellation. The flow should reach a neutral checkout attempt. If payment succeeds, one order should be created at the deal price and the reserved stock should be finalized. If payment fails or the customer cancels, no completed order should exist. The reservation should be released exactly once, and the unit should return to available stock.
The seventh test checks repeated requests. Repeating the same claim, checkout, cancellation, or release request should not reserve, finalize, or release stock twice. This verifies idempotency, which means that repeating the same request does not create an additional effect.
The eighth test checks concurrency at the final unit. I would start with exactly one available deal unit and trigger two eligible customer claims at nearly the same time in a controlled integration test. Exactly one claim should succeed. The other should receive the defined unavailable result. Only one reservation should exist, and stock must never become negative.
Assertions should cover customer visible behavior and back end invariants. Customer visible behavior includes the active state, timer state, price, cart result, unavailable or waitlist result, and order outcome. Invariants include consistent available, reserved, sold, and claimed values, no duplicate reservation, no duplicate completed order, and exactly one release for a failed, cancelled, removed, or expired reservation.
The integration tests should use a dedicated test database, isolated schema, or controlled temporary database. Required migrations should be applied. Factory data should create the exact stock, reservation, cart, and order state needed by each scenario. Isolation can use transaction rollback, truncation, or database recreation. Production data must never be used.
The critical integration cases are real inventory reservation, transaction behavior, pricing data, cart collaboration, successful order creation, payment failure cleanup, reservation release, waitlist behavior, and final unit concurrency. These tests provide confidence that real components work together, but they are slower and require more setup than unit tests.
The tests should control time instead of waiting for real time to pass. They should not use fixed sleep calls. Unit tests should not make real network calls. In continuous integration, the fast unit suite should run on every change. The controlled integration and concurrency suites can run in a separate job with the required services and database.
The main tradeoff is speed versus confidence. Unit tests are fast, isolated, and easy to debug. They cannot validate real database constraints, transaction isolation, or service contracts. Integration tests provide that confidence, but they take longer and require careful cleanup. A small end to end test may cover the most important purchase path, but it should not replace focused unit and integration tests.
- Define the Lightning Deal rules for active time, price, eligibility, customer quantity, stock, reservation, checkout, cancellation, expiry, and waitlist behavior.
- Choose the test level. Use unit tests for deal decisions and controlled integration tests for real service and database collaboration.
- Arrange deterministic data. Create a deal, customer, stock state, reservation state, cart state, order state, and controlled clock with small function scoped fixtures or factories.
- Replace unit test dependencies. Use a fake clock, a pricing and eligibility stub, and an inventory reservation mock at the lookup location used by the workflow.
- Run one action. View the deal, claim it, add it to the cart, attempt checkout, cancel, remove the item, or advance the clock past expiry.
- Assert the customer visible result. Check the deal state, timer state, price, cart state, unavailable or waitlist state, and order outcome.
- Assert system invariants. Check available, reserved, sold, claimed, reservation, and order state. Verify that finalize or release happens exactly once.
- Cover the active path, failure branches, time boundaries, sold out state, repeated requests, and final unit concurrency.
- Clean up. Reset the clock and unit test state. Roll back, truncate, or recreate integration state.
- Run fast unit tests on every change and run controlled integration and concurrency tests in a separate continuous integration job.
Algorithm complexity is not the main issue in this question. The important cost is test runtime, setup, isolation, maintenance, and continuous integration time. Unit tests are usually fast because they use small fixtures and test doubles in memory. Integration tests are slower because they may start services, apply migrations, create database records, open transactions, and clean up state. Concurrency tests may need multiple workers or threads and can take longer to diagnose. Small explicit fixtures keep maintenance cost low. Large shared fixtures, real sleep calls, and unnecessary service startup make the suite slower and less reliable.
This testing approach is used for flash sales, limited inventory promotions, ticket sales, reservation systems, product launches, coupon campaigns, and other workflows where time, price, customer limits, and stock must remain consistent. It is especially useful when many customers may claim the same limited resource and when failed payments, cancellations, cart removal, or expiry must safely return reserved capacity.
Interviewers ask this question to see whether a candidate can turn a customer feature into a complete and reliable test plan. They evaluate how the candidate defines the Lightning Deal boundary, controls time and inventory state, separates unit tests from integration tests, checks customer visible results, protects stock invariants, covers failure paths, and reasons about concurrent claims. They also want to see whether the candidate understands that fast tests with doubles provide isolation but do not prove that real services and database transactions work together.
A common mistake is testing only the successful order path. That misses time boundaries, sold out behavior, reservation expiry, payment failure, cancellation, repeated requests, and concurrent claims. Another mistake is using the real clock or fixed sleep calls, which makes tests slow and flaky. Tests may patch the original library instead of the name used by the Lightning Deal workflow. Over mocking is also risky because a passing mocked test does not prove real pricing, inventory, transaction, order, or waitlist behavior. Shared mutable fixtures can leak stock and reservation state between tests. Weak assertions may check only the visible response while missing negative stock, duplicate reservations, duplicate orders, or repeated releases. Tests should not use production data, depend on test order, or treat coverage percentage as proof of quality.
Start with the test boundary and the main invariants. Then group the cases into time, pricing, eligibility, quantity, inventory, reservation, checkout failure, repeated request, and concurrency scenarios. Explain which cases use unit tests and which require controlled integration tests. Finish by stating that test doubles provide speed and isolation, while real integration tests provide confidence in transactions and service contracts.
