Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenWeekly.test.js

 OpenWeekly.test.js

Internal talk given at The New York Times introducing teams to Jest JavaScript testing.

Jeremy Gayed

February 01, 2017
Tweet

More Decks by Jeremy Gayed

Other Decks in Technology

Transcript

  1. Test Brackets App Module Module Service Dependency User Unit Test

    Functional Test Integration Test End-to-End Test
  2. Definitions Unit Tests - The narrowest test bracket. Concerned with

    a single module under test, all other dependencies are mocked. Changes to the module being tested most likely require changes to the unit test. Functional (Spec) Tests - Slightly wider test bracket than Unit Tests. It’s concerned with the interaction between two or more modules. It tests whether a given flow or set of modules matches the product specification. Changes to implementation details of modules should typically not require changes to these tests. Integration Tests - Tests the conformance to some contract between two applications (e.g. the contract between some backend API service and the app that relies on it). End to End Tests - (aka Automated QA-tests, Selenium tests) - Tests the application from the user’s perspective. Should never rely on implementation details of the app.
  3. Directory Structure Example e2e/ project/ ├── __mocks__ ├── src/Page │

    ├── __tests__ │ │ ├── Page.spec.js │ ├── Component │ │ ├── __tests__ │ │ │ ├── Component.test.js ├── package.json End-to-end tests Shared mocks Functional (Spec) test Unit test
  4. Testing requires a different mindset • Typically not concerned with

    “efficiency”. • Test what the code is supposed to do, not what it does or how it does it. • Code coverage helps ensure you’re covering edge cases. • If when writing your test you find it hard to test certain things and need to change your code -- that’s a good thing!
  5. Also, specifically for React… • Don’t test React, test your

    own logic • Don’t rely on class names to find things, instead rely on Component names or instances • Try to keep separation of “smart” and “dumb” components
  6. Good Test Clear, self-evident test descriptions. Cryptic/repetitive test descriptions. Bad

    Test Does not test the module the way it will actually be used. Cannot be run in isolation/assumes some environment. Relies on tests to run in a particular order. Relies on CSS class names. A test failure does not communicate anything meaningful about the health of the module and feels like noise. Can be used as (further) documentation for how a module works/should be used. Mocks unnecessary dependencies (or, all dependencies in the case of a unit test). Stateless and/or sets up any necessary state. Relies on instances of components. A test failure is meaningful and immediately actionable.
  7. Enzyme - 3 Rendering Modes shallow Best use for unit-testing

    components. Essentially “stubs out” child dependencies so that the tests can focus on the single component in isolation. mount Does a full DOM rendering. Best use for testing full lifecycle methods (such as componentDidMount(), etc). render For rendering to static HTML markup. Can assert that specific DOM elements exist, etc. Good use case with Jest’s Snapshot ability.
  8. Jest Snapshot Testing Great for purely presentational components. Steps: 1.

    Ensure your component renders as you expect (green state). 2. Use EnzymeToJson to serialize the Enzyme render (shallow). 3. Then just use expect(enzymeToJson(shallow(<App />))).toMatchSnapshot() * Jest will notice that no snapshot exists yet and generate one for you. On subsequent runs, any deviation from this known green state will fail the test. * Note: Jest 18 now accepts a “snapshotSerializers” config option so that you can omit the call to enzymeToJson()
  9. Jest Snapshots • Great for pure UI components with not

    much logic in them • Ensures changes in the rendered markup are explicitly made (shared components!) • Updating them is easy, just run Jest with -u • Can use Enzyme’s .find() to create a focused Snapshot test • Not just for React components -- works for anything serializable!
  10. Jest Mocking • jest.fn(implementation) ◦ Provides interrogable spy ◦ Returns

    implementation with special .mock property that provides call information • jest.mock(moduleName, moduleFactory, options) ◦ Can mock import statements in code to test ◦ If you provide just the moduleName, the __mocks__ implementation is used (if there is any, if not, it will automock). ◦ Options can be used to specify “virtual” mocks (e.g. the module doesn’t actually have to exist) • __mocks__ directory convention
  11. Other neat Jest features --coverage --watch (awesome with --o) jest.useFakeTimers()

    --runInBand Custom “loaders” (e.g. identity-obj-proxy) Can mock globally (e.g. relay)