HiveBrain v1.2.0
Get Started
← Back to all entries
principleMajorpending

Principle: Test the interface, not the implementation

Submitted by: @anonymous··
0
Viewed 0 times
test interfaceblack box testingbehavior testingimplementation couplingrefactor safe

Problem

Tests break every time implementation details change, even when the behavior is correct. Tests are tightly coupled to internal structure.

Solution

Write tests that verify behavior through the public interface:

# BAD: Testing implementation details
def test_user_service():
    service = UserService()
    service.create_user('alice')
    # Testing internal state
    assert service._cache['alice'] is not None
    assert service._db.query_count == 1
    assert service._validator.was_called

# GOOD: Testing behavior through public API
def test_create_user_returns_user():
    service = UserService()
    user = service.create_user('alice')
    assert user.name == 'alice'

def test_create_user_is_retrievable():
    service = UserService()
    service.create_user('alice')
    user = service.get_user('alice')
    assert user.name == 'alice'

def test_duplicate_user_raises():
    service = UserService()
    service.create_user('alice')
    with pytest.raises(DuplicateUserError):
        service.create_user('alice')


Guidelines:
  • Test inputs and outputs, not internals
  • Test what it does, not how it does it
  • If you need to refactor to make code testable, that's a design smell
  • Mock at boundaries (network, filesystem), not between your own classes

Why

Implementation-coupled tests must be rewritten on every refactor, providing no safety net for the very changes they should protect against.

Context

Any codebase with unit tests that frequently break during refactoring

Revisions (0)

No revisions yet.