Test Pyramid vs Testing Trophy vs Honeycomb: Which Model Fits Your Team
Test pyramid vs testing trophy vs testing honeycomb compared: what each model says, where each fits (back end, React apps, microservices), a choosing checklist and a worked example.

Last updated 2026-11-04 · 14 min read · By SoftwareTestPilot
Quick answer: the test pyramid says most of your automated tests should be fast unit tests, with fewer integration tests and very few end-to-end tests. The testing trophy moves the biggest share to integration tests and adds static checks (types, linting) at the base. The testing honeycomb, written for microservices, puts most effort into tests that exercise a whole service through its real interfaces, with very few tests of internal details. None of them is "correct" everywhere. The right shape depends on where your bugs actually come from.
If you are new to the idea of layered testing, read our test pyramid explained guide first, then come back here for the comparison.
Key takeaways
- All three models answer one question: where should most of your testing effort go?
- The pyramid suits code with lots of business logic and stable interfaces between parts.
- The trophy suits front-end apps, where most bugs appear when components work together.
- The honeycomb suits microservices, where most risk sits at the boundaries between services.
- Your own bug history is a better guide than any diagram.
1. Why Testing Models Exist at All
Every automated test has a cost and a benefit. The cost is the time to write it, the time to run it, and the time spent fixing it when it fails for no good reason (a "flaky" test). The benefit is the confidence it gives you that the software works.
Different kinds of tests sit at different points on that trade-off:
- Unit tests check one function or class on its own. They run in milliseconds and rarely flake, but they can pass even when the real system is broken, because they do not test how the parts connect.
- Integration tests check that several parts work together: a service and its database, a React component and its child components, or an API and the code behind it.
- End-to-end (E2E) tests drive the whole application the way a user would, usually through a browser with a tool like Playwright or Selenium. They give the most realistic confidence but are the slowest and most likely to flake.
The pyramid, trophy and honeycomb are three ways of drawing the ideal mix. The width of each layer stands for how much of your effort, or how many of your tests, should go there.
2. The Test Pyramid
The test pyramid was popularised by Mike Cohn in his 2009 book Succeeding with Agile and later explained in detail by Martin Fowler and Ham Vocke in The Practical Test Pyramid.
/\
/E2E\ few, slow, realistic
/------\
/ Integ. \ some
/------------\
/ Unit \ many, fast, isolated
/------------------\
The idea: write lots of small, fast tests at the bottom, fewer at each level above. A ratio such as 70% unit, 20% integration, 10% E2E is often quoted as a rule of thumb. It is a starting point, not a law.
Where it works well:
- Back-end services with a lot of business rules (pricing, tax, permissions, calculations).
- Libraries and SDKs where most behaviour can be checked function by function.
- Teams whose CI pipeline must stay fast, because unit tests give feedback in seconds.
Where it struggles: when most of the code is "glue" (calling other services, mapping data, rendering UI), unit tests end up mocking almost everything. They pass while the real system fails, and they break whenever the internal code is reorganised.
3. The Testing Trophy
The testing trophy was introduced by Kent C. Dodds in 2018, building on Guillermo Rauch's advice: "Write tests. Not too many. Mostly integration." See Kent's original article.
___E2E___ a few
| |
| Integr- | the largest layer
| ation |
\ Unit / some
\______/
[ Static ] types + linting, the base
What is different:
- Static checks become a layer of their own. TypeScript and ESLint catch typos, wrong types and unused code before any test runs.
- Integration tests become the biggest layer. In a front-end app this usually means rendering a component with its real children and checking what the user sees, for example with Testing Library.
- Unit tests are kept for genuinely complex pure logic (date maths, formatting, reducers).
Where it works well: React, Vue and other single-page apps, where most bugs come from components interacting, state being passed wrongly, or the UI not matching the data. Testing each component in isolation with everything mocked tends to miss exactly those bugs.
Where it struggles: integration tests are slower than unit tests, so a suite of thousands needs parallel runs. In back-end code with heavy business rules, the pyramid is usually cheaper.
4. The Testing Honeycomb
The honeycomb comes from Spotify's engineering team, described in the January 2018 post Testing of Microservices.
/‾‾‾‾‾‾‾‾‾‾\
| Integrated | few: tests across several services
|------------|
| |
| Integration| most: one service, real interfaces
| |
|------------|
| Impl. detail| few: tests of internal code
\__________/
The idea: in a microservice, the code inside is often small and simple. The risk sits at the edges: the API it exposes, the database it writes to, and the other services it calls. So most tests should start the service (often with a real database in a container) and talk to it through its real API.
- Implementation-detail tests (the honeycomb's word for unit tests) are used only where internal logic is genuinely complex.
- Integration tests are the bulk: call the service's endpoints and check the responses and side effects.
- Integrated tests span several deployed services and are kept to a minimum, because they are slow and depend on other teams' systems.
Contract tests fit naturally here. Tools such as Pact let each service check that it still meets what its consumers expect, without running every service together.
5. Side-by-Side Comparison
| Pyramid | Trophy | Honeycomb | |
|---|---|---|---|
| Introduced by | Mike Cohn (2009) | Kent C. Dodds (2018) | Spotify engineering (2018) |
| Largest layer | Unit | Integration | Integration (one service) |
| Static checks | Not a layer | The base layer | Not a layer |
| Typical fit | Logic-heavy back end, libraries | Front-end and single-page apps | Microservices |
| Main strength | Fast, stable feedback | Tests match how users use the app | Catches boundary and contract bugs |
| Main risk | Over-mocking hides real failures | Slower suite, needs parallel runs | Needs container or test-environment setup |
| E2E tests | Few | Few | Few |
Notice the last row. All three agree that browser E2E tests should be a small, carefully chosen set covering the most important user journeys. The disagreement is only about the middle and the bottom.
6. Example Starting Mixes by Project Type
These are starting points to adjust, not measured industry figures. Count tests or, better, the time you spend on each layer, and revisit after a few months.
| Project type | Closest model | Unit | Integration | E2E |
|---|---|---|---|---|
| Back-end API with heavy business rules | Pyramid | about 60–70% | about 20–30% | about 5–10% |
| React / Next.js web app | Trophy (plus TypeScript and linting) | about 20–30% | about 50–60% | about 10–15% |
| Microservices platform | Honeycomb (plus contract tests) | about 15–25% | about 60–70% | about 5–10% |
| Legacy app with no tests yet | Start top-down, then reshape | low at first | growing | a handful of smoke journeys first |
The legacy row is worth explaining. When an old app has no tests, a few E2E "smoke" tests on the main journeys (log in, search, check out) give the quickest safety net. As you refactor, you add lower-level tests and the shape slowly moves towards whichever model fits.
7. How to Choose: A Five-Question Checklist
- Where did your last 20 production bugs come from? Label each one: wrong logic, two parts not working together, a broken service boundary, or a UI problem. Put more tests where most bugs cluster.
- How much of your code is business logic versus glue? More logic points to the pyramid; more glue points to the trophy or honeycomb.
- Is it one application or many services? Many independently deployed services point to the honeycomb with contract tests.
- How fast must CI be? If pull requests must get feedback in under ten minutes, keep the slow layers small and run them in parallel.
- Do your tests break when you refactor without changing behaviour? If yes, you are testing implementation details. Move effort up a layer.
Question 1 matters most. A team that tracks where bugs come from will drift towards the right shape whatever diagram they started with.
8. Shapes to Avoid
- The ice-cream cone: mostly manual and E2E tests, very few unit or integration tests. Slow, flaky and expensive. Common when automation is owned only by a separate QA team.
- The hourglass: many unit tests, many E2E tests, almost nothing in between. Bugs where parts connect slip through, and the E2E suite gets blamed.
- The mock forest: a "pyramid" on paper, but every unit test mocks every dependency. Coverage looks high while real failures go unnoticed.
- Copying a diagram: adopting a shape because a well-known company uses it, without checking whether your bugs look like theirs.
Flaky tests make every shape worse. If your upper layers are unstable, fix that first with our guide to the causes of flaky tests and their fixes.
9. Changing Shape Without Breaking CI
Moving from an ice-cream cone to a healthier shape is gradual. A safe sequence:
- Measure first. List your tests by layer, average run time and failure rate over the last month.
- Pick the slowest or flakiest E2E test. Work out which risk it actually covers, for example "discount is applied at checkout".
- Write a lower-level test for that risk. An API or component integration test usually covers the same rule in a fraction of the time.
- Run both for a sprint. Only delete the E2E test once the new test has proved stable.
- Keep the journey, not the details. Leave one E2E test per critical user journey; move edge cases down.
- Add static checks. Turning on strict TypeScript and linting is the cheapest layer to add and removes a whole class of bugs.
Never delete E2E tests in bulk just to "match the pyramid". You lose real protection before the replacement exists.
10. Worked Example: One Feature Tested Three Ways
Take a "apply coupon code at checkout" feature in an online shop.
Pyramid approach: a dozen unit tests of the discount calculator (percentage, fixed amount, expired code, minimum order), two integration tests checking the checkout service stores the discounted total, and one E2E test applying a valid code in the browser.
Trophy approach: TypeScript ensures the coupon object always has the right fields. Most tests render the checkout page component with a mocked network layer and check what the user sees for valid, expired and invalid codes. A few unit tests cover the calculator's tricky rounding. One E2E test covers the happy path.
Honeycomb approach: the coupon service runs in a container with a real database. Tests call its POST /coupons/apply endpoint for each case and check both the response and the stored order. A contract test confirms the checkout service still sends the fields the coupon service expects. One E2E journey runs in a staging environment.
// Honeycomb-style integration test (Playwright API testing)
import { test, expect } from '@playwright/test';
test('expired coupon is rejected with a clear message', async ({ request }) => {
const res = await request.post('/coupons/apply', {
data: { orderId: 'order-123', code: 'SUMMER-EXPIRED' },
});
expect(res.status()).toBe(422);
expect(await res.json()).toMatchObject({ error: 'COUPON_EXPIRED' });
});
All three test the same feature. They differ in where the confidence comes from. You can practise exactly this kind of API test for free in our API Playground.
11. How to Answer This in an Interview
"Pyramid or trophy?" is a common QA and SDET interview question. A strong answer has three parts:
- Show you know all three: name each model and what its biggest layer is.
- Say it depends, then say on what: the type of system and where its bugs come from.
- Give a real example: "On our React app we moved most component tests to integration-style tests with Testing Library, kept about ten Playwright journeys, and our flaky failures dropped."
Avoid saying any one shape is always right. Interviewers are checking judgement, not memorised diagrams. For more practice, see our software testing interview questions or ask other testers in the QA Community.
12. Summary
- Pyramid: mostly unit tests. Best for logic-heavy back ends.
- Trophy: static checks plus mostly integration tests. Best for front-end apps.
- Honeycomb: mostly service-level integration tests plus contract tests. Best for microservices.
- All three: keep end-to-end tests few and focused on critical journeys.
- Above all: let your own bug history decide, and reshape gradually.
To go deeper on the classic model, read the test pyramid explained. To build the automation skills behind any of these shapes, the Playwright course covers unit-style, API and browser testing in one framework.
