Make every outbound test request intentional.
Payments, identity, email, SMS, file storage, analytics, and shipping can all sit behind one browser action. Before writing the test, draw the request path: which service receives the call, which account or bucket it uses, which callback returns, and which application record changes. Put the endpoint and credential for each dependency in test configuration that fails loudly when it is missing.
A test should never quietly fall back to a live account because a clone or provider sandbox is unavailable. Use separate environment variables, test credentials, and hostnames for test traffic. Add a startup check that prints safe endpoint names and refuses live-looking credentials in the test job.
Vendor-shaped request
Your app calls the same API contract used in the integration.
base URL changesState you can inspect
A clone or mock returns the behavior your scenario needs without shared live side effects.
known responseCustomer-visible result
Check the browser state and the callback or record that caused it.
contract + screen stateChoose a provider sandbox, mock, or clone.
A provider test environment is useful for checking compatibility with the provider’s own contract. A mock lets you return a selected response, inject a failure, or model a short sequence. A stateful clone can keep provider-shaped records that your application creates and later reads. Choose based on the behavior under test, then read the limits of that option.
Stripe’s testing documentation explains its test values and sandbox behavior. WireMock’s stateful behavior guide shows how scenarios can move from one response state to another. Molar’s clone catalog lists the supported service paths and is the source to check before relying on a Molar-specific integration.
Give each run separate identities and records.
Create a disposable user, inbox, phone number, storage prefix, or provider customer for each isolated run where the service supports it. Parallel runs should not race for one verification code or delete each other’s object. Prefix records with a run identifier so a failure can be traced without exposing secrets in logs.
If the setup has snapshots or reset, capture a known state before the test and restore it afterward. Verify a representative record after reset. Cleanup is not the same as isolation: deleting the final order does not prove that a webhook queue, inbox, or provider-side object returned to its starting condition.
Test the callback that completes the work.
A successful outbound request often starts asynchronous work. Your app may be waiting for a signed payment event, delivery receipt, email, or file-processing status. Assert the incoming payload, signature validation, duplicate handling, and application state after the callback.
cy.intercept('POST', '/api/orders').as('createOrder');
cy.get('[data-testid=buy]').click();
cy.wait('@createOrder').its('response.statusCode').should('eq', 201);
// Follow with an application-level assertion:
cy.contains('Order confirmed').should('be.visible');This Cypress example observes the application request; it does not prove that a third-party callback arrived. Add the provider or clone step your workflow supports, and keep the callback test separate when the browser cannot observe it directly.
Exercise delay, duplication, and rejection.
Choose failure cases that change customer treatment: a timeout, a 429, a 5xx, an invalid signature, a duplicate event, an out-of-order event, or a missing object. Assert the intended pending, retry, rejection, or recovery state. Do not claim that a generic mock tests provider behavior unless its payloads, headers, and signing rules match the contract you depend on.
Keep a small compatibility check against the provider’s authorized test environment. Run it when you update API versions or integration code. A clone can make your application logic repeatable; it cannot establish that an undocumented provider edge case behaves the same way.
Inspect a complete customer task before expanding.
For an invitation, check that the admin creates the invitation, the intended inbox receives the link, the recipient accepts it, and the new account receives the right membership. Keep browser steps and downstream records linked to the same run.
The Molar invitation example is a controlled scripted test with email and identity clones. For your app, start with one integration and make its endpoint, account, callback, reset, and failure behavior explicit. Then talk to us if the supported path matches the task you need to protect.
Keep a contract check beside the repeatable integration test.
When you change an SDK, provider API version, or webhook schema, run a small compatibility check against the provider’s authorized test environment. Verify the request method, required headers, response fields, signing format, and error codes your application actually consumes. Store the expected contract in code or fixtures so a review can see what changed.
Then run the larger scenario against a mock or clone from a known state. If the two checks disagree, first ask whether the substitute is stale or whether the application relied on an undocumented provider behavior. The split keeps repeatable local feedback fast while preserving one direct signal that the integration still matches its external contract.