All Projects โ†’ tophat โ†’ dont-waste-your-ducking-time

tophat / dont-waste-your-ducking-time

Licence: Apache-2.0 license
๐Ÿ“ An opinionated guide on how to test Redux ducks

Programming Languages

javascript
184084 projects - #8 most used programming language
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to dont-waste-your-ducking-time

k-redux-factory
Factory of Redux reducers and their associated actions and selectors.
Stars: โœญ 18 (-35.71%)
Mutual labels:  actions, reducers
redux-reducer-async
Create redux reducers for async behaviors of multiple actions.
Stars: โœญ 14 (-50%)
Mutual labels:  actions, reducers
ReduxSimple
Simple Stupid Redux Store using Reactive Extensions
Stars: โœญ 119 (+325%)
Mutual labels:  selectors, reducers
isomorphic-react-redux-saga-ssr
Isomorphic, React, Redux, Saga, Server Side rendering, Hot Module Reloading, Ducks, Code Splitting
Stars: โœญ 19 (-32.14%)
Mutual labels:  redux-saga, ducks
azure-static-website-deploy
Deploys static website to Azure Storage
Stars: โœญ 18 (-35.71%)
Mutual labels:  actions
issue-action
github action for github issue
Stars: โœญ 58 (+107.14%)
Mutual labels:  actions
do-spaces-action
๐Ÿ“ฆUpload directories/files to DigitalOcean Spaces via GitHub Actions. Supports package/library versioning.
Stars: โœญ 30 (+7.14%)
Mutual labels:  actions
auth
A GitHub Action for authenticating to Google Cloud.
Stars: โœญ 567 (+1925%)
Mutual labels:  actions
nextjs-ts-antd-redux-storybook-starter
๐Ÿƒ๐Ÿผ Next.js + TypeScript + Ant Design + Redux Toolkit + Redux Saga + Styled Components + Jest + Storybook ไผไธš็บง้กน็›ฎ่„šๆ‰‹ๆžถๆจกๆฟ
Stars: โœญ 78 (+178.57%)
Mutual labels:  redux-saga
fractal-component
A javascript library that can help you to encapsulate decoupled UI component easily
Stars: โœญ 13 (-53.57%)
Mutual labels:  redux-saga
gcloud-login-action
A Github Action which can be used to authenticate with Google Cloud Container Registry
Stars: โœญ 21 (-25%)
Mutual labels:  actions
head-start
A boilerplate for React applications with an Express backend with a simple user registration/login
Stars: โœญ 24 (-14.29%)
Mutual labels:  redux-saga
action-lgtm-reaction
GitHub Action to send LGTM reaction
Stars: โœญ 62 (+121.43%)
Mutual labels:  actions
react-redux-hackernews
React Redux Hackernews Application
Stars: โœญ 19 (-32.14%)
Mutual labels:  redux-saga
react-truffle-metamask
Build an DApp using react, redux, saga, truffle, metamask
Stars: โœญ 25 (-10.71%)
Mutual labels:  redux-saga
setup-meteor
Set up your GitHub Actions workflow with a specific version of Meteor.js
Stars: โœญ 17 (-39.29%)
Mutual labels:  actions
composer-action
Docker and GitHub Actions for Composer
Stars: โœญ 34 (+21.43%)
Mutual labels:  actions
launchbar
Actions repository for LaunchBar 6
Stars: โœญ 65 (+132.14%)
Mutual labels:  actions
deploy-appengine
A GitHub Action that deploys source code to Google App Engine.
Stars: โœญ 184 (+557.14%)
Mutual labels:  actions
necktie
Necktie โ€“ a simple DOM binding tool
Stars: โœญ 43 (+53.57%)
Mutual labels:  selectors

Don't Waste Your Ducking Time

Logo

Builds codecov Dependabot Status Slack workspace All Contributors

Overview ๐Ÿ“ƒ

This repo is a simple example project demonstrating how to test the different components of a Redux application.

The general idea: Don't write individual unit tests for your action creators, reducers, and selectors; instead, write tests that test the whole "duck".

This strategy comes from this Redux issue thread in which @bvaughn describes a way of testing Redux applications in order to get "the most bang for your buck" (dare I say "bang for your duck"?).

See the motivation section for more details on this testing strategy.

Examples ๐Ÿ“

Examples of bad duck tests are found here.

Examples of good duck tests are found here.

Examples of good duck tests involving sagas are found here.

Motivation ๐Ÿ’ช

First of all, what is a duck? It's a combination of related action creators, a reducer, and selectors. (It can also include other Redux-related paraphernalia, such as sagas.) Action creators create actions that when dispatched, cause state changes in the reducer, which ultimately are manifested in different values returned by the selectors.

You can read more about ducks in the ducks-modular-redux project.

How do we test our ducks? The redux documentation gives examples of how to write unit tests for action creators, reducers, and selectors, i.e. how to test them each in isolation. So why don't we start by writing unit tests? That's what the testing pyramid suggests, after all:

testing pyramid

There are some examples of these kind of unit tests in this project, in one of the duck test files.

Let's step back for a moment and recall the purpose of tests:

  • Tests give us confidence that our code is working as intended
  • Tests give us confidence that our code is working as intended after we do refactoring

So good tests have the following properties:

  • They fail when the code doesn't work anymore
  • They don't fail when the code is still working
  • They test code as it actually is used in production

With that in mind, consider what happens to our isolated action creator tests, reducer test, and selector tests when we do the following:

  • Refactor our state shape
  • Accidentally introduce a bug

It turns out lots of bad things happen:

  • The reducer tests fail upon refactoring, even though our code is still working, because they test implementation details. We have to mock the state.
  • The selector tests disconcertingly DON'T fail when we introduce a bug in the state, because we're mocking the state. We don't have confidence that the entire action -> reducer -> selector contract is fulfilled.
  • Not all of the tests pass even when the code is actually working.

How do we fix these problems?

Write tests that test the whole duck! You can see examples of such tests in another duck test file. Notice how these tests are:

  • Resilient to state refactoring
  • Test the real state shape using a real store, just like what happens in production
  • Still fast
  • Give confidence that all of our action -> reducer -> selector contracts are fulfilled, because it actually tests the contract

Think of a duck as having a public API: action creators and selectors are how you interact with the duck. They represent a "public interface" to the duck. If you only write tests using action creators and selectors, your tests are resilient to change as long as you maintain the same interface for your action creators and selectors.

You're not going to have an action if it doesn't trigger a state change, or at least have the potential to trigger some state change. You're not going to have a selector unless it gives you part of the state that gets changed by the dispatch of some action. So when it comes to ducks, don't think of isolated unit tests, think of the combined action/reducer/selector tests. The unit you want to be testing is the "three-part unit" of action creator, reducer, and selector. They are not distinct entities, they only have meaning when considered in relation to each other.

Installation ๐Ÿ”จ

Set up:

yarn install
yarn start

Run tests:

yarn test

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Michael Rose

๐Ÿ’ป โš ๏ธ ๐Ÿ“– ๐Ÿš‡

Christian Battista

๐Ÿ“–

Noah

๐Ÿ“–

This project follows the all-contributors specification. Contributions of any kind welcome!

Credits

Thanks to LogoMakr for having an impressive bounty of free stock duck images.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].