React Native EU 2021: Louis Zawadzki - Going 100% TDD with React Native Testing Library

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
this conference is brought to you by codestack react and react native development experts my name is rusevsky and i hope my pronunciation is correct as i'm actually french and work for bam which is a paris-based mobile development agency today i'm going to talk about tdd and recognitive so you might be thinking different things about this topic already you might be thinking well i don't know what tdd is or i hate ud which is a fairly common thought actually or i don't know how to apply it to rec native so if you're thinking one of these i hope there will be something for you in this talk but first i want to tell you another story a story about something called doctor shotgun a few months ago the covet vaccination was made available to anyone above 18 in france to book a slot you had to check regularly on some websites then when one slot was available you had to click through the interface and pray that you were the fastest to get it so what did french developers do they created a script so that they didn't have to check the website and they were going to be fastest anyway one of the script was called doctor shotgun so when that happened i thought well as developers maybe we have some kinds of super powers you know well let's see how it does how we do every day at work let's take for example a specimen of the react native developers let's see what they do in their everyday work first we see them coding on their laptop they look happy and very focused then they open their simulator or install the app the app on their phone and they try the feature and most of the time it just does not work as expected so our developer who has tremendous determination is now going to make use of logs and break points to try to understand what the heck is going on here then they rebuild they rerun several times before everything works fine each of these iterations can cost two minutes or even more so it's a rather painful process and it's not the end of the story for a developer as they have to write a non-regression test to grant other developers including themselves from breaking the app in the in the future so it looks like we don't have much superpowers and we spend a lot of time clicking in real life okay so i think now it's a good time to introduce my topic i'm going to briefly explain what tdd is before going further so we make sure we're all on the same page tdd stands for test driven development it's a development technique from extreme programming that can be described as three phases first when you want to add a feature you have to you have to write a failing test it's going to be printed in red so that's why we call it the red face then you you write the code needed to make the test pass that's the green phase but you're doing it as quick as possible and that's why you need a third phase which is called the refactoring phase where we clean the code before going on to the next feature ok let's go back to our developer story and see what changes when they use tdd so now instead of writing the test at the end when they've already been through a lot of pain they write it first and then they can iterate until the test works which is usually much much faster than using a device because you get a much faster feedback and finally they check on the device and this time it works most of the times so td sounds like a good idea and you're probably thinking well that's in theory right otherwise everybody would be doing it two years ago i thought the same and i wanted to be sure so i challenged myself to do 100 tdd for two weeks but i struggle at first a lot because i didn't know which tests to write before starting my future and to earn you some time i'm going to show you how to do it first let me introduce the approval keynote it's a hackiness clone hacker news is a website that shows links of tech articles or interests i'm going to show you how to develop utility to features that are i believe quite representative of any react native application so first we can see our application here that i already have a list of top stories which are ranked by a mysterious algorithm and on top i have a button that enables me to change between top and new stories which are the newer stories so right now when i click on the button its title changes but that's all and what we're gonna do here is gonna we're gonna fetch the new stories when we click on the button and display them so let's have a look at the code before starting what we have is a page component which contains two states one with the list of items and the other one with the list with the type of stories which is either top or new then we have a toggle stories type function that toggles between tap and use state of the stories type and right now it's just used to get the title of the button which is computed in a little function here then we have a use effect that's called at the beginning of the first render are you know of our component and that gets the list of the news items actually only gets the top stories so what it does it's here it fetches the top stories and it gets all the ideas of the top stories and we set the news items to the first 20 ideas and then we use a flat list in which we render our newslist item which is a component that we're gonna see in a few seconds and we just passed to to this component the id of the item now in this component what do we have we have a state that we initialize to null that contains the item and in a use effect similarly to what we've done before we get the item so what this function does is that it fetches the item on the hacking news api it returns this as a it passes the json and sets the item so this is the interface of the item and you can see here we display some information you can see here for example the title the the host name a number of points the author and the number of comments and we have a test file and in this test file what we have is one test in which we mock the top stories api and the items so these functions um i made them myself and what what they do is that they actually use knock which is a handy package for mocking api calls so here we mock the top stories api and we return the list and here for one item we mock the api for the id and we return a fake item in which we only change the title here so in our test we render the page and then we check that the titles that we have passed as arguments to the mocks are displayed then we have a small test on the type switch that checks that the title changes and finally we have a snapshot to cover our back whenever we change some components but we're going to go back to that later okay so now what i want to do is to fetch new stories when i click on the button and the new stories and not the top stories so what i'm going to do before pressing the button i'm going to do a bit of setup here i'm going to mock new stories and to create that function later and what i'm going to do is that similarly to this one i'll pass two let's say two different ids and then i'm gonna mock these two items differently so with a different title up so here i say some new story and then another story called tdd is my best friend okay so now when i click on the button so it's like it's going to be asynchronous so i'm going to need a wait for from rec native testing library and then i'm just going to check that those two titles are displayed on my application now for the market news stories list i'm going to copy and change slightly the mark top stories list with the new stories api which is this one okay so now i'm going to show here my tester running actually running and we can see that it's hanging probably because it can't find the components we're looking for if we see it was expected to see some new story but it didn't receive anything and that's what we expected so we're done with the red face and now we're gonna do the green face so let's go back to our component and here what i want to do is to change to call a new route and to set the items whenever the stories type changes so what i'm gonna do here is i'm gonna simply pass the stories type to the use effect pass it as an argument here to get news items okay here i add it and i'm gonna already say that it's either top on you okay and now i'm gonna change here my url so in the green face i have to go as quick as quick as possible so i'm just gonna here say end of url and if [Music] stories type equal stop then it's going to be top stories otherwise it's going to be otherwise new stories okay and now here i just change this so i can simply put here my end of line okay so i think that should do it here it's complaining because i don't know maybe it's a bit slow i don't know here just made a mistake up should be better okay that should be compiling so check our tests so as i'm recording my tests are a bit slow and now i see that i have a change in my snapshot which is a good sign and now it displays some new story and td is my best friend in my final snapshot that's actually what i expected so i'm good i'm gonna update the snapshot and now i'm gonna check on the real app whether it's working or not so i'm just going to refresh and see so here i see my top stories and if i click on show new stories huh there's a bug that's interesting because i didn't foresee that that actually it says here undefined is not an object and get host from url so that's one of the cases where you can see at something something is not working but now i know that it's not my code that's supposed to fetch the items that's faulty but rather it's something that i didn't see that here i have a function of passes uh the host to display it and sometimes the url is not defined so here what i'm going to do is i'm going to say this url can be undefined in the my interface and then i'm gonna say okay if my url is defined i return this otherwise i return an empty string and now i refresh let's see what happens i show my new stories i see here this one the third one didn't have a url and that's why it was paid so at this point i'm gonna be honest i should have written a test for that uh i could have actually written a test for this little function here but as we have a little bit time i didn't do that i'll skip refactoring so we can focus on another example now that we've seen how to write tests for an api call i'd like to show you how to do tdd when you want to add some design to your app so let's say that when i click on one of the articles i like it to open on safari and if i've clicked on it and i go back to my app i'd like to see the title the grayed out so i know which one i've already read so let's design stuff and it's usually something that we think it's impossible to do in tdd well of course you could use visual regression tools uh maybe someone has presented some of them at the conference but personally i don't use them because it takes takes some times for this test to run and there needs to be a lot of conditions for it to work first you have to have pixel perfect mock-ups then you have to be aiming at pixel perfect and the data on your designer has to make sense so if you want to make td use tdd with visual regression tools then you need to have a lot of conditions okay but our goal is to be test driven here so here's how i apply a tdd mindset when designing components the only tests i write that can catch a design bug are snapshot tests i tend to use them very sparingly compared to a few years ago as they are not very easy to debug or understand and they can break easily personally i like to do one per page as you can see here i have a final snapshot at the end so i know which place to check on my simulator when i change a component and i see the snapshot is broken now i can't really write the snapshot before coding right but i can do two things to make the snapshot update actually much faster first i can check if there's already a snapshot in place so i don't have to find out later how to mark my data and to update my test so that it is covered by the snapshot two i can find out which existing snapshots are supposed to break so that when i'm happy with my design i can quickly update my snapshots and i know exactly which changes i am expecting if there is a change in one of the snapshot method is not that i did not anticipate and right away i have to check the if this page is still okay so here it is not so much test driven development in the sense of writing the test first but tdd in the sense that you know exactly which output you're expecting from your tests and you don't have much thinking to do after the feature is done so how are you gonna do it so i'm gonna simulate what i'm clicking on my tdd is my best friend item so i'm just going to add some context here so let's say link press ok so i'm going to rename this story and i'm going to simply get by text till it is my best friend now when i save this i expect my test to still pass so i'm just gonna open up the terminal for a second um and now what i'm going to do while my tests are running i'm going to simply change here i'm going to add is red boolean let's do a flag it's red set is red which is going to be a used state of boolean initialized to false okay and now what i'm going to do is that on the on press here i'm going to set his red to true and then i'll change the style here of my component of my title so it's this one so i'm going to change it here so what i'm going to say is that if red is true i'm gonna add to this component color so let's say blue so that it's gonna be more visible to you okay sorry so it's not red it is red so i'm going to run my tests and now what i expect are two things so now i'm expecting that my snapshot for the first of the components that i've rendered displays an error here of the style the previous style and then fault and for the second one it displays the previous style and the color blue so let's have a look at how the snapshot is failing and what it's saying is that okay i have one that turns from an object one style turned from an object to an array to which which i did the color blue and the other one turned from an object to an array with false which is what i expected so now i can update the snapshot i can refresh my app and check if everything works for real so here's my app and when i click on one of the links title turns blue so i'd also like to show you how we can uh open the link in the browser because i think it's interesting interesting as well so here uh after i press the button i'm gonna expect linking which is the rec native library that opens link that open url to have been called with and now i'm gonna pass it the url of my item which is actually the same for every item but it's not really a problem okay so now i save my tests and now my tests are expected to fail and here what i can do is i can in my component do linking dot open url with the item dot url okay so now typescript is complaining that it can be undefined so here i'm gonna just add wrap it into an if condition so obviously i should be writing a test for that but unfortunately i don't have very much time for this demo okay so let's just check if our tests have failed so yeah they failed because linking that open url hasn't been called and i'm going to save this change and now i expect my test to pass okay on another not be waiting while i'm waiting for my tests maybe you should add some accessibility hint to see that your title has been read because it's going to be nicer to your users and actually it wouldn't we wouldn't depend on snapshots but for the example of adding some design i thought it was kind of easy if you like the demo and want to know more about it i have written an article covering more cases and i should be doping the link in the youtube chat section or on twitter after the conference i told you i started a two weeks ddd challenge but i did not manage to do 100 tdd on the first day so this is how i did it and how you can do it too first before going to tdd you have to train at two things the first one is to train at refactoring it's a major part of tid that's easy to overlook and it's easy to mess it up too there are tons of books and websites about refactoring my favorite ones are refactoring.guru and they can the martin follower book so check them out if you want to know more about it then you should also know how to use jest and work native testing library before starting tdd otherwise it's going to be a lot to learn at once then when you want to apply tdd you should start by doing it where you have confidence in your test where you already know how to test the feature that's why in the wind face if your test is still not passing you're sure that it's not because of your test and it's a real bug otherwise it's going to cost you a lot of time then for every case where you don't feel confident about your testing learn how to write the test afterwards so you'll feel confident next time and you know how to write the test and if you apply this you get closer and closer to 100 td and as i personally started to apply tdd more and more i discovered it was bringing me more and a lot more than just faster delivery the first thing i gained was a better knowledge of my testing tools just android native testing library in particular and as my tests were becoming more important my tests files became first class code to me that means i was paying more attention attention on how i split them and i started to write custom functions and extract some of them just for my tests and as a consequence they became easier to maintain and a lot simpler to write and i also increased my test coverage and by that i mean i really increased the number of features that were covered by my tests and finally in many cases i figured out that my initial architecture or technical solution was not good enough to write simple tests and usually by making more testable it was actually easier to understand and change later the code and that's what makes me think that ted makes me have a better architecture so i hope i've changed a bit of your opinions if you didn't know what tdd was when you when you started this talk hope now you know what it is and you know how to get started if you were a bit skeptical about tdd i hope you want may want to give it a try or at least to discuss it with some colleagues or you can discuss with me on twitter if you like and if you didn't know how to do it i hope i've given you all the keys or at least some of the keys to get started thank you very much
Info
Channel: Callstack Engineers
Views: 661
Rating: undefined out of 5
Keywords: reactnative, reactjs, javascript, developer, softwaredevelopment, frontenddevelopment, coding, conference, testinglibrary, testing, codetesting
Id: SpStMyQbiao
Channel Id: undefined
Length: 26min 3sec (1563 seconds)
Published: Tue Oct 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.