a redux middleware to automatically generate tests for reducers through ui interaction

Last update: Apr 24, 2022

Redux Test Recorder

NOTE YOUR STATE TREE MUST BE SERIALIZABLE

Redux test recorder is a redux middleware for automatically generating tests for your reducers based on the actions in your app. Currently I've written redux-test-recorder-react a component to provide a gui for recording tests in react but I'm hopeful recording components for other frameworks can be created in the future.

Build Status

Also take a look at our latest build which currently runs a test generated using this module by taking advantage of the eval command. For a better idea of what is going on, you can take a look at the test file here.

Install

npm install redux-test-recorder --save-dev

Use

First set up your store utilizing the exported middleware from redux-test-recorder. Export the props included with redux-test-recorder at this time as well.

import reduxRecord from 'redux-test-recorder';
const reducer = (state = initState, { type, payload }) => {
  let newState;
  switch (type) {
    case 'INCREMENT':
      newState = state + 1;
      break;
    case 'DECREMENT':
      newState = state - 1;
      break;
    default:
      newState = state;
  }
  return newState;
}

const record = reduxRecord({reducer});
export const store = createStore(reducer, applyMiddleware(record.middleware));
export const recordProps = record.props;

Then, if you are using with React you can install redux-test-recorder-react and import the recordProps exported by the instantiation of the middleware and pass those into the record component.

