# The Testing Pyramid and Automation Strategy

Understand the testing pyramid, the role of each testing level, and how to build an effective test automation strategy with SHAFT Engine.

Canonical HTML: https://shafthq.github.io/docs/reference/guides/Testing_Pyramid
Guide index: https://shafthq.github.io/llms.txt

The **testing pyramid** is a foundational concept in test automation strategy. It guides how many tests you should have at each level and where your automation investment delivers the most value.

---

## The Pyramid

```
 / UI / E2E \ ← Fewest, slowest, most expensive
 /───────────────\
 / Integration/API \ ← Balanced count, moderate speed
 /───────────────────\
 / Unit Tests \ ← Most numerous, fastest, cheapest
 /───────────────────────\
```

| Level | Speed | Cost | Scope | Typical Count |
|---|---|---|---|---|
| **Unit tests** | Very fast | Low | Single function or class | Thousands |
| **Integration / API tests** | Fast | Moderate | Service interactions, API contracts | Hundreds |
| **UI / E2E tests** | Slow | High | Full user flows through the UI | Tens to low hundreds |

---

## Why the Pyramid Matters

Each level serves a different purpose:

### Unit Tests (Base)

- Test individual functions, methods, and classes in isolation.
- Run in milliseconds — fast feedback for developers.
- Catch logic errors early, before they propagate.
- **Owned by developers**, run on every commit.

### Integration / API Tests (Middle)

- Test how components interact — API endpoints, database queries, service contracts.
- Faster and more stable than UI tests.
- Catch issues in data flow, serialization, authentication, and business rules.
- **Where SHAFT's API testing shines** — use `SHAFT.API` to test REST endpoints efficiently.

### UI / E2E Tests (Top)

- Test the complete user journey through the real application interface.
- Catch visual regressions, workflow issues, and integration gaps.
- Slowest and most brittle — use sparingly for critical paths.
- **Where SHAFT's GUI testing shines** — use `SHAFT.GUI.WebDriver` for web and mobile.

:::warning
An **inverted pyramid** (more UI tests than unit tests) is a common anti-pattern. It leads to slow test suites, flaky results, and high maintenance costs. Aim for the right balance.
:::

---

## Applying the Pyramid to Your Strategy

### Step 1: Identify What to Automate at Each Level

| Question | Level |
|---|---|
| Does this test validate a single calculation or transformation? | **Unit** |
| Does this test verify an API contract, request/response, or service interaction? | **API / Integration** |
| Does this test need a real browser or mobile device to verify a user workflow? | **UI / E2E** |

### Step 2: Maximize API Coverage

API tests provide the best **cost-to-coverage ratio**. They are fast, stable, and cover the business logic that powers both the web and mobile UIs:

```java title="ApiTest.java"

public class ApiTest {
 private SHAFT.API api;

 @Test(description = "Verify user creation API")
 public void testCreateUser() {
 api = new SHAFT.API("https://api.example.com");
 api.post("/users")
 .setRequestBody("{\"name\": \"John\", \"email\": \"john@example.com\"}")
 .setContentType("application/json")
 ;
 api.assertThatResponse().extractedJsonValue("name").isEqualTo("John");
 api.assertThatResponse().extractedJsonValue("email").isEqualTo("john@example.com");
 api.verifyThatResponse().statusCode().isEqualTo(201);
 }
}
```

### Step 3: Reserve UI Tests for Critical Paths

Use UI tests only for the most important user journeys — login, checkout, core workflows:

```java title="CriticalPathTest.java"

public class CriticalPathTest {
 private SHAFT.GUI.WebDriver driver;

 @Test(description = "Verify complete checkout flow")
 public void testCheckoutFlow() {
 driver = new SHAFT.GUI.WebDriver();
 driver.browser().navigateToURL("https://example.com");
 // Login → Browse → Add to cart → Checkout → Confirm
 // Only the most critical path needs a full UI test
 }
}
```

---

## Where SHAFT Fits in the Pyramid

SHAFT Engine supports **every level** of the pyramid above unit tests:

| Level | SHAFT Module |
|---|---|
| API / Integration | `SHAFT.API` — REST API testing |
| CLI / Infrastructure | `SHAFT.CLI` — Terminal and file operations |
| Database | `SHAFT.DB` — Database queries and validations |
| UI / E2E (Web) | `SHAFT.GUI.WebDriver` — Browser automation |
| UI / E2E (Mobile) | `SHAFT.GUI.WebDriver` — Appium-based mobile automation |

:::info
By using one engine across all levels, you get a **consistent API, unified reporting, and shared configuration** — regardless of what type of test you are writing.
:::

---

## Best Practices

1. **Follow the pyramid shape** — more unit/API tests, fewer UI tests.
2. **Automate API tests first** when building a new automation suite — highest ROI.
3. **Use UI tests for critical paths only** — login, checkout, core business flows.
4. **Push testing down** — if you can verify something with an API test, do not use a UI test.
5. **Review your test distribution regularly** — measure how many tests exist at each level and rebalance.

## Related

- [Solution Design](/docs/reference/guides/Solution_Design)
- [Test Structure](/docs/reference/guides/Test_Structure)
- [Ci Cd Integration](/docs/reference/guides/CI_CD_Integration)
- [Quick Start](/docs/start/quick-start)
