liveBook · Manning

Test-driven development

As explained in Effective Platform Engineering

Test-driven development is a software development approach in which tests are written to specify expected behavior before implementing the corresponding code.

Test-driven development (TDD) specifies expected behavior with a test before implementing the change. For infrastructure code, the question is usually not whether a cloud provider’s API works. It is whether the deployed configuration meets the platform team’s requirements. section 6.3.5

Use the same cycle as for other software:

  • Write a test for the intended result and run it to see it fail. section 6.3.5
  • Write and apply the infrastructure code until the test passes. section 6.3.5
  • Refactor for readability, reduced duplication, or performance. section 6.3.5

Choose tests according to what the team controls. A reusable Terraform module warrants integration tests in a dedicated cloud account or project: its creator decides which resources and configurations the module provisions. When consuming an established module, test the story’s acceptance criteria rather than trying to retest the provider’s API. section 6.3.5

Test a subnet naming requirement

Suppose a subnet for managed nodes must support Karpenter and follow a naming convention. Test that the deployed subnet has the required tag values and pattern. A successful VPC deployment alone does not establish that the team’s naming requirement was met. section 6.3.5

…
private_subnets       = var.vpc_private_subnets
private_subnet_suffix = "private-subnet"
private_subnet_tags   = {
  "kubernetes.io/cluster/${var.cluster_name}" = "shared"
  "tier"                                      = "node"
  "karpenter.sh/discovery"                    = "${var.cluster_name}-vpc"
}

The VPC module parameters show the private-subnet suffix and tags that a configuration test can check, including the Karpenter discovery tag. section 6.3.5

Keep infrastructure tests useful after delivery. Run them as smoke tests following deployment and as nightly checks for configuration drift introduced by manual changes. An infrastructure pipeline needs these software-development practices, not just an infrastructure-as-code framework. section 6.3.3

For custom platform software, an architectural decision record can make TDD an explicit team rule. An architectural fitness function can then fail when a new service layer is checked in without associated tests; that guardrail enforces the practice rather than replacing behavior tests. section 2.3.3

How Effective Platform Engineering covers it

How deep it goes
Works through the failing-test, implementation, and refactoring cycle, then distinguishes module integration tests from acceptance-criteria checks.
Examples
Uses Karpenter subnet tags as acceptance criteria and proposes a fitness function that rejects service layers lacking tests.
What it assumes
Assumes familiarity with infrastructure pipelines and declarative configuration while spelling out the TDD workflow for infrastructure code.
What you can do after
Practice/perform it by writing a failing infrastructure test, applying code until it passes, and retaining the test for later checks.
How it connects
Connects TDD to Terraform modules, integration testing, configuration drift, architectural decision records, and architectural fitness functions.

Also explained in

Compare how 15 books explain test-driven development →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Effective Platform Engineering. The section links point to the parts of the book it draws on.