import {store, recordProps } from './store';
import TestRecorder from 'redux-test-recorder-react';
const Counter = ({count, dispatch}) => {
  return (
    <div>
      <button onClick={() => dispatch(increment())}>+</button>
      <h1>{count}</h1>
      <button onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}

const ConnectedCounter = connect(state => {
  return {count: state};
})(Counter);
const Root = () => {
  return (
    <div>
      <Provider store={store}>
        <div><ConnectedCounter /><TestRecorder {...recordProps} /></div>
      </Provider>
    </div>;
};

This will allow you to generate tests on your reducer with a record button in the bottom right corner.

Args

  • reducer - the root reducer of your redux app, used in the generated test.
  • includeReducer - a boolean value, if true, a stringified version of your reducer will be incuded in your generated test, if false, a note to import reducer for testing will be added. defaults to false. Useful when used to generate actual tests so you can test updated functionality.
  • stateKey(optional) - if instead of recording the whole state you only want to record a specific piece, pass that here (useful with actionSubset prop explained next). To get to a -nth level child use dots, as in: api.login.errors.
  • actionSubset(optional) - allows you to record against a subset of actions instead of all actions. Useful combined with stateKey to test a single reducer.
  • equality(optional) - a function used to determine if the reducer returned correct state. Receives result of the reducer call and nextState returned during the flow of the application (note, this api is in flux). deafults to ===. This argument can also be a string. This is useful if you want to call a function you will include in your test file, since calling external functions will not properly stringify that external function.
  • imports(optional)` - a string argument where you can pass in other modules that you would like included iny our test file. Useful if you want to reference external functions in your equality check.
  • testLib(optional) - defaults to tape. Currently supports tape, ava, and mocha, jest, and redux-ava. You can also optionally supply a function to this argument to generate your own tests. Will receive state, actions, imports, reducer, equalityFunction as arguments and expects return type to be a string containing your test contents.
  • numTestsToSave(optional, defaults to 5) - number of previous tests that will be accessible in the panel when tests are being displayed. Higher number = newer.

Create Your Own Testing Interface

If you're not satisfied with the built in testing interface or would like to experiment with something different, it's relatively straightforward. The return of the exported function is an object with two keys middleware and props. The middleware key contains, well, the middleware, props contains information for accessing the current state of the tests. These include startRecord, stopRecord , which are functions that start and stop test recording. createNewTest which creates and then returns a new test, hideTest , which resets all values to initial value, and most importantly listen , a function that takes a function and calls listeners any time any values related to recording status or generated tests is changed. More documentation on this coming soon.

You can take a look at what creating your own interface looks like here - here for what this looks like for the tape implementation.

GitHub

https://github.com/conorhastings/redux-test-recorder
Comments
  • 1. Move React code in a separate project?

    Hi, I would like to use this project in an Angular2 + Redux application. Do you think it could be a good idea to remove all of react dependencies and move the react code (needed for the component) in a new project? I can create a new repository for the ng2 component.

    Reviewed by francesco-strazzullo at 2016-06-20 14:28
  • 2. immutable state

    My state is mostly Immutable.js Maps and Lists. Is this a non-starter for this lib? Is that what 'state must be serializable' means? If so, any workarounds?

    My tests are failing with a few diff't errors:

    state.get is not a function state.removeIn is not a function and a few Expected value to be true, Received false

    This library is an amazing idea, hope I can get it working for my projects!

    Reviewed by brandonmp at 2016-11-10 15:49
  • 3. Doesn't work with React-Native? "Unknown option: foreign.Children"

    Has anyone used this with React-Native?

    We're doing this:

    import {applyMiddleware, createStore, compose} from 'redux'
    import * as reduxLoop from 'redux-loop'
    
    import middleware from './middleware'
    import reducer from './reducer'
    
    import reduxRecord from 'redux-test-recorder'
    
    const record = reduxRecord({reducer})
    
    const enhancer = compose(
      applyMiddleware([record.middleware, ...middleware]),
      reduxLoop.install(),
      global.reduxNativeDevTools ? global.reduxNativeDevTools(/*options*/) : nope => nope,
    )
    
    // create the store
    const store = createStore(
      reducer,
      null,
      enhancer
    )
    
    if (global.reduxNativeDevTools) {
      global.reduxNativeDevTools.updateStore(store);
    }
    
    export const recordProps = record.props
    
    export default store;
    

    And getting a TransformError in Babel-land of "Unknown option: foreign.Children".

    Please advise, thanks.

    Reviewed by GeoffreyPlitt at 2016-09-20 21:16
  • 4. Introduce multi-level stateKey

    As mentioned in https://github.com/conorhastings/redux-test-recorder/issues/37 , I prepared a working version of multi-level stateKey param.

    I haven't written any tests so far having no prior experience with tape, but all the previous ones seem to work well. Would you like me to add some auto-generated ones by replicating lines 56-97 of tests/index.js with multi-level state?

    Reviewed by pawelngei at 2016-09-01 08:53
  • 5. Nitpick about example code

    Hi- Cool project. One concern about the sample code...does not really matter, but it's triggering my ocd--

    const reducer = (state = initState, { type, payload }) => {
      let newState;
      switch (type) {
        case 'INCREMENT':
        case 'DECREMENT':
          newState = payload;
          break;
        default:
          newState = state;
      }
      return newState;
    }
    

    ... the actions are not really incrementing or decrementing, just copying the payload... so it's not really a good test because the state is replaced each time. Could the example really increment/decrement?

    Thanks

    Reviewed by winkler1 at 2016-01-11 11:53
  • 6. version react problem

    I use the version react 15 while the module uses react version 14, I also had problems with the library because it does not find the dependencies of highlighter.

    Reviewed by fabiolacasta at 2016-09-23 08:38
  • 7. How to use with huge single state

    In most of my projects I'm using single masterReducer and masterStore, making use of multiple combineReducers. My substates have several levels of depth and usually contain quite a lot of data (whole JSONs from the backend), and I'd like to use only specific substates for each test. Can I do that with redux-test-recorder? stateKey seems to be working only one level deep.

    Sample reducer:

    const masterReducer = combineReducers({
      auth,
      api: combineReducers({
        login,
        account,
        filterModel,
        users
      }),
      views: combineReducers({
        progressBar,
        stringDetails,
        stringDetailsHistory,
        review,
        navbar,
        replace
      }),
      uiLocale
    })
    

    I've prepared a branch with a fix (splitting stateKey on ., so stateKey: 'api.login' would work in my case), but don't know if it's intended use of this feature. Should I make a PR?

    Reviewed by pawelngei at 2016-08-31 19:59
  • 8. Stateless components testing

    Did you maybe have tried to apply similar logic for generating component tests? I imagine that somebody could experiment with such idea using for example HOC TestRecorder.

    Reviewed by Andarist at 2016-06-13 20:47
  • 9. Support for Jasmine Unit Test with describe() it() syntax ?

    Hi, was facinated to see this amazing work for generating test cases automatically.

    I was also wondering if there were any plan to support Jasmine like Unit Test with syntax such as: describe('', () => {...}); it('should xxx', () => {...});

    If we were like to contribute, what would be the good starting place for adding this support? Any suggestions or pointers are much appreciated. Thanks

    Reviewed by joyfulelement at 2016-06-10 13:58
  • 10. The demo link just shows some airplanes and a spinning head

    The demo link in the readme links to http://conorhastings.com/redux-test-recorder/demo/index.html but that just shows an airplane, a spinning head, and some text.

    Thanks to URL sleuthing, I see that it moved to http://conor.rodeo/redux-test-recorder/demo/index.html

    Reviewed by kumar303 at 2019-04-24 14:29
Docusaurus-theme-frontmatter - Docusaurus theme to expose front matter through a component hook

docusaurus-theme-frontmatter This package enhances the Docusaurus classic theme

Apr 27, 2022
A rollup plugin to generate javascript files that export the text of the css files

rollup-plugin-css-text A rollup plugin to generate javascript files that export the text of the css files. The plugin functionality This plugin will s

Dec 16, 2021
Questions-app - A React app allows users to generate as many random questions as they want
Questions-app - A React app allows users to generate as many random questions as they want

Questions App Projeto A aplicação permite aos usuários gerar quantas perguntas a

Mar 4, 2022
A chart monitor for Redux DevTools https://www.npmjs.com/package/redux-devtools-chart-monitor
A chart monitor for Redux DevTools https://www.npmjs.com/package/redux-devtools-chart-monitor

Redux DevTools Chart Monitor This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and

May 3, 2022
DevTools for Redux with hot reloading, action replay, and customizable UI
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

May 10, 2022
Redux DevTools remotely.
Redux DevTools remotely.

Remote Redux DevTools Use Redux DevTools remotely for React Native, hybrid, desktop and server side Redux apps. Installation npm install --save-dev re

May 10, 2022
Analytics integration for Redux and ngrx/store
Analytics integration for Redux and ngrx/store

Redux Beacon Analytics integration for Redux and ngrx/store Docs Migration Guide (from v1 to v2) Getting Started (Redux users) Getting Started (ngrx u

May 3, 2022
A resizable and movable dock for Redux DevTools monitors
A resizable and movable dock for Redux DevTools monitors

Redux DevTools Dock Monitor A resizable and movable dock for Redux DevTools. Powered by React Dock. Installation npm install --save-dev redux-devtools

Dec 27, 2021
The default monitor for Redux DevTools with a tree view
The default monitor for Redux DevTools with a tree view

Redux DevTools Log Monitor The default monitor for Redux DevTools with a tree view. It shows a log of states and actions, and lets you change their hi

Sep 17, 2021
Another Redux DevTools Monitor
Another Redux DevTools Monitor

redux-devtools-inspector This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and pull

Feb 28, 2022
Filterable tree view monitor for Redux DevTools
Filterable tree view monitor for Redux DevTools

========================= Filterable tree view monitor for Redux DevTools. Actions are collapsed by default but they can be expanded by clicking on th

May 2, 2022
A set of tools to facilitate react-redux development and decouple logic from compontents
A set of tools to facilitate react-redux development and decouple logic from compontents

react-redux-api-tools This project provides a middleware and a request helper to streamline react-redux data fetching. Installing Just run npm install

Mar 14, 2022
Crafty React & Redux snippets for Atom Editor

Mighty React & Redux Snippets Atom editor snippets for React and Redux. Made to be compliant with the latest & hottest ES6 and ES7 standards. Add the

Oct 22, 2019
基于 redux 的现代化 react 状态管理库。简洁、极致、极客精神

FOCA 基于 redux 的现代化 react 状态管理库。简洁、极致、极客精神。 特性 模块化开发 专注 typescript 极致体验 额外支持 Map/Set 数据类型 内置 immer 快速处理状态 异步方法自动追踪状态 多功能数据持久化 可与其他 redux 库共存,互不干扰 安装 ya

May 13, 2022
React State Management without Redux
React State Management without Redux

React RetiX Demo here This package is used for state management, it is not intended to become an alternative to Redux. It just provides a different ap

Dec 23, 2021
React State Management without Redux
React State Management without Redux

React RetiX Demo here This package is used for state management, it is not intended to become an alternative to Redux. It just provides a different ap

Dec 9, 2021
Filtering, Sorting and Pagination With React Hooks & Redux

React Redux Filtering Getting Started These instructions will get you a copy of

May 11, 2022
Create Redux State At Run Time

use-redux-states Create redux state at runtime. Overview use-redux-states allows

Feb 22, 2022
a redux middleware to automatically generate tests for reducers through ui interaction
a redux middleware to automatically generate tests for reducers through ui interaction

Redux Test Recorder NOTE YOUR STATE TREE MUST BE SERIALIZABLE Redux test recorder is a redux middleware for automatically generating tests for your re

Apr 24, 2022
remix-generate-css-links automatically generates links for your imported .css files
remix-generate-css-links automatically generates links for your imported .css files

remix-generate-css-links remix-generate-css-links automatically generates links for your imported .css files. You get the convenience of importing css

Mar 18, 2022