When asked how to test a new feature, start with its user contract and failure boundaries. Listing unit, integration and end-to-end tests is less useful than explaining which mistake each test would catch.

Use a fictional CSV import. It accepts a header and data rows, reports invalid input and creates records only under the agreed import policy. The policy is deliberately unspecified at first so you can practice asking the right question.

What must be clarified before testing?

Ask whether one invalid row rejects the whole file or whether valid rows may still be imported. Also ask how duplicate rows, duplicate uploads, unknown columns and empty files should behave. Without those answers, “the import passed” has no clear meaning.

Write one concrete example for the chosen rule. If the import is all-or-nothing, a malformed second row must leave no records from the first row. If partial success is intended, the response must identify what was accepted and rejected.

What is the smallest useful fixture?

name,email
Mina,mina@example.invalid
Noah,not-an-email

The addresses are illustrative and should not receive mail. The second row is a deliberate invalid input. This file is small enough to inspect manually and useful for tracing validation, storage and feedback.

Which tests belong near the parser?

  • A valid header and row produce the expected fields.
  • A missing required header produces a clear error.
  • Quoted separators are handled according to the parser contract.
  • Blank and malformed rows follow the chosen rule.
  • Encoding and line-ending cases match supported input.

Reuse an established CSV parser rather than designing a weak split-on-comma implementation for the test. The test should protect the product contract, not require one particular internal method.

What needs an integration check?

Verify that validated rows are stored correctly and that a rejected import leaves the intended state. Test duplicate prevention at the persistence boundary if it is a requirement. An in-memory list cannot prove a database constraint or transaction behavior.

Keep the database isolated. Give the fixture a known starting state and inspect the stored result after the request. A success message alone is not persistence evidence.

What should the user-facing test cover?

Choose a representative upload, confirm progress feedback and inspect the final summary. Check that the error identifies a useful row or field without exposing private data. Confirm the user can correct the file and try again.

Use a small number of broad interaction checks rather than repeating every parser case through the browser. Detailed edge cases are often faster and clearer near their responsible boundary.

How do you prioritize when time is limited?

Start with data integrity and access boundaries, then the main successful flow and the most likely recoverable failure. Add cases based on consequence and likelihood. Do not quietly redefine “complete testing” as whatever happened to run.

Report the executed checks separately from the planned ones. A useful interview answer says what each test proves, which dependencies are real and what remains to verify. That gives a reviewer a basis for a release decision instead of a long unranked checklist.

References and next practice

careerservices.fas.harvard.edu — career · careers.umd.edu — preparation

Browse interview topics · Practise a question in Interview Challenge · How to Prepare for an Interview