import { Head, Image } from 'mdx-deck' import { Split, Invert } from 'mdx-deck/layouts' export { default as theme } from './theme.js' import { Appear } from 'mdx-deck'
<title>Testing GraphQL</title>export default Invert
export default Split
<img src="./assets/headshot.png" style={{ width: "50%"}} />
- Apollo Architect
- Best practices
- Schema design & Testing
- Apollo architect: I'm here to help you navigate the graphql ecosystem
- Best practices: we've worked with people/organizations at all sizes
- Schema design to help you prevent costly refactors in the future
- The Purpose of Testing
- Effectiveness of Tests
- Testing Clients
- Testing Servers
export default Invert
- Safety of production code
- Documentation
- prevent regressions in features that haven't been touched in a while
- documentation for you in the future or devs new to the codebase
>>> BUT... not all tests are created equal
export default Invert
- Pareto principle: 20% of the work can give you 80% of the benefit
- What this talk is going to do is tell you what 20% to focus on when testing graphql apps, to get 80% of the benefit
export default Invert
<img src="./assets/testing-trophy.png" style={{ width: '60%'}} />
- If you want tests to bring you more confidence in your code, you should be testing the parts you're least confident with or are most likely to break.
- The parts most likely to break are not the units, but the relationship between them
- For that reason, most of this talk will be focused on equipping you to test these relationships
export default Invert
- Component props
- Types based off production schema
apollo-cli
- "Making sure all the pieces are there"
- Translation of props to rendered UI
react-testing-library
- "Making sure the pieces fit together"
- Loading, error, and expected states
- Local state changes (cache updates)
MockedProvider
- "Making sure the app is usable"
- Authentication headers passed to servers
- Components are visible and accessible
cypress.io
export default Invert
- pages/login: more complicated. Cache writes, interaction
export default Invert
- Type generation is not as easy as it sounds
- Resolvers don't have to return anything
- Default resolvers make this even harder
- Non-leaf Resolvers can return anything, as long as the resolvers receiving that response know what to do with it
- Leverage GraphQL's dependency injection
- DataSources are just classes
- Resolvers are just functions
- Use the constructor to pass things your datasources need (ex. store for SQL datasource)
- dep injection: use the context to pass everything that your resolvers need
- this makes your resolvers pure functions
- Testing execution of an operation
apollo-server-testing
🎉 🎉
- Where resolvers get data, and how they pass it to other resolvers to build a query response
- Checking HTTP semantics
- Making sure a valid request produces a valid response
- Can use real or staging services
export default Invert
- /dataSources/launch.js
- resolvers/query: first tests (pagination)
- /integration
- /e2e
Testing is essential, so it should also be easy and effective.
export default Invert