Software Testing & QA

Integration and API Testing

35 мин

Use the same database engine as production

SQLite is fast for tests, but it behaves differently from PostgreSQL in places (types, constraints, DISTINCT ON, case sensitivity, concurrent writes). Run at least your CI suite against PostgreSQL:

services:
  postgres:
    image: postgres:16
    env: { POSTGRES_PASSWORD: postgres }
    ports: ["5432:5432"]

Locally, Testcontainers starts a throwaway PostgreSQL in Docker for the test session.

Transactions for speed

Instead of recreating tables for every test, wrap each test in a transaction and roll it back at the end. Tables are created once per session and each test still starts clean.

Testing JSON APIs

def test_hash_api(client):
    resp = client.post("/tools/api/hash", json={"text": "hello"})
    assert resp.status_code == 200
    body = resp.get_json()
    assert body["sha256"].startswith("2cf24dba")

def test_hash_api_rejects_huge_input(client):
    resp = client.post("/tools/api/hash", json={"text": "x" * 200_000})
    assert resp.status_code == 413

Test the contract: status codes, response shape, error messages and limits.

External APIs: record or fake

  • responses or respx intercept HTTP calls and return canned responses, so tests run offline.
  • VCR.py records real responses once and replays them.
  • Stripe provides test mode keys and test card numbers (4242 4242 4242 4242) for end-to-end checks in staging.
import responses

@responses.activate
def test_fetches_exchange_rates():
    responses.get("https://api.rates.example/latest", json={"eur": 0.92})
    assert get_rate("eur") == 0.92

Testing webhooks

Construct a signed payload the way the provider would and post it to your endpoint:

def test_stripe_webhook_rejects_bad_signature(client):
    resp = client.post("/webhooks/stripe", data=b"{}", headers={"Stripe-Signature": "t=1,v1=bad"})
    assert resp.status_code == 400

Also test that delivering the same event twice has no double effect.

Contract tests

When a frontend and backend (or two services) are developed separately, contract tests check both sides agree on request and response shapes. A shared OpenAPI schema validated in both test suites is a lightweight way to do this.

Check yourself

  • Name two ways SQLite and PostgreSQL behave differently.
  • How do you test code that calls an external API without the network?
  • Which webhook behaviour must be tested besides the signature?

Ваш прогресс сохраняется только в этом браузере.

Отправить на проверку (10 баллов)