Building a React Components Living Documentation using React-Storybook.
The first time I heard the term "living documentation" was when I discovered Behavior Driven Development (also known as BDD). If you don't know what BDD is you can still read this introduction by Dan North. But to give you a quick idea, it's when developers, Q&A and business people collaborate to write specifications. Those specifications are focused on examples.
Now, who never read a documentation that were out of date ?
Code is often the only thing we can really trust; most written documentation is outdated before the project is delivered.
One of the benefit of practicing BDD besides that you're going to develop the right software (which is the most important thing actually), is that you can also build a functional documentation that can't be outdated. The only thing you need to do is to use scenarios as tests. They will end up instrumenting your application and verify that outputs are correct. That's it, you've just created a living documentation.
By using those scenarios as tests, you're making a strong connection between the code version and the specifications.
But using BDD scenarios is not the only way to create a living documentation.
Living documentation is a source of information about system functionality that's as reliable as programming language code but much easier to access and understand.
Bringing a living documentation for front-end components
A year ago, I'll join a project where for the first time I needed to make front-end development. We were using Ember and we did have some components to avoid duplication. But we've got a problem with new comers : it was hard to know what components were already there, what they were doing, and how to use them.
One day, a colleague got the idea to add a showcase to display all the components we have, with every possible behaviors. Of course, this showcase needed to be a living documentation, so we used the showcase to test our components.
We end up having a specific url in our dev environment to display our components. It was perfect when somebody needed to see a component in action. But the associated tests were also an important part of it because they helped to understand how to use the component and why they were used for. Indeed, the test code was the component specification.
And then comes React-Storybook
Those last months, I discovered React and Redux. I was working on a presentation about how to test a React and Redux application when I discovered React-Storybook. Almost immediately I made the parallel with what we've done on my previous project.
If you have no idea of the purpose of react-storybook, you can read this article. Basically, it creates an isolated application where you can :
- Display your components inside storybook by declaring stories.
- Taking advantage of storybook to develop in isolation your components by using quick iteration
Adding more and more stories of your components to react-storybook will allow you to build a strong documentation. Every time a developer will want to know what does a component and how to use it, he will either be able to saw it live in storybook or look at its declaration. That's good but is this documentation live ?
Well, no if we rely only on the declared stories. Maybe our components will change in the future and if there is no tests related to the stories, how can we be sure that the displayed component in react-storybook is still correct ? We surely ain't gonna watch them all manually.
Maybe we do have some tests for those components. That's a great thing, but there's a big chance that we're re-declaring the components that we're testing in our test files. If so why not used directly the one made for the story and write tests on it ?
In example above, we're just exporting the component declaration used for the story to be reused inside our tests files.
To make the test runner works we'll also need to be able to redefine storybook functions. We can also take advantage of that redefinition by replacing action and linkTo functions by spies.
For example, I use the following file in my storybook config. It's those functions I import inside my stories files :
And I use this as a mock for the facade :
All our stories are now verified by tests that share the same component declaration. It's a good thing because when the component will evolved, only one piece of code will be modified.
But we can do better...
Executable specifications directly inside Storybook
As I said earlier, tests are specifications. Wouldn't it be nice to have those specifications directly displayed inside react-storybook ? And wouldn't it be nice to also have both tests and stories declaration side by side ?
To do that, I had the idea to create a new addon : react-storybook-specifications.
The idea behind this addon is to write tests directly inside stories and still be able to use them with the CI.
It will create a new panel inside storybook that looks like this :
Of course, to use tests written inside stories with the CI you'll need to use the same kind of strategy with the facade that I showed you before. You'll also need more configuration. More on that can be found on the addon documentation.