Tests assert behavior through supported interfaces, not internals

test-008

Intent

Tests that couple themselves to private structure or unofficial seams fail on harmless refactors while missing the supported behavior users actually rely on.

Applicability

Applies when the diff adds or changes tests for code that has a supported public API, event, persisted effect, or boundary-visible result. Return unknown when the internal structure itself is the explicit contract.

What to inspect

Review changed assertions and whether they inspect private fields, internal helpers, or unofficial seams instead of a supported result or effect.

Pass criteria

Tests exercise the behavior through the supported public surface and assert the externally visible result, state, or emitted artifact.

Fail criteria

The test’s main evidence depends on private fields, internal collections, helper-only state, reflection into private methods, or lower layers that bypass the supported contract.

Do not flag

Parser or codec tests where the returned structure is itself the contract, or white-box regressions where no stable external surface exists and that constraint is explicit.

Confidence guidance

HIGH when the test directly inspects private implementation details. MEDIUM when the coupling is obvious but the supported surface is partly inferred. LOW when the intended contract is ambiguous.

Remediation

Rewrite the test to use the supported public interface and assert the observable behavior instead.

Pass example

def test_render_message():
    assert MessageRenderer().render(Message('h', 'b', 'f')) == '<h1>h</h1><b>b</b><i>f</i>'

Fail example

def test_renderer_structure():
    renderer = MessageRenderer()
    assert type(renderer._sub_renderers[0]).__name__ == 'HeaderRenderer'

Sources

  • Growing Object-Oriented Software, Guided by Tests — Steve Freeman & Nat Pryce book
  • Practical Test Pyramid — Ham Vocke article
  • Software Engineering at Google — Titus Winters, Tom Manshreck, Hyrum Wright book
  • Unit Testing: Principles, Practices, and Patterns — Vladimir Khorikov book
  • xUnit Test Patterns: Refactoring Test Code — Gerard Meszaros book