AkiVaMu Just tiny things come to mind...

Software Testing

Below are collections of article against heavy unit testing.

A1. Write tests. Not too many. Mostly integration

  • Write tests
    • Static typing and linting tools
    • Write tests
  • Not too many
    • No need 100% coverage because of maintainence cost when refactoring
    • Still need 100% coverage for libraries
  • Mostly integration

Tradition

vs

Lean

A2. Lean Testing

  • End-to-end tests provide the greatest confidence, with highest time cost (implementation & execution)
  • Integration tests provide the best balance of cost, speed and confidence
  • Unit tests provides less cost to write and faster to run, but they test only a small part that might not even be critical

Summary:

  • Use a typed language.
  • Focus on integration and end-to-end tests.
  • Use unit tests only where they make sense (e.g. pure algorithmic code with complex corner cases)

A3. Giving up on test-first development

Unit test:

  • You become conservative to avoid breaking lots of tests
    • More reluctant to make large-scale changes
  • Makes you focus on detail rather than structure

A4. Unit Test Fetish

  • Return on investment of unit tests is an order(s) of magnitude lower than that of end-to-end tests.
  • End-to-end tests test the critical path. Unit test do not.
  • Unit tests ossify the internal architecture.
  • There are things that can’t be unit-tested.
  • Some stuff has no rigorous acceptance criteria.
  • Unit tests are easy to measure and you should fear that.

Below are collections of article support unit testing.

B1. The Failures of “Intro to TDD”

  • Failure #1: Encouraging Large Units
    • Solution: refactoring after every test passed (Red-Green-Refactor)
  • Failure #2: Encouraging Costly Extract Refactors
  • Failure #3: Characterization Tests of Greenfield Code
  • Failure #4: Redundant test coverage
  • Failure #5: Eliminating Redundancy Sacrifices Regression Value
  • Failure #6: Making a Mess with Mocks

A Successful Approach to TDD

See the detail in post.

Basically:

  • Top-down approach
  • Fake it until you make it

My take away

  • Unit test has quick feedback cycle
  • Refactoring internal code of unit (keep same public interface):
    • Unit test is great
    • Quickly test if refactored unit is working
  • Refactoring public interface:
    • Unit test is bad: requires more maintainance cost
    • Should prevent changes in public interface. How? -> Top-down approach
  • E2E test:
    • Quickly spot behavior bug
    • Test critical paths
    • Bad at: hard to cover all cases/edge

Conclusion: Unit test and e2e test are complementary

  • Unit Test:
    • Quick feedback
    • Useful for clear-defined requirement/responsibility of unit
    • Cover edge cases
    • Support internal refactoring/optimization
  • E2E:
    • Useful for overall behavior, user scenario
    • Cover large areas, critical paths