skip to content

questions

3

How does an automated case read a text message the product sends when no person holds a phone?

level: juniorimportance: should knowfreq 42%

answer

  1. The run has no handset
  2. The recipient must be an endpoint you own
  3. Rent a receiving number for the run
  4. Match on the number you exclusively hold
  5. Release and clear it in teardown

basics

~20 s

A run cannot open a handset. Instead the account under test is registered against a receiving number the automation controls, whose inbound traffic a capture service exposes over an interface, and the case queries that interface for its own arrival.

solid answer

~40 s

A run cannot open a handset, so the phone number under test has to be one the automation owns: a **receiving number** rented for the run, whose inbound traffic a capture service exposes over an interface the case can query. What the case then has to own is that number. It **leases** one and registers the account under test against it, so no other case can claim the arrival. It **correlates** — matching on the number it exclusively holds, never on "the newest text at this number". And it **releases** the number and clears its recorded history at the end, because a number reused across runs still carries yesterday's arrivals. Everything else is ordinary case work once the recipient is unambiguous.

code

pseudocode · 11 lines
pseudocode
number = numberPool.lease()              # a receiving number the run controls
account = signUp(phone = number.value)

arrival = waitFor(deadline = 60s):
    inbound(number)                      # only texts addressed to THIS lease
      .firstArrivedAfter(caseStartedAt)

assert arrival.recipient == number.value

teardown:                                # runs on pass AND on failure
    numberPool.release(number)           # clears history, returns to pool

go deeper

for a junior

Be ready to say that a run cannot read a handset, so the account under test is registered against a receiving number the automation controls and can query for what arrives.

for a middle

An interviewer expects the mechanics: leasing a number, correlating an arrival to your own case rather than taking the newest one, and clearing the number in teardown.

for a senior

Show production judgment — a pool sized to the suite's parallel width, teardown that releases on failure too, and a diagnosis path for a case that matched an arrival which was not its own.

for a principal

Own the governance question: whether the organisation keeps a pool of real receiving numbers at all, who pays for and retires them, and what the suite does when no lease can be granted.

## Why the recipient has to change first When a product sends a text message — a sign-up confirmation, a password reset, a second-factor prompt — it hands that message to a mobile network addressed to a phone number, and there it leaves your system. There is no store the automation can open afterwards and no history it can page back through. The person whose handset it is may be in another building, or may not exist at all, because the account was created by the run thirty seconds ago. So the first move is not "how do I read a text message". It is to **change who the recipient is**. The account under test registers against a number the automation controls, and only then is there anything to read. A **receiving number** in this sense is a number rented from a capture service that accepts inbound traffic on your behalf and exposes what arrives over an interface a program can query. The network delivers the same message the same way; it simply lands somewhere a case can look. ## The three responsibilities the case takes on Once the recipient is an endpoint you own, three jobs move into the case, and almost every recurring failure on this kind of check traces back to skipping one of them. 1. **Lease it.** Take a number from a pool for the life of the case rather than hard-coding one standing number into the suite. A leased number has exactly one account registered against it, which is what makes the next step trivial. 2. **Correlate the arrival.** Decide, inside the case, why the message it matched is its own. With an exclusively leased number the recipient *is* the correlation: anything that arrives there belongs to this case. Where numbers are pooled and reused, exclusivity is not enough and you need a second signal — an arrival timestamp later than the moment the case started, or a value in the body that the case itself put into the account. 3. **Release it.** Teardown returns the number to the pool and clears its recorded history, and that teardown has to run when the case fails, not only when it passes. A number handed back dirty poisons whichever case draws it next. ## Standing number versus leased number | | One standing number | A leased number per case | |---|---|---| | Correlating an arrival | By content and time; ambiguous the moment two cases overlap | By recipient; unambiguous | | Parallel width | Effectively one case at a time | As wide as the pool | | History between runs | Accumulates; yesterday's arrival still matches | Cleared on release | | Diagnosing a failure | "Which case produced this?" | The number names the case | | Cleanup burden | Manual, and always overdue | In teardown, automatic | The single standing number is the shape almost every suite starts with, because it is one line of configuration. It is also the shape that breaks first: it works until two cases run at the same time, and then it fails in the worst possible way — not by erroring, but by **passing against another case's message**. ## "Take the newest one" is the classic bug The tempting match is *the most recent arrival at this number*. It reads naturally and it is wrong for two reasons that only surface under load. Two cases sharing a recipient produce interleaved arrivals, and "newest" resolves to whichever case was quicker, so both may assert happily against the same text. And a number carrying history from an earlier run already has a newest arrival before the current case has caused anything at all, so the case can complete before the product has done any work. Match on the recipient you exclusively hold, or on something the case can prove it caused. ## The number as a resource with a lifetime - **Size the pool to the parallel width** of the suite, with headroom; a pool one short does not fail cleanly, it makes a case wait or quietly fall back to sharing. - **Fail loudly when a lease cannot be granted.** A case that cannot get an exclusive recipient should stop rather than proceed against a shared one. - **Assume numbers churn.** A rented number can be reclaimed and reissued, so treat the pool as configuration that changes, not as constants pasted into cases. - **Keep the number out of behavioural assertions.** It is plumbing; asserting on it beyond "this arrival was addressed to my lease" couples cases to the pool. - **Record which number a case held** in the failure output, because the first question on a red result is always which recipient was being watched. Everything after the arrival — what you pull out of the body and how you then use it — is a separate concern with its own rules. This part of the job is finished when the case can say, without qualification, that the message it is holding was produced by the product, for the account this case created, during this run.

  • The suite leases receiving numbers but never releases them. What fails, and when?
    The pool drains, so later cases either block waiting for a lease or quietly fall back to a shared number and start matching each other's arrivals. Recorded history also accumulates, so a case can match something from a previous run before the product has done anything. Release belongs in teardown that runs on failure as well as on success.
  • How would a case assert that no text message was sent at all?
    A negative assertion over a channel with an unbounded arrival tail can only ever be bounded, so define a settle window you can justify, assert that nothing addressed to your leased number arrived inside it, and treat the result as evidence rather than proof. Where possible, assert instead at the point the product decides not to send, which is inside your system and definite.

It is a locker rented for the afternoon rather than your own postbox: it is exclusively yours while the case runs, and you empty it before handing the key back.

saying these in an interview costs you the question

  • Assuming a person must read a handset for the check to count
  • Asserting on the newest arrival at a number every case shares
  • Hard-coding one standing number into every automated case
  • Leaving a number's recorded history in place between runs
  • Skipping release when the case fails, so the pool drains
open as a page

How do you design an automated check for a push notification when delivery to the receiving device is best-effort?

level: middleimportance: should knowfreq 35%

basics

~20 s

Split it in two. Assert at the boundary you own, that the product produced an outbound notification with the right recipient and content. Treat arrival at a receiver the run registered as a separate, tolerant, non-gating check.

open as a page