Interview frequency: …
Short answer
The Test Pyramid suggests a broad base of fast, inexpensive unit tests, a smaller middle layer of integration tests, and a pointed top of complex, slow end-to-end (E2E) tests.
Explanation
Unit Tests check isolated functions and classes in microseconds, quickly pinpoint failures, and are cheap to maintain. Integration Tests check that several real components work together, such as a service and its database. E2E tests simulate a real user in a browser. They are great for building confidence before release but are very slow, costly, and prone to flakiness. Relying on an inverted pyramid (the Ice Cream Cone anti-pattern) kills development speed.
Code example
# Unit test — milliseconds, many of them
def test_total_with_tax():
assert total(100, tax=0.14) == 114
# Integration test — real database, fewer
@pytest.mark.integration
def test_order_is_saved(db):
repo = OrderRepository(db)
repo.add(Order(id=1, total=50))
assert repo.get(1).total == 50
# End-to-end test — real browser, very few and only for critical journeys
def test_checkout_flow(page):
page.goto("/cart")
page.click("text=Checkout")
expect(page.locator("h1")).to_have_text("Order confirmed")Common mistakes
- Writing most tests as E2E and ignoring unit tests, making CI/CD builds take hours and fail randomly.