Skip to main content
Software Engineering

Writing Effective Unit Tests: Quality Over Quantity

Stop chasing coverage numbers. Learn to write tests that catch real bugs, document behavior, and give you confidence to refactor.

Mbeah Essilfie

Mbeah Essilfie

May 6, 2026 at 06:04 AM

8 min read 541 views
Writing Effective Unit Tests: Quality Over Quantity

Coverage Is Not Quality

100% code coverage with bad tests gives false confidence. 70% coverage with well-chosen tests catches more real bugs.

What Makes a Good Test?

  1. Tests behavior, not implementation — Survives refactoring
  2. Has a clear assertion — One logical assertion per test
  3. Fails for the right reason — Catches actual bugs, not false positives
  4. Is readable — Serves as documentation
  5. Is fast — Runs in milliseconds

The AAA Pattern

describe('calculateDiscount', () => {
  it('applies percentage discount to order total', () => {
    // Arrange
    const order = createOrder({ subtotal: 100 })
    const coupon = { type: 'percentage', value: 20 }

    // Act
    const result = calculateDiscount(order, coupon)

    // Assert
    expect(result.total).toBe(80)
    expect(result.savings).toBe(20)
  })
})

Test Boundaries, Not Internals

// ❌ Testing implementation (brittle)
it('calls formatDate with the correct args', () => {
  const spy = vi.spyOn(utils, 'formatDate')
  renderPost(post)
  expect(spy).toHaveBeenCalledWith(post.date, 'YYYY-MM-DD')
})

// ✅ Testing behavior (resilient)
it('displays the post date in readable format', () => {
  const post = createPost({ date: new Date('2024-01-15') })
  const { getByText } = renderPost(post)
  expect(getByText('January 15, 2024')).toBeDefined()
})
Ask: "If I refactor the internals without changing behavior, will this test still pass?" If no, you're testing implementation details.

Edge Cases Worth Testing

describe('parseEmail', () => {
  it('accepts valid emails', () => {
    expect(parseEmail('user@example.com')).toEqual({ valid: true })
  })

  // Edge cases that catch real bugs:
  it('rejects emails without @', () => {
    expect(parseEmail('userexample.com')).toEqual({ valid: false })
  })

  it('handles plus addressing', () => {
    expect(parseEmail('user+tag@example.com')).toEqual({ valid: true })
  })

  it('rejects empty string', () => {
    expect(parseEmail('')).toEqual({ valid: false })
  })

  it('handles unicode domains', () => {
    expect(parseEmail('user@münchen.de')).toEqual({ valid: true })
  })
})

Test Factories

// Create realistic test data without boilerplate
function createPost(overrides?: Partial<Post>): Post {
  return {
    id: randomUUID(),
    title: 'Test Post',
    slug: 'test-post',
    content: 'Test content',
    status: 'published',
    authorId: randomUUID(),
    createdAt: new Date(),
    ...overrides,
  }
}

// Usage — only specify what's relevant to THIS test
it('shows draft badge for unpublished posts', () => {
  const post = createPost({ status: 'draft' })
  // ...
})

When NOT to Unit Test

  • Trivial getters/setters
  • Framework boilerplate (Vue template rendering details)
  • One-line wrapper functions
  • Third-party library behavior

Integration Tests Fill the Gap

describe('POST /api/posts', () => {
  it('creates a post and returns it with generated slug', async () => {
    const response = await request(app)
      .post('/api/posts')
      .send({ title: 'My New Post', content: '...' })
      .expect(201)

    expect(response.body.data.slug).toBe('my-new-post')
    // Verify it's actually in the database
    const saved = await db.post.findUnique({ where: { slug: 'my-new-post' } })
    expect(saved).not.toBeNull()
  })
})

Write tests that give you confidence. If a test doesn't make you confident about a deployment, it's not pulling its weight.

JavaScriptTypeScriptTesting
Mbeah Essilfie

Written by Mbeah Essilfie

Fullstack Software Developer

Read next

The Complete Guide to Vue 3 Composables
12 min read

The Complete Guide to Vue 3 Composables

Understand the power of Vue 3's Composition API through practical, real-world composable patterns that you can use today.

Mbeah EssilfieMbeah Essilfie
987