Don’t Let Your Unit Tests Slow You Down: Improve your front-end testing – Daniel Irvine

hello can you hear me okay yeah all right okay so I’m slightly nervous because usually when I talk about testing it’s two audiences who care about testing and the react community I think is you know a little bit well I’m not gonna say okay so there’s two parts to this silk and the first part the majority of it I’m gonna talk to you about six ideas that I think can improve your testing and the second part of the talk is some philosophies so some kind of deep thinking about testing in general but first some context setting so too long didn’t listen of this talk is a good test remove fear of change so I’m gonna talk about fear today and how to us can help you go faster by helping you have confidence in any change you want to make to the codebase and I think you know if you’re if you’re both sent here today you can that’s the message if you if you’re absolutely already dead set against testing and you know go to sleep now that’s fine that’s the message it’s not talk about TDD so I am TD deist I do practice TDD but I think there’s a problem with a lot of talks about TDD and you probably recognize this yourselves they’re quite shaming so if you don’t practice TDD they’ll make you feel like you’re crap if you don’t know what you’re doing you’re not proper developer and and I kind of feel like that’s not the right approach so although that is what I do in the day today this is the ideas I’ve got here are things you can apply even if you’re not doing TDD and I don’t really want to talk too much about that because I’m trying to not turn you off testing and so an example of that and this has infected our community a little bit is that a lot of talks will will tell you how TDD isn’t about unit testing or you’re doing it wrong if all your tests of unit tests and the problem with this is that when a perceived authority figure says something like that’s you you believe that as the law right that’s the that’s true and unfortunately you know our software laws are not like laws of nature it’s not like the law of gravity it’s not things are absolutely true they’re things it’s just somebody made up right so when we’re on stage and we’re telling you what we believe it’s just stuff that we find works for us there’s no truth in it it’s just our experience and that that’s the messaging aspect to this so and it’s true of my talk today as well so my message to you is a you know take all this with a pinch of salt it’s just what stuff that’s work for me and I know it works for other React developers it might not work for you so we all know the 10x developer myth this idea about a rockstar developer of course there are really really good developers out there there are React developers who are fantastic leave great at what they do and they work very fast the problem is that they tend to be very insular and they work alone and they can be problematic for teams as a whole and I like to think of testing is something that is a whole team activity and that’s because it’s all about requirements and requirements help us communicate across the whole team so I’ve got an example here of a simple requirement about something this is something the whole team can talk about unexpected in software and one of the reasons why I think testers can go super fast and accelerate their own work is because they’re constantly focusing on these requirements that the whole team understands so with that said I want to look at the difference between developer tests and QA tests because they’re different and this is something this is fundamental to what we do as developers we are trying to write tests that help us speed us up QA tests are more about proving that what we’re delivering hasn’t broken or it’s the correct thing so there’s there’s different things that play there so to start with develop test will encode requirements like I just talked about and then also catch regression right so there they’re there I mean this is kind of obvious stuff right so your automated tests are there to tell you that you haven’t caused regression in the software well yeah QA tests do that as well so they have that in common developer tests also do all these things right so they assist you with design to start with they’re going to help you decide if you’re testing against the API if your own software it’s going to tell you if it’s good or not it’s going to help you make design decisions it’s going to help you refactor because you’ve got that CFD neither refactor refactoring you know the kind of

