storybookjs / testing-react

Testing utilities that allow you to reuse your Storybook stories in your React unit tests!
MIT License
588 stars 24 forks source link

Question: Can we use assertions inside interactions and avoid writing tests in jest files ? #98

Closed dimitrisfasoulas closed 2 years ago

dimitrisfasoulas commented 2 years ago

Hello, I have a question about using testing-react and passing stories with jest assertions to jest.

In the examples, in the readme, the stories are used as they already include the necessary decorators so it saves a considerable amount of time and avoids a lot of doublication.

I was wondering if there is a problem (or if it is considered an antipattern) having assertions in the stories as well.

The setup I'm experimenting with is leveraging Interactions play functions with assertions.

Then when I import the stories into jest I run any play functions there are and as far as I can see everything seems to be working as it should.

Tests pass and fail when they should and coverage is also generated:

Psedocode examples: Story:

//...
export const Default: ComponentStory<typeof InputGroup> = args => (
    <InputGroup {...args} />
);
//...
Default.play = async ({ args, canvasElement }) => {
  const canvas = within(canvasElement);

  await userEvent.type(canvas.getByRole('textbox'), 'This is a search query', {
    delay: 50
  });

  await expect(args.onValueChange).toHaveBeenLastCalledWith(
    'This is a search query'
  );
};

Test file:

//...
import * as stories from './InputGroup.stories';

const testCases = Object.values(composeStories(stories)).map(Story => [
  Story.storyName,
  Story
]) as [string, StoryFn<unknown>][];

// Batch testing
test.each(testCases)('Renders %s story', async (_storyName, Story) => {
  // render story
  const { container } = render(<Story />);

  // run play function if exists
  if (Story.play) {
    await Story.play({
      canvasElement: container
    } as StoryContext<ReactFramework>);
  }
});

The above when run with jest will result in:

image

and will fail if I change the assertion:

image

It will also generate a valid coverage report.

yannbf commented 2 years ago

Hey @dimitrisfasoulas thanks for using this library! And what an interesting snippet you've got over there!

@storybook/testing-react was released a year ago to achieve something that wasn't possible to automate in Storybook. Now we have a shiny test runner called @storybook/test-runner which automatically turns stories into tests and you can automate that in CI! That means that, if you wanted, you could just not have any tests written in Jest anymore and have them all in your stories (which seems like what you're doing now).

You can definitely use both the test-runner and @storybook/testing-react, because @storybook/testing-react can help you cover more use cases in case you don't want them as stories.. however in your scenario, it seems like you can just remove your test files, stop using this library and rely on the test runner instead.

You can check more about it here: https://storybook.js.org/blog/interaction-testing-with-storybook/

Let me know your thoughts!