Built self-documenting, easy-to-maintain tests which integrate with any test framework using Statecharts.
Create a visual model, tell it how to interact with your app, and execute the model to test your app automatically.
Read our intro to model-based testing in our beta docs
Write Fewer Tests! From Automation to Autogeneration at React Rally 2019 (🎥 Video)
- Install
xstate
and@xstate/test
:
yarn add xstate @xstate/test
- Create your test machine using
createTestMachine
:
import { createTestMachine } from '@xstate/test';
const machine = createTestMachine({
initial: 'onHomePage',
states: {
onHomePage: {
on: {
SEARCH_FOR_MODEL_BASED_TESTING: 'searchResultsVisible'
}
},
searchResultsVisible: {
on: {
CLICK_MODEL_BASED_TESTING_RESULT: 'onModelBasedTestingPage',
PRESS_ESCAPE: 'searchBoxClosed'
}
},
searchBoxClosed: {},
onModelBasedTestingPage: {}
}
});
- Turn the machine into a test model using
createTestModel
import { createTestModel } from '@xstate/test';
const model = createTestModel(machine);
- Run the model in a test, passing it the instructions on what to do on different
states
andevents
. For example, using Cypress.
describe('Toggle component', () => {
/**
* For each path generated by XState,
* run a new test via `it`
*/
model.getPaths().forEach((path) => {
it(path.description, () => {
// Run any setup before each test here
/**
* In environments, like Cypress,
* that don’t support async, run plan.testSync();
*
* Otherwise, you can run await plan.test();
*/
path.testSync({
states: {
onHomePage: () => {
cy.visit('/');
},
searchResultsVisible: () => {
cy.findByText('Model-based testing').should('be.visible');
},
searchBoxClosed: () => {
cy.findByText('Model-based testing').should('not.be.visible');
},
onModelBasedTestingPage: () => {
cy.url().should('include', '/model-based-testing/intro');
}
},
events: {
CLICK_MODEL_BASED_TESTING_RESULT: () => {
cy.findByText('Model-based testing').click();
},
SEARCH_FOR_MODEL_BASED_TESTING: () => {
cy.findByPlaceholderText('Search').type('Model-based testing');
}
}
});
// Run any cleanup after each test here
});
});
});