$30 off During Our Annual Pro Sale. View Details »

Oh Snap!

Oh Snap!

Gaining leverage over legacy CLI apps with snapshot testing

Dan Miller

July 06, 2017
Tweet

More Decks by Dan Miller

Other Decks in Programming

Transcript

  1. Oh Snap! Gaining leverage over legacy CLI apps with snapshot

    testing Dan Miller Rogue Software Engineer @jazzdan https://dmiller.io
  2. @jazzdan Overview •What are snapshot tests? •How do you use

    them? •A tale from production!
  3. Who is this person?

  4. None
  5. None
  6. None
  7. None
  8. @jazzdan I love testing

  9. Snapshot Testing

  10. Code Produces Output

  11. @jazzdan Assert that the output doesn’t change

  12. Code Produces Output

  13. Code Produces Output

  14. @jazzdan Why is this especially useful for React?

  15. @jazzdan If the output changed, then your UI changed

  16. < A /> < C /> < D />

  17. < A /> < C /> < D />

  18. < A /> < B /> < C /> <

    D /> < D />
  19. < A /> < B /> < C /> <

    D /> < D />
  20. < A /> < B /> < C /> <

    D /> < D />
  21. Code Produces Output

  22. JSX Renders to DOM

  23. JSX Renders to DOM

  24. JSX Renders to DOM Text!

  25. Code Produces Serializable Output

  26. @jazzdan Show me the code!

  27. 1 test("Link renders correctly", () => { 2 const tree

    = renderer 3 .create(<Link page="http://queensjs.com"> 4 Queens JS</Link>) 5 .toJSON(); 6 expect(tree).toMatchSnapshot(); 7 });
  28. PASS ./Link.test.js ✓ renders correctly (15ms) Snapshot Summary › 1

    snapshot written in 1 test suite. Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 1 added, 1 total Time: 0.287s Ran all test suites related to changed files.
  29. 1 exports[`Link renders correctly 1`] = ` 2 <a 3

    className="normal" 4 href="http://queensjs.com" 5 onClick={[Function bound _onClick]}> 6 Queens JS 7 </a> 8 `;
  30. None
  31. Non-React Uses

  32. None
  33. None
  34. @jazzdan We wrote a web application

  35. @jazzdan We wrote a web application text editor

  36. @jazzdan We wrote a web application text editor database

  37. @jazzdan We wrote a web application text editor database
 compiler

  38. App Changed daily JSON Generated quarterly

  39. Node CLI App JSON JSON PHP SQL

  40. Code Produces Output

  41. Node CLI App JSON JSON PHP SQL

  42. Node CLI App JSON PHP SQL

  43. Node CLI App JSON JSON PHP SQL

  44. Node CLI App JSON PHP SQL Intermediate Representation

  45. Node CLI App Intermediate Representation

  46. @jazzdan It’s OK if the test fails!

  47. @jazzdan Tests tell you about change in the behavior of

    your system not necessarily a bug
  48. @jazzdan Snapshot tests are great for detecting changes

  49. @jazzdan Example Uses •CLI help menus •Error messages •Emails •CSVs,

    SVGs, etc
  50. Integrating in to your test runner

  51. @jazzdan npm install jest-snapshot

  52. // ... const toMatchSnapshot = function(received: any, testName?: string) {

    this.dontThrow && this.dontThrow(); const {currentTestName, isNot, snapshotState}: MatcherState = this; if (isNot) { throw new Error('Jest: `.not` cannot be used with `.toMatchSnapshot()`.'); } if (!snapshotState) { throw new Error('Jest: snapshot state must be initialized.'); } const result = snapshotState.match( testName || currentTestName || '', received, );
  53. class SnapshotState { _counters: Map<string, number>; _dirty: boolean; _index: number;

    _updateSnapshot: SnapshotUpdateState; _snapshotData: {[key: string]: string}; _snapshotPath: Path; _uncheckedKeys: Set<string>; added: number; expand: boolean; matched: number; unmatched: number; updated: number; }
  54. Snapshots built-in

  55. None
  56. None
  57. @jazzdan Thanks! Find me over a if you love testing

    too!
  58. @jazzdan More Resources • https://www.selenic.com/blog/?p=663 • https://glebbahmutov.com/blog/snapshot-testing/