Open ooloth opened 4 years ago
For machines that drive application logic I tend to export machine configuration and machine options separately:
import { createMachine as createXStateMachine } from 'xstate'
export const configuration = { .. }
export const actions = { .. }
export const services = { .. }
..
export const createMachine = createXStateMachine(configuration, { actions, services })
This allows me to import the pieces in my test file and enhance the configuration's states with meta.test
@rjdestigter so that sometimes you can decide to mock the services, actions, etc. or do you leave the machine config mostly unchanged in the test?
@CodingDive Yeah exactly
@rjdestigter I understood your code and intention, but machine options(such as actions
, services
, guards
) have to be separated from machine to implement test without duplicating existing machine. It makes lots of boilerplate codes and this problem is worse in TS than JS. I think it should be possible to use existing machine without separating machine options. How do you think?
@baeharam David has recently added a guide on testing state machines that might help you: https://xstate.js.org/docs/guides/testing.html
@rjdestigter I read your link, but it still has problem. If I follow that guide, I have to test all paths generated from every states and events. To test every paths simply, I have to use @xstate/test
but I have to write meta
property for each state. It means test code and implementation code would be mixed. It's harmful to readability and maintainability. I think there should be more cleaner way to test every paths of machine like withMetaInfo
method. cc @davidkpiano
It means test code and implementation code would be mixed
It's not "test code and implementation code" - it's test code and test code. The state machine describes the flows of the system under test, with assertions (in meta.test
) that make sure each visited state is actually in their expected state.
@davidkpiano Thanks for comment! Then, it means that meta
property should be included in machine
?
@davidkpiano Thanks for comment! Then, it means that
meta
property should be included inmachine
?
Not sure what you're asking, but you can put meta
on the machine itself.
@davidkpiano
Not sure what you're asking,
What I'm asking
meta
property of machine is "test"But, your explanation is that machine is also "test"?
@baeharam I've struggled to understand this too. It made more sense once I read this tweet. The goal is NOT to import your machine and generate tests from it. The goal is to write a NEW machine that acts like your users will, and test that. According to the xstate advice, you should not be trying to directly instrument your app's machine in the test files you create.
@martypenner Thanks for the link! I understood intention of "model based testing". However, when machine is changed, test and machine should be changed. It means that working should be twice, isn't it? Then, is it weak point of "model based testing"? Or Is my understanding wrong?
It depends on what the user expects. If you are making an internal change (like refactoring) that won't impact what the user sees, then you shouldn't have to change the test model.
But, if it is not internal change which have to be exposed to user interaction, two parts(machine and test) should be changed. isn't it?
That sounds correct to me.
@davidkpiano Then is it weak point of this mechanism?
I'm excited to give this a try!
My app logic is implemented using a state machine. I now want to generate tests for that machine using
@xstate/test
.For the machine I'll feed to
createModel
, which of the following approaches is the right idea?actions
,services
, etc) and add my assertions to that machine(Thanks!)