Testing Made Easy: Better, Faster, Stronger Unit Tests and Integration Tests

Norbert de Langen speaking at JS Monthly London in April, 2017
1158Views
 
Great talks, fired to your inbox 👌
No junk, no spam, just great talks. Unsubscribe any time.

About this talk

Unit testing and integration/e2e/flow testing can be quite time consuming. Watch this talk for tools and best-practices to decrease the amount of time you have to spend writing and maintaining tests, making teams more productive and happier, increasing confidence and coverage. The tools we’ll be using are Jest, Cypress and Storybook.


Transcript


Norbert: Thank you. Can everyone hear me? Is this good volume for everyone? Male: Yes. Norbert: [inaudible 00:00:06] if there’s still room in here if you want to move, that’s fine. Me, my name is Norbert de Langen, I've worked on a few projects, and I do some open source. I work for a company called Xavier, and I am a front end consultant. I come in at a company who has a specific problem, and I try to do [00:00:30] my best job as I can. Solve their problem, but I try to solve it in a way that they can then handle it on their own. I’m not an employee of that company. It’s my Twitter handle and my Github handle if you want them. First thing I want to talk about is the testing pyramid. This is a very old concept. It’s like 1990 old. It looks like this. We’ve got [00:01:00] a little test at the top, and then gradually, as we go down, there should be more and more tests. There are different types of tests, so at the bottom we’ve got unit tests. I think these test a single function. This is function, if I pass these parameters in, does this come out? Is this correct? Really basic testing. Component testing would be if I render this [00:01:30] part of UI like this with these settings, does it render correctly? Integration testing is if I combine a few UI components together, do they interact correctly? Like throw a few events at them, do they do what they are supposed to do? API testing is a sidetrack from UI aspect where we test our back end API, we [00:02:00] throw a object at it, and a put, and we assert that a database call has been made for example, or we do a get, and does it actually return the right data back? Then we’ve got GUI testing, or often called end to end testing. This is where we would run a script that would interact with the browser, which will be clicking, selecting, dragging, dropping, [00:02:30] editing things in an actual browser. If everything works well, we’ve got a passing test. Then at the top of our testing pyramid, we’ve got our users or our product owners who are actually manually testing our application. We, of course, as developers, are manual testers also, but we try to minimise our own manual testing, and try to defer them as much down as possible. [00:03:00] This testing pyramid is like, on the top, we’re very user centric. At the very top, we are a user. A user is actually discovering a bug for example, so you could view testing like that. The more down we go, the more abstract our tests become. At the bottom, we’re no longer interacting with users, [00:03:30] we’re no longer thinking about our entire app. We’ve isolated them to very small modules. Small units. I think we don’t need a new tool or a different tool for each one of these layers. We actually have three tools that I’ll be introducing to you today. Actually, one of these tools you already know, because this is human. They are irreplaceable. I’m pretty sure everyone of you [00:04:00] is familiar with this tool. They're not always reliable, so that’s a problem. Of course, technology is not always reliable as we’ve seen, but at least they’re more predictable. For GUI, or end to end testing, I’ll be introducing Cypress.io today. For every [inaudible 00:04:23] test, I will be introducing Jest. Recently, [00:04:30] this testing pyramid has become under attack, or is more talked about, because this entire layer of unit tests, you need a lot less of it when you do, well, static analysis. If you’ve got good modules that are built, then you’re built. If it’s not failing, this actually tells you a lot about your code. [00:05:00] We also have tools like ES Lind, or static Typescript, or Flow that will help us find problems in our code. I’m not saying bugs, because whether something is a bug is really up to humans to determine. If code is incorrect, that could still be considered a future. We have this divide between end to ends [00:05:30] tests, or GUI tests, and this other big chunk of tests. Which one should you be doing? You should definitely be doing tests by the way. Should you be focusing or starting out with unit tests, or maybe should you be starting out with end to end tests? Who thinks starting out with end to end tests is the right way here? [00:06:00] Who thinks starting out with unit tests is the right way? There’s no wrong answer here by the way. It really depends on your application, on what you are developing. For example, if you’re developing a website, really a website that will stay up for a few months, writing unit tests for that is probably not worth your time. Maybe, probably not. Writing end to end tests in that scenario, I think that’s definitely going [00:06:30] to be worth your time. If you do not have a code base that has really well-defined units, writing units, unit tests for large units, that’s problematic. That’s pain waiting to happen. Maybe at that point, you should be starting out with end to end tests, and split up your code 1st. Here’s a few quotes that I’ve come across when researching this topic and making this presentation. [00:07:00] I thought they were thought worthy. Have a read. This is a really well-known or repeating pattern where end to end tests, usually people write them in selenium or protractor, maybe CasperJS, or some PhantomJS stuff. These things [00:07:30] can be really slow, and they can be really flaky. If there’s two things as a developer you don’t like, it’s in predictability and inaccuracy. End to end tests have this problem of being slow, but also being inaccurate. It’s really a big problem if you have an application, you want to have confidence. End to end tests, yeah, they are problematic sometimes. Of course, writing [00:08:00] only unit tests, that’s problematic as well, because oh, your units may be functioning correctly, or at least passing their test, but if they don’t integrate, they’re still broken in some way. This person clearly has that in mind, and they say bugs are when you simulate or ask a user whether something is wrong, that’s how you find bugs. You cannot find bugs using [00:08:30] unit test is at least this person’s opinion. The other side of the spectrum, this is a quote from Dan [A-ver-moff 00:08:40]. I did not keep track of all who made these quotes by the way. Sorry. There is a huge crowd of people doing unit tests on reactive components. He says maybe that’s not really worth your time. Maybe you should be investing your time somewhere [00:09:00] else. Well, where should you be focusing your time on? Well, another guy is in a different quote, this person clearly thinks that in the middle layers is where you should be focusing. It’s not at the bottom layer, not the top layer, it’s in the middle. It’s integration. That’s where, if you do thorough testing, [00:09:30] you’ll get the best bang of your buck. A quick comparison between the two, unit testing, fast, reliable, you get really isolated areas, which is a huge plus. If you actually get an error, you know where in code this problem is occurring. Therefore, it is preferred by developers, because it’s accurate. It can become very time-consuming. [00:10:00] End to end tests, well, they simulate a real user. When something is broken, and is repeatedly broken, you actually found a bug. Actually finding bugs is really important. It’s also very easy to migrate from manual testing to end to end testing, because it’s basically whatever you were doing by hand is now done by a computer, because you wrote the script to do it. [00:10:30] Because it actually finds bugs, and provides quick business value, this is preferred by managers. A huge problem of end to end testing is that you actually need to deploy a server, and have it up and running and accessible for you to run your end to end test on it. This is a sharp contrast, where is unit tests, you do not need an entire environment or an entire [00:11:00] app, but only a small module, you load it, you run it, you know whether it works or not. An end to end testing has this problem where if you view your entire code base through the lens of a app user, hitting all the code paths, and all the possible code paths, that’s becoming impossible. There’s just too many. Think about a application [00:11:30] that is more like a game than a website. You’ll understand that it is just plainly impossible to end to end test a game. That would be really, really hard to do. Not impossible, sorry, but it’s really hard. There’s too many code paths, too many things a user could do that you should … Yeah, simulating all of that would just take too much time. What are tests about? Tests are about providing feedback to the developer as quickly [00:12:00] as possible, whether something is wrong. This feedback, this constant feedback gives a developer confidence. I truly believe that giving your team and your developers confidence improves their agility, and improves their speed of development. This is what tests are about. If you do them for other reasons, you could still be gaining a lot of worth, but I think if you do them for these reasons, [00:12:30] for gaining confidence, your development team will speed up, will increase, and improve in performance and quality. Sorry, that was the word I was looking for. Writing tests sounds good, why are we not all writing tests? Why are some people writing tests and not happy? You would think that if someone writes a lot of tests, he [00:13:00] should be happy. That’s not always the case. Who here has had this occurrence that you’ve got lots and lots of tests, but you’re not really happy with them? Yeah. Yeah. It happens, but why? What happened? What went wrong? Well, if your feedback is not fast enough, like you’ve gotten end to end test that takes an hour to run, yes, I’ve experienced that, this is not fast feedback. Feedback might [00:13:30] be accurate, but it’s just tremendously slow. It’s too slow to provide value as a developer. You start doing other things waiting for your end to end test to finish. This can even happen with unit tests, although they should only test small things. If your feedback is unclear, for example, your test is flaky, your feedback is bad. Even worse if the feedback is inaccurate, [00:14:00] that’s a problem as well. Another really huge thing why testing can become harder and harder over time in a code base, because you may be optimising for writing the unit tests, or understanding the unit tests, but not so much for actually updating the tests. I think optimising for removing [00:14:30] or changing code should be our focus. Because if you add lots of layers of abstractions and tests, they become harder and harder to understand, and thus, harder and harder to update by next developers. I think being really careful with making your test too complex, and of course, writing too many tests is not a problem actually. If you have multiple tests testing [00:15:00] the same functionality, you would expect that if you change that functionality, multiple tests will now fail. That means that you now have to edit multiple tests to make a single feature available. Make sure that you know what you’re testing, and testing it where and when. In other words, make sure that you choose [00:15:30] a strategy, and you communicate that strategy with your team. Certain features, they’re really user centric. You might want to write a GUI test for that, but other features, you could write a unit test for and be done with it. Try to minimise the amount of double testing that you do. Don’t write a module [00:16:00] that would be unit tested for foreign validation, and then also do foreign validation in your end to end test. Maybe you want to do that still, but if you do it, understand that you’re adding a lot of extra work for developers that need to change this functionality. Another part of making sure that your tests will not bog you down over time [00:16:30] is actually choosing the right tools. Who here knows all four of these tools? You’re my friend. Awesome. Male: [inaudible 00:16:44]. Norbert: Cool. I will be introducing three of these tools today, because I think there is already a lot of [00:17:00] interest for it. There’s also a lot of talks you can view online about them. I will be using React in my examples, and I will be providing examples and demos for the tools, Jest, Cypress, and Storybook. Let’s start out with Jest. Jest is a test runner. It’s [00:17:30] like Mocha, but it comes with more stuff added to it out of the box. Without doing anything, it actually replaces Mocha, Chai, Sinon, and Istanbul. My opinion, Jest is just amazing. It’s a great tool. Especially in large code bases. Because what Jest will do is it creates a pool [00:18:00] of all your tests, and then spin up a few processes. It will actually do tests, and when they’re out of work to do, Jest will distribute tests to them. In other words, it will use as many cores your machine as your machine has. In my case, that would mean there is eight tests running in parallel. Making Jest probably [00:18:30] eight times faster than, for example, Mocha. You can do sharding in Mocha, and I’ve done it once myself, but it becomes quite hard, because now you actually need to, yeah, do a lot of manual splitting of test files. It’s not really the same as what Jest does, because the way I’ve implemented it in before [00:19:00] was by just splitting up the test files like in an array, and giving them both to other processes. Jest will actually redistribute them and make sure that they almost end up at the same time. Of course, what Jest will do is aggregate all the test data, and pipe it back to a single terminal. Not only that, but Jest [00:19:30] doesn’t need all that much configuration. You can start using ES whatever, like six, or 2015, 16, 17 right out of the box. It will actually detect if you’re using Bobble. It has a feature called snapshot testing. Who here has ever heard of this term snapshot testing? Who of those people don’t like it? [00:20:00] Okay. I’ll try and convince you, okay? Before diving into snapshot testing real quick, Jest is extendable, so you can, for example, it ships with Jasmine 2 by default, but you can take it out and put in Chai if you want. I like Jasmine 2 to be honest. Snapshot testing, [00:20:30] it changes the way you write tests. Not just unit tests, but old tests. Interesting thing about it is that you can snapshot anything. Don’t think a snapshot as being a visual snapshot, like a picture. Think of them like an output of a function that you put into a file, and then make sure that when you run the test again, you compare [00:21:00] whatever is in the file to whatever the output of the function was. If they match, you’ve got a passing test. What really changes when you do this? Well, in the above statement, I hope it’s readable for everyone, you can see that it's function called calculation. It takes three numbers, and it returns a single number. We tested here [00:21:30] what are one, two, and three combined together. They should be six at the end. This test passes. The second expectation at the bottom, it does the same thing, except it doesn’t really care if it’s six, or seven, or eight, or nine, or 10, it just cares that whatever it previously returned in the previous test run, that’s what should come out [00:22:00] now. Why is that so amazing? Well, now I don’t actually have to think about what this function returns in here, all I assert right here is that this functionality should stay unchanged, and if it changes, I should know about it. I should know about it via a failing test. [00:22:30] This is really popular for people who use React. If you do use React, I can definitely tell you about Enzyme. It’s a library for rendering React components, either deeply or shallow. A shallow rendering of a React component is basically like auto mocking all its child components. [00:23:00] A component, like this component, what it actually does is it renders three other components. What a shallow renter will do is it would not actually render those [inaudible 00:23:18]. They would still be findable, but they would not get initiated. If I were to change that expectation to [00:23:30] a [inaudible 00:23:30] snapshot, what’s happening is basically what I’m saying here is I’ve got this React component, and it renders correctly. I noticed, because it’s something I’ve manually tested, I change the functionality, and I know it functions correctly. Now I just want to assert it should not change. This thing should not be influenced by anything. [00:24:00] Jest will then detect that you’ve used too much snapshot, and if you’ve got Jest running in watch mode, it will tell you that it found a new snapshot, and it’s written it to a file. This file is human readable, and you should commit it with Git. Why? There's a few awesome things about it. You can now actually see what this function returned given the specified [00:24:30] parameters. It’s human readable in a file, and if you commit it, you can actually see it in your pull request. You can actually peer review it and see, well, why is it returning four here? That should not be the case. You could read that in a test file as well if you did old-style assertions. It’s much easier to miss certain things using old-style assertions. [00:25:00] Complex functions that return objects that are complex objects, using too much snapshot, you would snapshot the entire object in it’s entirety. You would not have to write a lot of assertions, or you would not basically be writing the same object twice. Basically, just what automate that process. Of course, the next question would be [00:25:30] your component changes. It does. What will Jest do? Jest will display a diff inside your terminal. I think the diff that Jest displays is top-notch. I’ve tried a few other test tools, and this is one of the best different tools that I’ve seen. A test is actually failing right now, and [00:26:00] how do I fix it? Well, using old-style assertions you would actually be changing the test, and making sure things are correctly, and then rerunning the test again, maybe making another few changes to your assertions, or even worse, your test was actually passing, but you’ve added new functionality. Because I was using too much snapshot, I actually get notified if anything was added, [00:26:30] and now the magic part. All I have to do was run Jest in watch mode and press Q, and all my snapshots were updated. I went from minutes to maybe hours in modifying my test files and making sure everything was right, to a single keystroke. I think that was pretty powerful experience. We can [00:27:00] snapshot anything at a really low level. We can even snapshot whatever it was in a module that we were testing. This is a pattern I’ve been using and liking it pretty much. I import everything from module, and then I expect its exports to stay the same. Now, the awesome thing about it is because you commit this human, readable file to Git to write, you can see [00:27:30] the file. This now actually gets its own history in it, so you can actually see what modules exports over time. Jest is actually already pretty old, but it had this problem in the beginning [00:28:00] where it was very unpopular because of this. Jest did auto mocking of everything. Everything. You would import a module and it actually would be a mock. This is a really powerful feature, but not many people wanted it, so they change things around where this is now an opt in. The mocking utility in Jest is top-notch. It’s amazing. [00:28:30] You can write them in a variety of ways. The bare-bones way is to write Jest.mock, and then the module name, and then give it a mock implementation. You can return that mock implementation in a function. This is really expressive, really powerful. The better way is really to put this to mock implementation [00:29:00] in a different file. Some advice that I’m giving to you for free is you should think about globals. Globals are actually dependencies that are like included automatically. What we can do is actually use a MPM module called Global. Using some wizardry, it actually exposes everything that’s on [00:29:30] the global object. We can import things from this global package. Now, not only one, but two things are really powerful about it. One, we’ve actually gotten import statement at the top, so we know exactly what we’re going to be using from the global scope. We can see it right here. Also, we can actually now market really easily with Jest in our unit test. [00:30:00] A short demo of Jest. This is readable. Okay, cool. Be a run test. If I run Jest just like this, a single run, it will give me all the suites that passed, and give me an overview of [00:30:30] everything it did. It found nine suites, 28 tests, and it found three snapshots in total, and all of them are correct. We’re all happy about that. Of course, we all want to see how Jest runs in watch mode. Here we go, this is Jest in watch mode. Interestingly enough, Jest did not run any tests. That’s because [00:31:00] Jest detected that I’m using Git, and I’m actually on the latest master. There is nothing changed since my last commit, so why would it test anything? It assumes that you’re writing CI where things are tested automatically. If you’ve committed something, it ought to be good. Of course, in a demo case like this, I definitely do want to run all the tests, so all I have to do is press A, and it will run all [00:31:30] the tests for me. All of them. Awesomely enough, sometimes you focus on a particular feature. I don’t know if you’ve done this using Mocha, but it’s hard to then give it a pattern, so you only want to test these few files. With Jest in watch mode, all you have to do is P, and now I can type in a regular expression. Press enter. It will [00:32:00] run only the tests that match that regular expression. Really, really powerful feature. This will also work for test names. What I just showed you, P, that was like a pattern on the URL, or the path of all the test files. It can actually detect test names. It’s quite cool. Using enter, I can run the same thing again and again, so it will remember this pattern that I’ve just given it to it. If I [00:32:30] want to exit this pattern, all I have to do is press a and it will run all the tests. Then Q will quit it. That’s the deal with good testing for units, or units like things. If we wanted to write end to end test, we would not be using Jest. Jest is not the right [00:33:00] tool for that. There is a few other tools. WebdriverIO is a current, pretty new tool, and Chrome is about to become headless. That’s a really cool feature as well. Most people have been writing selenium or protractor tests I think. Cypress is a new kid on the block that does the same thing. It does it a lot better. [00:33:30] Start our Cypress in the background. What is Cypress? Cypress is a replacement for selenium. It’s not selenium. What selenium does is run a browser, run a backend, and then push things, commands to a browser. Then hopefully, the browser returns. It responds with something [00:34:00] we all hope. Everyone that has ever used selenium has experienced this problem of timeouts where the browser crashed, or did not respond in time, the tests were flaky, and you did not get a reply fast enough. What we do? Well, we increase the timeout times until our build becomes an hour long. Cypress also has a watch mode. It’s not as powerful [00:34:30] as Jest, but of course, it can do pretty neat things like taking screenshots, and take a video of the entire session. It can also do mocking. If you want it to go to the strategy where your GUI tests are not end to end, so you’re not actually hitting any of your backend, you can do that with Cypress. It has a asynchronous API [00:35:00] that is like how you write commands to selenium. You write lots and lots of commands that actually get executed in the right browser context. There is no communication delay or channel in Cypress, because Cypress actually encompasses your app. Cypress is almost like a custom chrome built. [00:35:30] It actually has a really cool GUI tool where you’re in selenium debugging, if you can call it that, with your terminal. It’s just a horrible experience. Debugging with Cypress is just a breeze, it’s really easy. You get really good feedback of what’s going on and why some things are failing. Unfortunately, [00:36:00] Cypress currently is closed source. They plan to make everything that is available to the public now open source, it’s a promise. It currently has no window support, so that’s a big problem for Windows users. You can run it in a virtual machine though, but of course, performance will be different. They plan to create a paid product that will run [00:36:30] these tests in the cloud. I think that’s a pretty cool feature, because running end to end test is rather CPU intensive, so it’s hard to do other tasks while doing this. I think for CIs, it’s definitely a good feature. Otherwise you’d be spending a lot of money on hardware to run your own end to end test locally. Short Cypress demo. [00:37:00] Like I said, Cypress is a GUI tool. Sorry, did not prepare. Instal it as an application on your local machine. Right now, it’s in beta, in alpha. You need to ask for access if you want to use it. They’re pretty quick on giving you access, if not, [00:37:30] I can probably help you. What you do is you add a project to Cypress, and under this project you add tests. To have a kitchen sink, if you instal it and add it to your project, you could just safely remove it. Though it is interesting to look at it. I will not be running it today because it’s slow, and I’m in time. I’ve written my own small end to end test, and yes, you can see it fails immediately. Why? [00:38:00] Well, I’m not running my server. I did this on purpose. This is annoying thing about end to end test, you need to run that server. Let’s run the server. Start. It’s waiting for WebEx to do its thing. It’s done. [00:38:30] Now, Cypress should be happy. Cool. I can actually show you the application, it’s quite interesting. Near top. It’s a [00:39:00] React with Redux app that uses SoundCloud to create a visual website where you can find, and navigate, and yeah, listen to music. In my end to end test, I test whether this works. I'll increase the size a bit. [00:39:30] With selenium it’s like you get a Boolean feedback. That this thing either work, or it didn’t. With Cypress, I can actually open up a test after it’s done and have a look at what was happening. I can actually, at right, if you can see it, I know it’s small, but what’s happening on the right is that it reverts the [inaudible 00:39:58] back to the way it was when [00:40:00] it was running the test in that step. It will demonstrate. It’s not visible. It is visible on my machine. What it’s doing is it’s showing me exactly which element it found, and which one it’s going be first. It’s trying to find a range of elements, and it’s found them, [00:40:30] and then it’s picking the first one, and then it’s clicking the first one as you can see by the red dot. That’s exactly where Cypress clicks. This is also handy with debugging. Then I’m asserting that the URL is changed. Apparently, this test succeeded. Yeah, URL did change. I can click on another one. Can you see? That’s hard to see, sorry. Male: [inaudible 00:41:04] [00:41:00] . Norbert: Yeah. It’s visible after the fact exactly what Cypress said, what your test did, and if something went wrong, I can change this number two to be 60. It’s this one. [00:41:30] Cypress [inaudible 00:41:34]. It should be right here. This is how the Cypress test looks like, though there are different ways of writing them. In my tests of main navigation, it should show songs, and I’m testing whether it found more than two [00:42:00] items, which I thought was normal. If I change to 200, that should fail. Like I said, Cypress has a watch mode, so it actually started running the test while I changed my code so I didn’t have to press refresh. As you can see, it failed. Male: [inaudible 00:42:20]. Norbert: Yeah? Male: [inaudible 00:42:24]. Norbert: Yeah, it’s not as good as Jest’s watch mode, it just ran [00:42:30] all the tests again. That was a question, or a remark? Male: No, I mean that it ran just the single test. Not the [inaudible 00:42:37]. Norbert: It ran them all. Male: Okay. Norbert: Yeah, it’s unfortunate. Yeah, this is something Jest does a lot better. It actually runs the failing tests first upon a second iteration. If I change it again Cypress should pick this up. [00:43:00] This time the test succeeds. Cool. Last tool or introduction of the day, this is actually a tool that I, with a few other open-source maintainers maintain. [00:43:30] This is a tool I know a lot about. If you have questions, come at me. Storybook is a development/documentation tool, currently specific for a react component. Why do you need such a thing? Well, as your code base grows and more and more components are added in more varieties, what ends up happening is your team [00:44:00] expands, or maybe even you have two teams working on this UI. Eventually, two people will be working on the same thing. They will be developing different components that serve the same purpose. Documenting which UI components you have, that can become a valuable thing to do. Actually, developing in isolation a UI [00:44:30] component in isolation, I think that is one of the things we’ll be seeing people do a lot more in the coming years. It’s something I’ve been doing for over a year, and I don’t want anything else. I hate it when I make a little change to my code base, and I have to start up the entire application in its entirety, and go through the entire application flow just to make sure whether this radio button [00:45:00] is now green. I hate it. It’s not needed, with especially things like React, we can render components independently alone in isolation, and thus, if we can render them that way, we can develop that way. This is something Storybook provides for you. Besides just displaying components, what Storybook will do is actually open up WebEx configuration, [00:45:30] and will automatically push new code to this UI component. As you develop the UI component, React Storybook will continuously react to what you’re changing. If you change the CSS to be read, boom, you’ll see it right away. If you change the component text to be different, it will change. I can actually demo this. [00:46:00] Quick run Storybook if I can type. I’ve just picked out a few React UI components from the previous application. I think you might recognise them. [00:46:30] I’ve got this comment, so someone can comment on another user, or on a specific song, and it looks like this. What React’s storybook does is, instead of writing a single example for a single component, you can write as many examples as you’d like, and how they differ is up to you as a developer. In this case, [00:47:00] they differ only by the username. They can differ by a whole lot of other things. [inaudible 00:47:08] also got this component, this comments, component. I’ve written a short one that has just four, but I’ve also written a long one that has a lot more. I can see how this component interacts, and how it reacts with [00:47:30] so many items in this list. I like this tool for displaying my [inaudible 00:47:38] of my UI components. One of the [inaudible 00:47:42] for this component would be if there is only one item, or if there is no items in this list. I’ve also got the Nav component in here and a song card. A song list item, and one that [00:48:00] is currently playing. The spinner is in here. The tool box. As you can see, things like mouse over. This is a completely interactive React component, which I can also demonstrate in here. This thing works. If your Reacts component has state, React storybook will just [00:48:30] display the component with its state. Another interesting example is this [inaudible 00:48:38]. You can set it at different moments in time via props and display it this way. That’s not what I want to do. [00:49:00] Okay, I have to do it by manual. There we go. Okay. Now, this window. As I said, one of the very cool things about React Storybook is that you can actually [00:49:30] code whilst looking at your storybook at the same time, and your storybook will continuously update via code pushes. Especially if you have two monitors, this is really powerful. You can focus on your development and your code whilst looking at how it renders all the time. I can take this common comment component, and [00:50:00] pick its code. Component, comment. In its username, I could add a few exclamation marks and save it. Well-off. Storybook picked it up and add it down here. Maybe it’s clearer if I add them here. Boom. There we go. This is, [00:50:30] within seconds, you actually get feedback on how you are developing. If you make a typo, which you can do, it happens, this is how React handles this stuff. I guess if I make a larger problem, yeah. I would expect this to be a problem actually. [00:51:00] This is not a problem, okay. This should be a problem. Yeah. You actually get a error in your console [00:51:30] as well. That concludes my demos. I’ve got some random tips for you. If you do test, try to test small things. If your function is complex and large, it’s test follow-up can probably be more complex and larger. This is my experience is testing large things. The test is even larger. Try to [00:52:00] reduce the amount of code paths that are possible in a function. That will really help with testing it. It’s really easy to write subfunctions and then test those independently. Then just at the large functions, just assert that it’s calling the right functions. Don’t test things multiple times. Be careful on what’s set up and what [00:52:30] assertions you're going to share. Making these things too complex will hurt in the long run. It makes perfect sense to optimise and structure your tests in a way that makes it really small and compact, but maybe over long periods of time, that’s actually hurting you. I personally think if you write your tests in a bit more for both, [00:53:00] less abstract way, this will help you, future you, but it will also help your team in the future and make sure that mutating the test later on is easy. I tend to do aggressive mocking, so mocking as many things as I can. In unit tests and in end to end test. Or, yeah, GUI test. I do this because it increases predictability [00:53:30] and reduces flake. It also allows me to make sure that whatever data I’m going to be getting and acting upon, I know it will work. To make sure that I’m not optimising for a specific data object, what I do is actually make mock data generators, and I’m using an MPM module called Faker to generate fake or new data every time. [00:54:00] If you had a quick look at my Storybook, every time I open comment or comments, the data is completely new, and its random data. Co-locating files is a huge plus for testing. It’s not only easy to identify where your missing test, because tests are supposed to be next to the source files, [00:54:30] but it’s also really easy for importing and mocking, because it’s only one folder away instead of moving up five folders up in the tree, and seven folders down because it’s in the source directory. It’s really easy if you just bundle all these files together. CSS templates, JavaScript, put them all in tests and stories if you’re using storybook. Put them all in one folder. [00:55:00] Integration, unit test, and twin test, what strategy has worked for me? A strategy I really like is writing lots and lots of unit tests. Writing integration tests with React is basically a unit test, because it’s just another component that you’re testing. I really like that about React, how testable it is. What I do to make sure that everything that should happen in a browser will probably [00:55:30] work in a browser is by writing one or two, at least a few end to end or flow test like things that just flow through my entire application. If you can login and order a product, you probably can also register. That’s my opinion. Do what you think is well for your application. I use a lot of snapshot testing. I keep track of coverage, but don’t try [00:56:00] and make 100 percent coverage the end goal. The end goal is to make sure that your application works whilst not burning money at the same time. Last few tips, Jest tips, I like using a config file. It’s really standard to put things in your package. Jason, I don’t like editing this file by hand, because if you make a [00:56:30] problem in there, what ends up happening, if you miss it, is that nothing will instal, nothing will run. I think each tool should have its own configuration, and if there is a problem in that, there’s no problems for other tools. Like I said, using mock files over in-line manual mocks is my preference. I have no problem [00:57:00] with combining snapshot testing with old-style assertions at all. It’s perfectly fine to make sure on a few detailed things, and put some old-style assertions in there. That was it, these are my sources. Thank you very much for attending. I had a good time. Male: Do you have any questions Male: Does this snapshot testing [00:57:30] work with the [inaudible 00:57:33] development? It sounds to me that you first develop, and then you take a snapshot of the golden case scenario. Norbert: Yep. Male: Yeah? Okay. Norbert: Do you do test driven development? Male: Yes, I do. Norbert: Do you do it all the time? Male: Yes, I try to. Norbert: Okay. I tried to, but it doesn’t really work that well for me personally. That’s a preference, and test driven development, to me, [00:58:00] only works when you know exactly how you want it to end up. Projects that I work on, it’s more iterative. It’s more, do you like this? Do you like like so? Doing test driven development like that is just not agile enough for me. It’s really different for every person and for every project I think. Yes, it’s a very clear observation that snapshot testing, it doesn’t really [00:58:30] work well if you’re in a TDD mindset. Male: I have two questions, sorry about that. Norbert: Sure. Male: Is it possible to add [inaudible 00:58:44]? Norbert: Definitely. Male: [inaudible 00:58:45]? Norbert: Definitely. Storybook is extendable. It has 17 add-ons that we maintain ourselves. A few of them are for markdown parsing, so you can show [00:59:00] documentation next to or overlay any component. There is also other people making open source add-ons to it, and you can create your own. It’s really easy. Male: Than the other one is, is it possible to show the code that [inaudible 00:59:19] the React product? Norbert: It’s one of the things that I want to do eventually where you show the code, and you get to live edit it. [00:59:30] Then display that continuously. It’s something that I’ve worked on in another tool, it’s called SourceJS. Yeah, that’s a pretty cool feature. Though, the idea behind Storybook is that it’s so easy to grab your IDE or your editor and start editing there. Yeah, just quick experimentation for even non-technical people, I think, is definitely a plus. It’s something that I [01:00:00] would definitely want to have developed, or develop myself. I’m currently focusing on migrating it to use WebEx two, and creating a [inaudible 01:00:10] for it, because it was spread over like 30 [inaudible 01:00:13]. Male: Then one more question. Norbert: Okay. Male: Do you know when Cypress [inaudible 01:00:20]? Norbert: I do not, no. I do not work for them, and it’s all up to them. It needs to be financially viable for them to do so. [01:00:30] I think that it’s something that has been requested a lot, and I’ve heard rumours that they would want to, but that’s not their main focus right now. Male: Okay, that’s a week from today. I would like to give thanks once again to Norbert for coming all the way for [inaudible 01:00:51]. If you have any more questions, we’d like to [inaudible 01:00:56] this, and- Norbert: I’m there, so if you have any questions come to me. I’ll [01:01:00] be happy with any question really. Male: Yeah.