Skip to content

Testing Approaches

An approach is how you design and drive tests, independent of what you test. Two axes matter most: how much of the implementation you can see, and when you write the test relative to the code.

Approach You see Typical use Weakness
Black-box Only inputs and outputs Acceptance, E2E, API, functional tests Misses untested internal branches
White-box The source code and structure Unit tests, coverage-, mutation-driven tests Can over-fit to implementation
Grey-box Some internal state/logs Integration tests, security testing Requires discipline to stay useful

You treat the system as an opaque box: given this input, expect that output. Tests survive refactors because they never touch internals.

import { test, expect } from 'vitest';
// No knowledge of how `add` is implemented.
test('add sums two numbers', () => {
expect(add(2, 3)).toBe(5);
});

You inspect structure. Coverage tools and mutation testing live here; so do tests that deliberately exercise a specific branch.

// White-box: we assert on the internal branch we just wrote.
if (items.length === 0) return { total: 0, empty: true };

Partially informed by internals — e.g. an integration test that seeds a database directly, or a security test that reads the app’s logs.

Practice Meaning Cycle
TDD — Test-Driven Development Write a failing test, make it pass, refactor Red → Green → Refactor
BDD — Behaviour-Driven Development Tests written as plain-language scenarios (Given/When/Then) Feature → Scenarios → Steps
ATDD — Acceptance-Test-Driven Development Acceptance criteria written as tests before coding Criteria → Test → Code
Test-after Tests written after the code Risky: the code “defines” correctness
1. RED — write a test that fails for the right reason
2. GREEN — write the minimum code to pass
3. REFACTOR — clean up, keep the test green

BDD scenarios are written in Gherkin so non-programmers can read them:

Feature: Login
Scenario: Reject a wrong password
Given a registered user "ada" with password "s3cret"
When the user signs in with password "wrong"
Then the user sees "Invalid credentials"

Robot Framework is a keyword-driven, Python-based automation framework with its own tabular, plain-language syntax — widely used for BDD-style acceptance and RPA. It needs no programming to write the high-level test:

*** Test Cases ***
Reject A Wrong Password
Given a registered user "ada" with password "s3cret"
When the user signs in with password "wrong"
Then the user sees "Invalid credentials"

Its ecosystem (SeleniumLibrary, RequestsLibrary, AppiumLibrary) makes it a strong choice for acceptance testing across web, API and mobile from one syntax.

Manual Automated
Best for Exploratory, usability, one-off checks Regression, repeated, high-volume
Cost profile Cheap to start, expensive to repeat Expensive to start, cheap to repeat
Evidence Human judgement, screenshots Deterministic pass/fail, artifacts

Most healthy teams do both: automate the regression suite, and reserve humans for exploratory and usability work where judgement is the point.

Self-assessment quiz

Pick one answer per question, then press Check answers.

  1. A test that never inspects internal state and only checks inputs against outputs is…
  2. In TDD, what is the first step of the cycle?
  3. Which practice writes acceptance criteria as executable scenarios in plain language?
  4. Which tool is a keyword-driven, Python-based framework often used for BDD-style acceptance and RPA?
  5. Which type of work is a poor fit for automation and best left to humans?