Skip to content

Testing Types: Unit, Integration, and E2E

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Testing Types: Unit, Integration, and E2E. We cover key concepts, practical examples, and best practices to help you master this topic.

API testing spans three levels: unit tests check individual functions, integration tests verify component interaction, and end-to-end tests validate complete workflows. Each level serves a different purpose in the quality assurance strategy.

What You'll Learn

  • Unit Testing for API business logic
  • Integration Testing for database and service interaction
  • End-to-end testing for full system validation
  • Mock vs real dependencies at each level

Why It Matters

The testing pyramid guides investment: many fast unit tests, fewer slower integration tests, and a handful of critical e2e tests. Proper balance catches bugs efficiently.

Real-World Use

Google's testing blog recommends 70% unit, 20% integration, 10% e2e. Stripe follows this model. GitHub's API tests are primarily integration tests with mocked external services.

flowchart TD
    Unit[Unit Tests] --> Fast[Fast, No Network]
    Unit --> Test[Test Business Logic]
    Integration[Integration Tests] --> Medium[Medium Speed]
    Integration --> Test2[Test API + DB + Services]
    E2E[E2E Tests] --> Slow[Slow, Full Stack]
    E2E --> Test3[Test Complete Workflows]

Teacher Mindset

Start with unit tests for validation and business logic. Add integration tests for each endpoint. Add e2e tests for critical user journeys. Mock external services at the unit level but use real dependencies at the e2e level.

Code Examples

// Example 1: Unit test for validation logic
describe('validateEmail', () => {
  it('returns true for valid email', () => {
    expect(validateEmail('user@example.com')).toBe(true);
  });

  it('returns false for invalid email', () => {
    expect(validateEmail('not-an-email')).toBe(false);
  });
});
// Example 2: Integration test with database
describe('POST /api/users', () => {
  beforeEach(async () => {
    await db.migrate.latest();
  });

  afterEach(async () => {
    await db.migrate.rollback();
  });

  it('creates user in database', async () => {
    const res = await request(app)
      .post('/api/users')
      .send({ name: 'Alice', email: 'alice@test.com' })
      .expect(201);

    const user = await db('users').where({ email: 'alice@test.com' }).first();
    expect(user).toBeDefined();
    expect(user.name).toBe('Alice');
  });
});
// Example 3: E2E test for full workflow
describe('User registration and login', () => {
  it('completes full registration workflow', async () => {
    // Register
    const register = await request(app)
      .post('/api/auth/register')
      .send({ name: 'Bob', email: 'bob@test.com', password: 'Pass123!' })
      .expect(201);

    const token = register.body.token;

    // Access protected resource
    const profile = await request(app)
      .get('/api/users/me')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(profile.body.name).toBe('Bob');
  });
});

Common Mistakes

  • Writing integration tests that mock the database (defeats the purpose)
  • Writing e2e tests for every edge case (too slow and brittle)
  • Not having enough unit tests for business logic
  • Using the same test data setup for all test levels
  • Not cleaning up state between test runs

Practice

  1. Write a unit test for an input validation function.
  2. Write an integration test that hits the API and checks the database.
  3. Write an e2e test for a multi-step workflow.
  4. Refactor a slow e2e test into a faster integration test.
  5. Challenge: Measure test execution time for each level and calculate the ratio.

FAQ

How do I decide if a test should be unit, integration, or e2e?

Unit tests: single function with no IO. Integration tests: API endpoint with real dependencies. E2E tests: complete user journey across services.

Should I test the database layer separately?

Integration tests that hit the API and verify database state effectively test the database layer as part of the integration.

How many e2e tests do I need?

Cover the 3-5 most critical user journeys. Keep e2e tests to under 10% of your total test suite.

Can I run all test levels in CI?

Run unit and integration tests on every commit. Run e2e tests on merge to main or scheduled jobs.

What is the cost of each test level?

Unit: milliseconds, Integration: seconds, E2E: minutes. Optimize the fast tests for coverage and the slow tests for critical paths.

Mini Project

Choose an API endpoint and write: a unit test for its validation logic, an integration test that calls the endpoint and checks the database, and an e2e test that exercises the complete user flow including the endpoint.

What's Next

Next, you will learn about Postman basics for manual and automated API testing.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro