Notes on TDD

Test-Driven Development is not about testing.

The best way to design your code is to refactor it.

Unit tests let you refactor safely
and capture the intent of your code.

To refactor often, tests must run quickly.

The TDD loop

  1. Write a test that describes one behavior.
  2. Watch the test fail (red).
  3. Write the simplest code you can to make the test pass.
  4. Watch the test pass (green).
  5. Refactor anything you want as long as the tests are green.

Applications to Brackets

  • Have both fine-grained unit tests and larger integration tests. Unit tests don't tell you about overall workflow.
  • Unit tests should run really fast. It's okay for integration tests to run slower.
  • To make tests that run fast, mock dependencies as much as possible.
  • Writing tests first helps you capture each behavior as you think of it. It won't help you capture cases you haven't thought of.
  • It's okay to build tests that know about "private" implementation. Just be aware of the tradeoffs.

Unit testing UI

  • Unit test UI by treating the DOM as data and building DOM fixtures.
  • (This is harder to apply to complex things, like CodeMirror and tree view.)
  • Using simplified DOM fixtures forces you to make fewer assumptions about overall UI.

Mocking and dependencies

  • Use mock editors and documents where possible instead of whole windows.
  • We should try to decouple more modules, especially from ProjectManager.
  • "Spies" are a useful tool for stubbing or monitoring function calls.
  • We should try to figure out a way to do dependency injection with require.
  • "Mockjax" is a useful way to stub out AJAX calls.

Miscellaneous thoughts

  • Async testing in qunit is kind of sucky.
  • Could we add phantomjs to our process to do headless unit testing?

Q & A