Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

React combo test

Build Status View on npm

Typecheck stateless component trees via PropTypes. You get weaker guarantees than real typechecking (eg., with typescript), but it's easier to set up and maintain.

This library helps you gain confidence about two things:

  1. For any valid props, a component renders without crashing
  2. Any props it passes to its children are valid

The "any" claim for both points above is an over-reach -- we are just rendering with a bunch of valid props in different combinations. This is usually enough.


$ npm install --save-dev react-combo-test


React combo test is currently test framework agnostic: it just throws to fail. For example, with tape:

import test from 'tape';
import comboTest from 'react-combo-test';
import MyComponent from '../wherever';

test('MyComponent renders without crashing', () =>
  comboTest(MyComponent, {
    colour: ['red', '#BAD', 'rgba(4, 3, 2, 1)'],
    interactive: [true, false, undefined],

In this case, MyComponent will be rendered nine times, checking every combination of the sample props (eg, <MyComponent colour="red", interactive={true} />, <MyComponent colour="red" interactive={false} />, ...).

Gotcha: import react-combo-test before react. This library patches react's render functionality in order to intercept proptype errors. To set that up, it needs to be imported before react is.

You can also pass your test framework's assert to comboTest for better failure reporting. Again with tape:

import test from 'tape';
import comboTest from 'react-combo-test';
import MyComponent from '../wherever';

test('MyComponent renders without crashing', assert =>
  comboTest(MyComponent, {
    colour: ['red', '#BAD', 'rgba(4, 3, 2, 1)'],
    interactive: [true, false, undefined],
  }, {

Check rendered output

Many testable behaviours can be described as invariants that should hold given some props. Since React Combo Test is already generating lots of props for your component, a hook is provided to add extra checks called check(jsx, invariant, props).

There are many ways to assert things about rendered JSX, so we just provide JSX and leave render/checking up to you. For example, with enzyme's shallow renderer:

import comboTest from 'react-combo-test';
import React from 'react';
import PropTypes from 'prop-types';
import { shallow } from 'enzyme';

const LabeledNumber = ({ label, value }) => (
    {label && (
      <span className="label">{label}</span>

LabeledNumber.propTypes = {
  label: PropTypes.string.isRequired,
  value: PropTypes.number.isRequired,

comboTest(MyComponent, {
  label: ['', 'A', 'zed'],
  value: [-1, 0, 1],
}, {
  check: (jsx, invariant, props) => {
    const wrapper = shallow(jsx);
    const label = wrapper.find('.label');
    if (props.label.length) {
      invariant(label.exists(), 'A label is rendered when label is not empty');
    } else {
      invariant(!label.exists(), 'No label is rendered when label is empty');

Skipping invalid prop combos

The best way to avoid bad states is to make them unrepresentable (ahem), but sometimes you're stuck with legacy code where certain combinations of props are invalid and shouldn't be checked. React combo test has an escape hatch for this situation, shouldSkipCombo(props):

import comboTest from 'react-combo-test';

comboTest(AnnoyingComponent, {
  mode: ['numbers', 'letters'],
  value: [-1, 0, 1, 'A', 'Z', 'm'],
}, {
  shouldSkipCombo: ({ mode, value }) =>
    (mode === 'numbers' && typeof value !== 'number') ||
    (mode === 'letters' && typeof value !== 'String'),

How it works

This library takes a naïve but useful approach that I should write more about in this section.


In 2016, the original idea and code were implemented in openride's web app code. In 2017, ratehub sponsored extracting and refactoring it into this open-source library version.


Test stateless components with their PropTypes for almost-free







No packages published