standard definition retooled if refactoring is that it’s changing the internals but the external behavior remains the same and that’s the regression part of our test they explain your code to others that’s like comments tests are these amazing things because they’re like comments but they’ve got this verifiable proof with them right so often you’ll find testers who never write comments because they don’t need them their tests or the comments they pinpoint error so I’m going to come back to that one in detail so I’ll skip that for now and they minimize debugging and they minimize manual testing so this is this is probably the the biggest thing I see about react community a lot everybody is very much about you know the latest browser plugins or the constable environment in the browser that’s a really slow thing to do right if you’re writing good tests you should never have to debug never you know ideal situation would be you’d never be debugging because debugging takes a lot of time if you can write a test that proves that where failure is then you’ve got a little repeatable unit there that is going to help you every single time you have to check your changes so if you’re trying to fix something you can make a change see if it passes the test and the same with manual testing who actually wants to use software software is a horrible thing most of the time you know and again it takes time to load up your app to kind of get to the point that you’re trying to test or figure out that takes a lot of time QA test do a few other things as well I’ve here’s just – I’ve thought off the top of my head probably a bunch of other things the QA tests are there to do as well but they’re different right so these top two assists with design and guide refactoring that’s kind of what I’m talking about removing fear of change so if you have your tests there in place and they’re good quality tests then you’re not going to be afraid to change the code underneath you’re not going to be afraid to play with design because you know you’ve got all these automated checks right so I guess I challenge you to maybe think about that emotion of fear in your own code does it affect you do you have moments in your coding process where you’re scared to change code are scared to touch a clock maybe there’s a component you have that you know is absolutely horrendous all of the bugs are in that component I you don’t want to touch it because you know that something’s gonna break if you touch it that’s the kind of fear that good tests will help you avoid entirely so these last four are about reducing dev time clean and simple so you know we’ll talk I’m going to talk about pinpoint errors in a little bit the rest I’m gonna leave to the side for now okay let’s move on to the six ideas and first of all I’m very simple hopefully you know if they’re beginners in the room have never tested this might be new to you I hope some JavaScript developers will already be familiar to you your test should always be in this format arrange actors our first part you set up your inputs your collaborators the middle part that’s where I’ve got this render call that’s the action that’s the thing your test is like your test is acting on so that’s what the requirement is the behavioral requirements so here I’m saying when I render the component I expect this thing to happen and the expectation is the assertion so there’s always these three parts and by the way a lot of my tests are this simple right so if you’ve got tests that are dozens of lines long they’re they could probably be simplified into a few different tests that look like this so I did two again I’m hoping this is familiar to some of you you want to test the external behavior of your components this true for all types of software functions classes react components it’s always true you want to be focusing on that on the behavior the external users of that component or class see not the internal state and I’ll talk about that in a second so we saw an example in the last slide where I rendered the components one part of the component lifecycle right you you mount a component here I’m clicking a button so the action is I’m clicking a button another part of the lifecycle of a component this quick function I’m gonna show a later it’s interacting with the dorm actually so I’m not calling a components internal handle click function I’m actually instrumenting the dorm here to say okay I’m clicking in that button that I expect to be in the dorm here’s some mill uniform same thing right submit form using the Dom API the action is main uniform and again that causes some lifecycle to happen in your component another thing this is slightly more complicated this is getting updates to

props right so how do we how do we put the test what happens in our class our component or function when things change well we can call it multiple times so with this component we ran there twice and I’m going to show the definition of render and waiting a little bit but in this case that’s going to trigger all of the code we have to update props in our component before I move on from this idea I did mention about not testing state and I don’t have an example of that I was kind of challenged to write you an example of not testing state and it’s I realize it’s really hard when you haven’t done something for a long time to come up with an example of thing that you believe to be wrong so I don’t have an example for you but the the thing about testing state is it’s brittle right so when you’re testing things and you’re testing the external behavior you’re doing that because you want the ability to change how it works inside you want to be able to refactor things and if you’re testing stay you’re very locked in to how that component operates so as soon as you want to change something you’re gonna have to change your test even though the external behavior hasn’t changed okay idea 3 we’re getting a little bit more complicated so be aware of the test surface every react application is a tree of components you’ve got a root component and you’ve got a bunch of components inside of that and this is where React.js engineers get confused about unit testing so if we write tests for a those tests our testing behavior of a and the behavior of C and D as well all of that so the surface area is all of that gray box that means if there’s an error if any of your tests for a fail you’re not entirely sure whether the failure was in a or C or D you’ve got to hunt that down right so if maybe you’ve got some tests like this that have failed and you’ve had to go and search for why they failed good tests pinpoint errors that means you don’t have to search for why failed a good test will tell you immediately why it failed and and point to the three or four lines of code that the failure could exist in so when I’m talking about going faster through your tests this is this is kind of what I mean great test will immediately say hey there’s a problem in this part of the code go and fix it so if you’ve got test a you know that’s not really the case whereas if I’ve got tests against be the surface area is much smaller if failure happens in one of my tests for B I know that the error has got a B and B so a way we can get around that is writing tests just D right so there are these different levels of tests there are all unit they’re all unit tests in a way you know you can call them whatever you want it’s fine to write tests at a it’s also fine to write tests at D and this is one of the benefits as I said about refactoring the tests we get to make a mess first of all so in the previous slide I had a and then I had seen the as part of that and I talked about how you know if you have detested just this level of a then you might be in trouble but that’s actually a perfectly normal situation to be in because when we make a mess with tests will often just hack together code and this is another way that we we get speed in our development we’ve got the tests to back us up so we make a mess first that means we don’t think right we don’t stop to think about the design we don’t stop to decide whether we’ve got the right layout or four components already we just write it all in one long procedure so maybe a ended up because of that it was just this one big long component because we decided we were going to make a mess and then at that point we’ve got the tests there so we’ve written all of our tests we’ve got an area but it’s a bit of a mess we are safe to refactor that and maybe we extract out C and D because we think that’s the cleaner thing to do so we do the design thinking afterwards when we have our tests there to back us up and we’re safe to do it and we don’t have that fear of change so you know then that’s a good point maybe you want to maybe then that’s when you realize your test for a aren’t helping you so you decide okay I’m going to go and refactor those and pull out some tests for T so that’s why unit tests are important okay idea five we’re getting into the big ideas now this is this is common advice in every language in every framework you know if you’re writing in Ruby on Rails see I might seem to you you don’t want to have a you know Ruby on Rails application you don’t wanna have a react application you want to have an application that happens to use react for your tests writing test for react components is complicated you have to deal with life cycle like we already talked about you you’ve got to use these testing libraries testing simple functions super easy right you just

testing what you put into the function and what you get out of the function those tests are very simple so any business logic pull out of your components it’s kind of all Redux is doing in a way people I’m always interested in how people define complexity people think Redux is complex and react is simple well actually from a test point of view it’s the other way around right so because Redux when you’re building into Redux you’re just writing functions it’s very simple the test functions we are components not so simple the test and now at that point of the last point there that’s super important even an if Simmons complexity and I’m going to come back learned a little bit so idea six no this is a big idea so yeah it’s absolutely fine to use enzyme and use react testing library but they’re actually not that complicated and I’m gonna give you three reasons why I think you might want to try writing your own test library first one is it’s a really good way to further your learning so if you’re not sure how the Dom API works it’s a great way to learn that’s all these testing libraries are doing to an extent it’s just instrumenting the dorm so they’re clicking on buttons for you their rendering real components for you it’s actually not too difficult and you’ll learn a lot by redoing that yourself second point this is slightly more subtle but it’s a very important one they lock you into their way of working so if you’re using an enzyme for example you’re gonna write your tests the way enzyme one used to write tests and as a tester you know yeah I might have my dogmatic view of how I want to write tests but I don’t necessarily want to lock you into doing the same thing you really you’re just dealing with react components in the dorm there’s so many ways to test that and there are all many of them are perfectly valid but if you use a testing library you’re not going to have the chance to explore that I think this has come up quite recently because I’ve heard of a lot of people not migrating to hooks because their testing lab it doesn’t support it you know my response is well you know you don’t need the testing library just move the hooks obviously that’s a just it’s a huge just right but it’s maybe something to think about and third point you know you don’t necessarily need to learn yet another library right learn the Dom API that’s always going to be important it’s always going to be useful for you to know so in a way it’s simpler right so if you’re teaching novices it might be simpler to just teach them the Dom API rather than teaching them yeah another library so here’s some examples you’ve already seen all these functions these are the functions I use to test my code render and wait so that just calls the render form and wraps in an act call an element so that I can use that I can use my expectations which I think you’ve already seen in a previous slide it just calls the query selector API click calls the react estatales package which is already there for you and the same with submit right so these the way I test I just write a bunch of little helpers like this you know I know my own works for shallow rendering to write so I’m not going to show you the code because it’s slightly more complex and I don’t want to focus on the code I want to focus on the idea so I’ve got function element matching which just walks through the tree of react component instances which the reaction renderer has produced for me so again you know this is a this is a big idea I’m not saying you need to go and dump your testing libraries I’m saying that this is a great way to further your learning and it’s entirely possible when people do this okay so that’s the six ideas I want to move onto more of the philosophy now the JavaScript community isn’t well known for its testing I think that’s fair to say it’s probably an accident of history more than anything else but the way that we test is kind of boring it’s been with us for 20 years Kent Beck spoken TDD was written almost 20 years ago so why does the JavaScript community not have these ideas maybe it’s because you believe they’re not useful to you that’s fine maybe you’re scared to read all of the literature that we have on this so there’s so many books about testing they’re just they’re not in JavaScript they’re in Ruby or they’re in Java you know I’d say don’t be scared of that like these languages aren’t complicated and the ideas apply they they can completely apply to react and so you know gopher there’s no reason to not want to test like I say testing will help you go faster imagine not having the debug right I think that’s what kind of win for you so it’s a bunch of ideas I want to look at some

books so the first book is 99 bottles of LP by Sandy Matson Katrina Irwin this is tastic book it’s it really about 50 lines of code the whole book is about 50 lines of code and they pour over every single line in a huge amount of detail it’s it’s impressive they really focus on what is the best way to write this particular solution it’s in Ruby but I believe they’re bringing out a JavaScript version later this year and if you if you buy it today though you’ll get the JavaScript version for free I believe so no go for it this is a really good book if you’ve never focused on that idea of an if statement being business logic get this it’ll make you realize where complexity really is in software then there’s actually no test patterns this is like every pattern it’s it’s kind of useful if you’ve got a bunch of experience and you can read it and read about these patterns and say oh yeah I recognize that I do that all the time you know so you get this warm fuzzy feeling from knowing that what you do is what other people are doing by doing all you’re really doing is learning somebody else’s name for that pattern and so I wouldn’t say if you’re a beginner read this book it’s it’s a good one to just pick up if you’ve got any experience at all and it’s very detailed it’s not a light read I’ll tell you that and then finally that there’s my book I couldn’t not get a plug for this in his book about TDD but it is about testing in JavaScript so if you’re scared of other languages come understand that you know oh there’s not many JavaScript books about testing here here’s the way I do it and again about messaging I’m in this book I’m not saying this is how you should test to react components it’s just a way that works for me and it’s some ideas that you might find useful okay so I want to talk about snapshots so snapshot testing that you know it’s a useful way to check your components visual state right so you can check if they’re unexpected changes so it it’s a kind of mechanism to catch for regression and you can visually inspect the HTML so they’re useful but if you look at the ideas of I’ve shown you in the previous slides you’ll see there’s some things that they don’t quite solve so the first thing I’ve noticed with snapshots is that people ignore them right they’re noisy they break all the time and so you just update snapshots you get into this habit of just updating snapshots you don’t really look oh why they’ve fallen over the other thing is and this is something I kind of you know I’ve been talking about going faster as a developer part of the idea of snapshots is that you check them in right you put them in your PRS and you should visually deficit in jizz I mean this is to me this isn’t you know why would I do that right I want to go faster and you’re you’re telling me I should you know look for these huge generated files for differences and see if they’re right I mean it doesn’t fit with how I want to work like I want to go faster I want techniques that are gonna give me confidence but not slow me down as a result so yeah I do think they’re great and if they’re the only kind of test you have you know stick with them not saying delete all your snapshots but I want to go through our list of why I define developer test to be earlier said do they include requirements no they don’t really tell you anything about what your software is meant to do they just say you know hey here’s some HTML it’s not it doesn’t really tell you well I expect this feel to be a required field or anything like that did they catch regression well yeah I mean they do right they absolutely there to catch regression but they’re also noisy as I said so I’m gonna give this a thinking face emoji I’m not gonna score you out today assist with design I don’t think so I mean the design help comes from writing tests and using your API and deciding well is this is this test difficult to write if the test is difficult to write maybe I need to work on my design that’s what good test will we’ll give you some shots don’t give you that design feedback same with refactoring so refactoring is partly designed but it’s also partly regression right so if we go back to the definition of refactoring it’s that you want to be able to make internal changes but maintain the external behavior so you know it’s not just help us do that so I’m gonna give that another thinking face I almost want to get that a green tick but they don’t explain your codes others so they’re not comments they don’t pinpoint errors I don’t think they minimize debugging cuz if they break you still have to figure out why and I guess the same is true for a manual testing so

you know yeah like I said these are great and all I said right at the start I don’t want to have this be a TDD talk about shaming you into doing something else snapshots are perfectly fine but if I think about tests and developer tests I want to be writing great tests tests that help me go faster right help me produce software of higher quality that’s more valuable to my clients and usually when we start writing tests we start out writing about tests and this is why a lot of people stop writing tests it’s because they they’re writing bad tests that slow them down they’re writing things that you know they have to go back and fix because the tests of brittle are they they don’t catch regression it actually takes a lot of effort to get to the point where you’re writing grreat tests and so people stop because they’re right in bar tests which is unfortunate you know in the middle somewhere we’ve got new tests here and I guess I would ask you I’m not gonna do this but you know where to snapshot test fit on this line are they you know what yeah I’m not gonna answer it but what I will say is you know if you’re if your answer lies anywhere to the right of no tests I’d probably want to ask you why why do you think that okay so to finish up like I said I’m not you know the truth is snapshots are really helpful to us there are a bunch of other test techniques that also are really helpful to us and it’s worth your time learning them it’s kind of sad that the JavaScript community has forgotten about that if you’ve got the confidence to go and read books and test in yeah they’ll be maybe they’ll be in Java you’ll have to get over that the testing is the same regardless so my question to you is you know what’s your fear of getting started what are you going to do to you know go back to your desk on Monday and take some of these ideas into your work and help you improve and that’s it thank you