1. Test output (how the DOM changes), not what happens behind the scenes (implementation)
Think about the user’s perspective and how they would interact with the components. Testing output allows you to change implementation without affecting output. That means tests only break when there’s an actual functionality change.
2. Make reusable components that can be tested in isolation
They’re easier to test and make tracking down changes faster.
3. Cut down on the amount of DOM rendering in tests
When setting up your tests, prefer before not beforeEach to cut down on repeat renderings. It can slow things down considerably.
4. Isolate mutations to test contexts
Relying on other cases mutating state or DOM leads to brittle tests that are hard to refactor or reason about. Test blocks’ contexts should be self-sufficient. Resist the urge to share data.
5. Be explicit and don’t abstract too much setup or repetition
Writing out and repeating steps makes it easier to scan the code while you’re under stress.
6. Choose a tool that allows you to isolate cases for a faster feedback cycle
Have and use the ability to isolate a test or tests, without running them all. It’s easier to focus and faster to find the change.
7. Turn on source maps, if applicable
Get pointed to the source code quicker, if you’re using a compiler.
8. Use a headless browser and rerun tests when files change
The key to TDD is speed, speed, speed.
9. Allow for in-browser debugging
Sometimes you just need those Chrome dev tools (and maybe Firefox or Safari).
10. Name your test blocks consistently
File names, methods, modules.
11. Make your describe, context, and it descriptions human-readable
Mad Libs–style: [Module name], when [state], (and), it [behavior]
12. Include polyfills, if testing on multiple browsers
Browsers behave differently, especially older versions of PhantomJS versus something like Chrome. A polyfill such as es5-shim will get you to parity.
13. Use a pluggable expectation system for more meaningful assertions
For example, chai-jsx (or expect-jsx or jasmine-expect-jsx), if you’re using React, allows you to assert with JSX on a component. Same goes for libraries such as Immutable.js, Sinon, and bluebird.
14. Fail the build on console.error
A third-party developer is politely telling you there’s been a horrible problem, without crashing your app (isn’t that all you can ask for in a client-side app?). This happens with PropType validation errors in React.