41. Double charge bug
Some customers are charged twice. It happens only rarely and only on slow networks. What is the most likely cause to test for?
- A.A wrong CSS colour on the pay button
- B.The database has too many indexes
- C.The UI text is not translated
- D.A double submit or client retry is processed twice because the payment API is not idempotent
Show answer
Answer: D. A double submit or client retry is processed twice because the payment API is not idempotent
On slow networks users tap again or clients retry, sending the same payment twice. Without an idempotency key or disabled button and server-side duplicate check, both requests succeed. Test by throttling the network, double-clicking and replaying requests.
42. Reusing an idempotency key
A payments API supports an Idempotency-Key header. You send POST /payments with key abc-123 and amount 100, which succeeds. You then send the same key with amount 500. What is the correct behaviour?
- A.Charge 500 as a new payment
- B.Charge 400 more so the total is 500
- C.Reject the second request with an error (for example 409 or 422) because the key was already used with a different body, and create no new charge
- D.Return 500 Internal Server Error
Show answer
Answer: C. Reject the second request with an error (for example 409 or 422) because the key was already used with a different body, and create no new charge
An idempotency key means "this is the same operation". Repeating it with the same body should return the original result without charging again. Reusing it with a different body is a client error and must be rejected, otherwise retries can create wrong charges. Also test concurrent requests with the same key and key expiry.
43. equalTo fails on a decimal
The response is {"price": 10.5}. This REST Assured check fails with a message saying 10.5 is not 10.5. Why?
- A.REST Assured cannot read decimal numbers at all
- B.JsonPath returns a Float by default; the check uses a Double
- C.The price field is sent as a string
- D.Hamcrest equalTo only works on text
Show answer
Answer: B. JsonPath returns a Float by default; the check uses a Double
By default REST Assured parses JSON decimals as Float, so equalTo(10.5) (a Double) does not match. Use equalTo(10.5f), or set JsonConfig to return BigDecimal and compare with a BigDecimal, which is also better for money.
44. Who writes a Pact contract
In consumer-driven contract testing with Pact, how is the contract created and checked?
- A.The provider writes it, then every consumer verifies it
- B.A tester writes it by hand in a shared spreadsheet
- C.Consumer tests generate it; the provider verifies against it
- D.It is generated from production logs every night
Show answer
Answer: C. Consumer tests generate it; the provider verifies against it
The consumer's tests run against a Pact mock and record the requests and responses they need into a pact file. The provider then replays those requests against its real code to verify. A broker shares pacts and results.
45. Exact values in a pact
A consumer pact expects "createdAt": "2026-03-01T10:00:00Z" exactly. Provider verification keeps failing because real timestamps differ. What is the right fix?
- A.Ask the provider to hard-code that timestamp
- B.Use a type or regex matcher for the timestamp
- C.Delete the createdAt field from the pact
- D.Turn off provider verification for this pact
Show answer
Answer: B. Use a type or regex matcher for the timestamp
Contracts should pin the shape and type the consumer relies on, not incidental values. Pact matchers like like(), regex or a datetime matcher check the field is a valid timestamp without fixing its value.
46. Webhooks twice and out of order
A provider may send the same webhook more than once and not always in order. Which test is most important?
- A.Send each event once, in the right order, and check 200
- B.Send an event with an empty body and expect a 400
- C.Send 1,000 events per second and measure the speed
- D.Send "paid" twice and "created" after "paid"; check final state
Show answer
Answer: D. Send "paid" twice and "created" after "paid"; check final state
Most webhook systems deliver at least once and do not guarantee order. Handlers must be idempotent (use the event ID) and must not let an older event overwrite a newer state. Testing only perfect delivery misses both bugs.
47. Testing a 202 Accepted API
POST /reports returns 202 with a Location of /reports/jobs/31. How should an automated test check the report?
- A.Assert the report content in the 202 response
- B.Sleep a fixed 60 seconds, then fail if not done
- C.Treat 202 as a failure, since it is not 200
- D.Poll the job URL until done or timeout, then check it
Show answer
Answer: D. Poll the job URL until done or timeout, then check it
202 means the work was accepted but is not finished. The test should poll the status URL with a sensible interval and overall timeout, then check the final result. Fixed sleeps are slow and still flaky.
48. Too much data in a response
GET /users/me returns the profile plus "passwordHash", "isAdmin" and "internalNotes". The UI only shows the name and email. Why is this a defect?
- A.The API exposes sensitive fields the client does not need
- B.The UI is too slow to show all of those fields
- C.The response should have been sent as XML instead
- D.The user should be shown their own password hash
Show answer
Answer: A. The API exposes sensitive fields the client does not need
Hiding fields in the UI is not protection; anyone can read the raw response. OWASP's API Security Top 10 covers this under object property level authorisation. Tests should check responses contain only allowed fields.
49. Static settings and parallel tests
Tests set RestAssured.baseURI in their own setup, some to the orders service and some to the users service. Run in parallel, tests sometimes hit the wrong service. Why?
- A.REST Assured cannot send two requests at once
- B.Parallel tests always use the last URL in the file
- C.JUnit resets baseURI between every test
- D.RestAssured.baseURI is a global static shared by threads
Show answer
Answer: D. RestAssured.baseURI is a global static shared by threads
Static fields like RestAssured.baseURI are shared across all threads. One test changes it while another is running. Use a RequestSpecification per test or per client instead of global settings when running in parallel.
50. Machine-to-machine auth
Your test suite calls a backend API as a service, with no user logging in. Which OAuth 2.0 grant fits?
- A.Authorization code with PKCE
- B.Implicit grant
- C.Client credentials
- D.Device authorization
Show answer
Answer: C. Client credentials
The client credentials grant lets a service swap its client ID and secret for a token, with no user involved. Authorization code with PKCE is for user logins in apps. The implicit grant is deprecated in current OAuth guidance.
51. Testing a token right at expiry
An API accepts JWTs and allows 30 seconds of clock skew. A token's exp is 10:00:00. Which tests check the expiry handling?
- A.One call at 09:00 accepted, and nothing near 10:00
- B.Calls at 10:00:20 accepted, at 10:00:40 rejected with 401
- C.Calls at 10:00:20 and 11:00 both accepted with 200
- D.Calls at 09:59:50 rejected, at 10:00:40 accepted
Show answer
Answer: B. Calls at 10:00:20 accepted, at 10:00:40 rejected with 401
With a 30-second leeway, a token is still valid until 10:00:30. Testing just inside and just outside that window catches wrong leeway or ignored exp claims. An expired token should get 401.
52. Error message shows code details
A malformed request returns 500 with a full Java stack trace, SQL query and library versions in the body. Why is this a security bug?
- A.It gives attackers internal details to plan attacks
- B.Stack traces make every response much slower
- C.Clients cannot parse such long error bodies
- D.It breaks the API's documented JSON schema
Show answer
Answer: A. It gives attackers internal details to plan attacks
Detailed errors reveal frameworks, versions, table names and code paths that help attackers. Production APIs should return a generic message with an error ID and keep details in server logs. Fuzzing bad input often finds this.
53. Same URL, different method
GET /admin/users/5 correctly returns 403 for a normal user. What extra test checks for method-based access bugs?
- A.Send GET again with a much longer timeout
- B.Send GET to /admin/users/6 as an admin
- C.Send OPTIONS and expect a 200 with a body
- D.Send DELETE and PUT to the same URL as a normal user
Show answer
Answer: D. Send DELETE and PUT to the same URL as a normal user
Access rules are sometimes set per method and one gets missed, so DELETE may work where GET is blocked. Trying every method on protected URLs with low-privilege tokens finds these gaps.
54. GraphQL introspection in production
In a production GraphQL API that serves only your own apps, the __schema introspection query returns the full schema, including admin mutations. What should a tester report?
- A.Introspection makes queries slower for everyone
- B.Introspection exposes the whole schema to attackers
- C.Introspection is needed by all production clients
- D.Admin mutations cannot be called if listed
Show answer
Answer: B. Introspection exposes the whole schema to attackers
Introspection is useful in development, but in a private production API it hands attackers a map of every type and mutation. Many teams turn it off or limit it there. Hiding the schema is not access control, so mutations still need auth checks.
55. One GraphQL query, many DB calls
A GraphQL query for 50 orders with their customers makes 51 database calls. What is this problem called, and how do you test for it?
- A.The N+1 problem; count DB queries per request
- B.A cache miss; clear the cache and retry
- C.A race condition; run the query twice
- D.A timeout; raise the request timeout
Show answer
Answer: A. The N+1 problem; count DB queries per request
Resolving each customer separately causes 1 query for orders plus 1 per order. Batching with a DataLoader fixes it. Tests can count database queries for a request, or watch latency grow with the list size.
56. Checking a provider against its spec
A provider has no Pact consumers but publishes an OpenAPI spec. What kind of check verifies the running service matches the spec?
- A.Compare the spec file with last month's copy
- B.Ask consumers to read the spec carefully
- C.Count the number of endpoints in the spec
- D.Generate requests from the spec and validate responses
Show answer
Answer: D. Generate requests from the spec and validate responses
Tools like Schemathesis or Dredd read the OpenAPI spec, send requests and check status codes and bodies match the schema. This provider-driven contract testing catches drift between docs and code.
57. One coupon used twice
A coupon is valid for one use per user. A tester sends 10 identical redeem requests at the same moment and 3 succeed. What does this show?
- A.The coupon limit was set to 3 by mistake
- B.The client sent requests to different servers
- C.Normal behaviour for any API under load
- D.A race condition: check-then-update is not atomic
Show answer
Answer: D. A race condition: check-then-update is not atomic
Each request checked "not used yet" before any of them marked it used. The fix is an atomic update or a unique constraint. Parallel requests are the only way to find such bugs; serial tests always pass.
58. Breaking changes between services
Team A's service often breaks Team B's client when it changes its API. Full end-to-end tests are slow and flaky. Which approach fits best?
- A.Consumer-driven contract testing (for example Pact), where the provider verifies the consumer's expectations in its own CI
- B.More UI tests that go through both services
- C.Manual testing by Team B before every Team A release
- D.Freezing Team A's API forever
Show answer
Answer: A. Consumer-driven contract testing (for example Pact), where the provider verifies the consumer's expectations in its own CI
Contract tests record what a consumer needs from a provider and verify it against the provider on every change, without deploying the whole system. They catch breaking changes early and fast, complementing a small number of E2E tests.
59. Can I deploy this service
You use Pact with a broker. The provider team wants to know if their new version is safe to release to production. What answers this?
- A.Running the provider's unit tests
- B.A manual check of the API docs
- C.Running all end-to-end tests in staging
- D.The can-i-deploy check, which looks up whether this version has verified the contracts of the consumer versions currently in production
Show answer
Answer: D. The can-i-deploy check, which looks up whether this version has verified the contracts of the consumer versions currently in production
The broker stores contracts and verification results for each version and environment. can-i-deploy turns that into a yes/no gate in the pipeline, giving fast safety without a full integrated environment.
60. A fake that drifted from reality
Unit tests use a FakePaymentGateway. Over time it accepts amounts the real gateway rejects, and bugs reach production. What practice keeps fakes honest?
- A.Delete the fake and call the real gateway sandbox from every unit test
- B.Run one shared contract test suite against both the fake and the real gateway sandbox
- C.Let each developer update the fake whenever they think it is wrong
- D.Make the fake accept every input so that unit tests never fail on it
Show answer
Answer: B. Run one shared contract test suite against both the fake and the real gateway sandbox
If the same behavioural tests run against the fake and the real implementation (or its sandbox), any difference shows up as a failing test. The fake then stays a faithful, fast substitute, and unit tests remain trustworthy.