Tests in React Native with testing library

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello folks today i'm gonna teach you how to test react native applications using react native testing library and integration tests but first of all why use integration tests well basically because in my opinion integration tests have the best cost benefit between amount of written code and reliability gained from that code because if you don't know exactly what integration test is i'm going to give you a quick overview about unit tests and integration tests which are the two most common ways to test your frontend basically when we talk about integration tests we just care if our system works well together and when we talk about unit tests um what you care about is you want to like break out of your software down to the smallest testable pieces of code possible and then you want to test them in in isolation what means that for instance if i were to test a clap uh if i were making a an integration test i would say okay my hands touched and make any kind of sound if yes my test passes if not my test fails but if we were testing a clap using unit tests what would what i would probably test is my right arm movement and my left arm movement and then i would write something like uh i want my right arm move to the center of my body and stop approximately in front of my nose and i would say the same thing about my left arm and then i would test my right arm [Music] and my left arm in isolation but if i were to run them together those two tests passing doesn't necessarily mean that my code works because my arms can make the right movement but they don't like touch each other and make the sound i want my code to do in this case my example whatever and that's why in my opinion integration tests are much simpler and much easier to write if you're starting to test applications right now uh obviously obviously in a real world environment you're gonna want to have all sorts of tests uh not only unit not only integration and not only end-to-end tests which is a subject for another video if you folks want me to to talk about it also um but enough with the chit chat uh i've written a little application that we're gonna test together and hopefully it will help you to get a good grasp of how integration tests work and how they should be written using react native testing library so let's go to the code folks i'm just passing here to clarify one quick thing uh during various points of the video you are going to watch i use specific methods from libraries such as jazz and react native testing library um that i'm going to teach you but i never really explained where did i learn them from so i just wanted to make sure that i told you uh to read the documentation it's really important so uh if you see like chess documentation you're gonna see that it has like a bunch of detailed guides uh it has its api reference it has framework guides it has a bunch of stuff and the same thing goes for react native testing library it has like guides sorry here it has like apis it has external sources and stuff like that and it's super important for you to read the documentation especially when you feel overwhelmed or doesn't know what to do or how to test your application because even though i tried my best to show you the most used uh utility methods and functions from those libraries there are way more methods then it's possible for someone to cover in just one video in those libraries so that's pretty much it i just wanted to reinforce the message please read the doc gonna make you an awesome developer and i'm gonna leave you to my video i hope you enjoy it bye so this is the application that i've built for us to test together and as you can see it's a really really simple application it's just a a to-do list app so basically we have this text input right here where we can type stuff so for instance test and we can click this giant plus button here on the screen and this is going to create an item for us and we can also delete items and we have some kinds of validation so for instance if i try to create an item with without typing anything into the text input uh i'm gonna see this error right here uh as you can see this is a super super simple application i really avoided doing anything super fancy here because i wanted the whole focus of this video going to the testing of the application the first thing that we got to do in order to be able to test it is we have to install react native testing library um you can know how to do this by typing react native testing library in google and it's either going to take you to to their github page or directly to their website but basically all that you got to do is you got to choose if you're rather using yarn or npm and then copy and paste this command right into your terminal uh i have already done this so if we go into my package.json i already have the testing library dependency here in dev dependencies because uh anything that's related to tests is not going to production it's just here to help us develop our application and that's all we have to install in order to make sure that our application is gonna work that our tests are gonna work when you create an app using react native init just as i did um it already handles setting jazz up for you just as a test runner basically jazz is going to be responsible for finding and running every test that you write but it's already configured by default so we do not have to do anything uh the only thing that we have to do to start our tests is create a new file and every test file that you write has to be one specific keyword that's going to help chess know that is that it is a test file so what i like to do is i copy the name of the component that i'm testing in our case this is app and then i add dot and instead of adding uh js directly to tell my my uh to tell my computer that this is a javascript file what you have to do is you can either choose to add like tests to the middle of it or you can also call your test files spec files uh they're both the same thing actually this isn't gonna change anything in your in your tests it's just a matter of preference uh i usually use spec but it doesn't make any difference at all but once i i run my tests uh jess is already going to recognize that this app.js file is a test file so if you if i run this command right here um it's going to give me a failed test suit basically because um every test so it must contain at least one test and app.spec.js is an empty file so that's why it failed okay but before we start testing let's think what do we want to test what's important to be tested well as i mentioned in the introduction tests special integration tests only care about reliability the only reason they're there is to make your life easier is to make you sure that you can trust your tests so basically what you have to do is think of the expected behavior of your application and then ex uh tell your code somehow to expect the behavior that you want your application to have now we have to think what do we want to test in our application well basically this is a to-do list so i expected to i expect to be able to create items so in this case let me just uh do this test and create an item so that's one expected behavior let's write it down create an item i should be able to delete one item so just click the delete button and it should disappear delete an item uh i should be able to create more than one item so i don't know maybe um your app has some kind of specific bug that makes that allows you to create one item but not many so i just have to create more i just i'm just gonna write this down more than one and okay i just make sure that i can create more than one item so create multiple items and i also want to validate that when i'm creating an item i have valid data in this in the text input so whenever i have like i try to so whenever i try to create an item with an empty text an error should pop up on my screen so shoot show and her sorry er whenever i try to create an invalid to do and i also expect this her to disappear at some point in our case it disappears once i create a valid uh text so shoot so ever warning error warning should disappear once a valid item is created and basically these five items are what we are expecting our tests to validate and that's it but how do we do that actually well um when we talk about react native testing library it has a very awesome way of testing stuff which is it expects you to behave as a user of your application what means that instead of i don't know having to know your code to know what you're doing you're basically just going to inspect stuff that is on the screen stuff that is able to the user to see so for instance if i want to select this create i item button what i have to do is search for a giant plus button on my screen and that's it and that's how you're going to query all of your stuff inside react negative testing library uh again maybe that's not as clear as it should be for you but i'm going to start writing some examples down and as i go along uh things are going to become clear for us so whenever we are going to test something we need to impart a few things before well the first thing that we got in part is the component that we are going to be testing so in my case i'm gonna import app uh and the second thing that we have to import are testing libraries methods that you need to render your components and uh fire actions in it so i'm just gonna import them and i'm gonna explain their utility as with that stuff from ad testing library react native the first method that i'm gonna import is render render is basically going to make us able to interact with or with our application um and that's it that's outing parts we need for this moment maybe uh you're not familiar with chest but just has some globally available functions that allows us to to write down our tests and one of them is called it oh sorry it my vs code just imported something here and it accepts two parameters the first one of them is a quick description of what are we going to be testing so let's test this constraint that we have already set up so create an item and i'm maybe i'm getting a little ahead of myself here but it's a good practice that your tests made make sense when read like plain english so usually whenever you use it to test something most people start their tests with shoot so it makes uh it makes sense as an english sentence so it should create an item it's pretty self-descriptive if you've never seen this step before you're probably gonna know what this test wants to achieve and that's it and the second parameter that it accepts is an arrow function in which the your test is going to be run before we start testing i just want to say that it has an alias so it's another name it can be called by which is test they're both the same thing they're just like spag and test choose whatever you like the most i rather use it so i'm gonna stick with it i don't know why i did that but okay but well how do we start our tests well the first thing that we got to do is we gotta render a component so we so it's working and we're able to interact with it so let's do this so i'm gonna write const rendered component and i'm going to render it i'm going to render app in google play and jsx oh i just remembered something actually um i have to import one more thing which is react because in the version of react that i'm using um you have to import react into your document every time you're using jsx uh if i'm not mistaken newer versions of react doesn't doesn't ask you to do this but in our version it does so i'm just gonna keep it here and basically what this render function is gonna return us is a bunch of utility methods that are gonna allow allow us to scan our scanner component and interact with it and make assertions based on it uh maybe you're not so used to the [Music] to the concept of assertions but basically tests are all about expecting some behavior to happen when you make that library is gonna give you the means to to do those certain actions but yes search but assertions are the way you are going to tell your program to expect some things to happen so before i start this test let me just do a simple a simple example for you if you've never seen tests before test being done before so i can create a variable called con's test and assign the value of q plus q to it and that's that's something being done on my program so that's half of her test what's left to be done is i have to say tell my program to expect something to happen based on what i've just done so again this is a globally available uh function by jest but we have this function called expect basically it expect oh sorry basically you'd expect to receive a value in our case it's going to be the test variable and you can you can say what you want it to be so in your in our case i expect this to be equal to 4 because q plus q is 4 or to be equal to 2 plus q whatever it doesn't mean it doesn't it doesn't matter sorry so i expect tests to equal 2 and then i can run my test and see sorry and see what has gone wrong because apparently oh yeah i said that it was going to be equal to two it has to be equal to four so now if i test it everything should be all right so yeah our test passes because i've done some action and i've expected a result from it and if by any reason uh the action that we generated doesn't doesn't has the expected output our test is going to fail so for instance if i type 3 here our test is not going to pass uh i have an extension to the s code that already runs my tests for me so you can see that it has already failed here but on the terminal it also has failed because it has the wrong um wrong value so that's basically how all tasks are gonna work um but okay we generated like a super simple action which is assigning a value to a variable but how do we apply that same kind of logic to our component the basically returns us a lot of utility methods that we can use to scan down our our component and interact with it so for instance if i instead of like assigning this value to a named variable i just destructor this structured it i can press ctrl plus spacebar and i would see a lot of available methods that ranger returns us they're all very interesting but the one we are looking for right now it's one called get by text and its name ex it's pretty explanative it's gonna search something on the screen based on the text he passes as a parameter to this function and if this item that we are looking for exists is going to return us its value and if it doesn't exist it's going to throw us an error so in our case what we want to do is we want to search for this huge plus button here in our code base so let's do this let's do const okay my tabs are okay just let me adjust my spaces and that's it const add item button and i want to query my document by text so i'm just gonna use the get by text method and i'm gonna search for plus and what we have done so far is we rendered our component and we have searched for this button right here and it is stored in this variable but that's not enough in order for us to create an item we have to to do a series of steps the first one of them is finder the plus button the second one of them is finding this text input right here we have to type stuff into this text input we have to press the add icon button and we have to verify if the item that we are trying to create has been created so the first type of this is done we have just found the add item button but how do we find our text input because even though i have this placeholder text right here we do not have any text on it so we cannot use get by text because write something is not really a text in our screen so the solution for us is to use another method that is returned for uh returned by render which is get by placeholder text so get by placeholder text and we are going to look for we are going to assign our text input value to a variable called text input input and we are going to use this get by placeholder text function and we're going to pass the text that we are looking for as a parameter so in our case it's going to be write something all right so we have done two things so far we have done three things actually we rendered our component we found our at item button and we have found our text input button our first step is to type something into our text input but how do we do that we do not have the means to do that just yet well thankfully for us testing library has a set of utility methods that are available inside a utility method called fire even so whenever we want to interact with anything on on our screen we are going to use fire event so as i just told you what we are what we want to do right now is type some text into our text input so we are going to call one of fire events sub methods which is uh change text and change text accepts two parameters the first one of them is the variable that is gonna suffer that mutation so in our case it's text input which means that we are going to interact with it and the second parameter that change text requires is the text that we are going to pass to our component so in our case i'm just gonna type first to do and after that the next step that we have to follow is we have to press the add item button so again as you might already imagine we have to use fire event but we cannot use change text we have to use another sub method called press which is very simple it just it just requires uh the item that is going to be pressed so in our case i'm going to just type fire even press and pass add item button as a parameter so so far what we have done is we have rendered our component we have found at item button we have found text input we have typed something into our text input and we have pressed or add item button so so far our arc our item should have already been created and how that's left for us to do is to make an assertion and make sure that whatever we just created really exists in our code but how do we do that well basically uh i misspelled first here didn't i i'm not sure for how do i write first sorry let me just check this on google uh no yeah i just write it just written it in the right way so basically what you have just done is this first to do and created plus and what we have to do in order to make sure that this exists is we gotta search for the for this text first to do because we have to make sure that we created uh the item that has this specific task that we've had that we've passed to our text input so first of all let me just change this value for a variable so cost created item text because i'm gonna use it more than once and i do not want to rewrite it and what i i want to do is i'm going to create a variable called created item and i'm going to get by text and i'm going to search for this text okay we have already found this but how do we make sure that this really exists well basically we can rely on chests globally available expect method so we can use expect i don't know why my vs code keeps autocompleting to this weird stuff and we can pass create an item as a value to be evaluated and we can use a map as a method of expect which is not dot to be new so basically what we're doing here is we're expecting created item we're having a negation operator here and we're saying to be new so it just has to exist and if i run this test everything should run just fine and my test suit should pass but there's kind of this golden rule when you're testing something just so we can make sure that we are not having any kind of false positive uh you should never trust a task that you haven't seen fail so let's just make this test fail on purpose just to make sure that we are not getting some kind of false positive here so i'm gonna get by text and instead of passing the created item text variable i'm gonna pass this string therefore this text is gonna to be different from this text and my test should fail so let's just see how that goes and yes my test has already failed and as you can see this text text doesn't exist so let's just return it to its normal state and congratulations we have now just written our first test for a react native component together and that's pretty awesome so we can remove this test from our list well the second pass that i want to do is i want to be i wanted to make sure that i can create more than one item so basically it's the same test that we have just done but instead of using just one uh instead of creating just one item we are gonna to create a bunch of them i'm just gonna create two because that's enough for for my test to pass and that's it uh but basically i'm going to to use the same structure as the first test i'm just gonna duplicate this so i'm gonna create created item text under line two and this is gonna be second to do and what i'm gonna do here is i'm going to replicate this and pass created item text two instead of the first one and i'm going to rename this to first created item and i'm going to create the second created item and let me just okay yes let me just pass this down and i also have to duplicate this and make sure that this test passes and if i have done everything right my test should pass yeah my test still passes i don't know why but my vs code extension is not working properly but that's okay uh when we run yarn test on our terminal everything works just fine so that's what matters to us again just following that golden rule i'm just going to change my text and see my tests fail so just to make sure that i'm not getting any false positives here so yeah it just works and now i can delete this and talking about delete now what we have to do is we want to make sure that we can delete an item so basically what we have to do in this step oh i actually forgot to do one thing i forgot to change the this test right here i forgot to change this text's description so let me just do it should create multiple items and that's it that's just a minor detail that's going to help us whenever a test fails because when your test fails as you can see here um the description that you gave to your to your test just is shown in the in the in the terminal so in in case you have i don't know thousands of tests it's just easier for you to uh search for this in your code base so you should create an item and get to the right file that has your test directly now what we have to test is it should is our application should be should delete to delete an item and basically all that we got to do differently than the first test is by the end of the creation of the item we just have to um to find the zax button and click on it and we should make sure that our test that our our item has disappeared so first of all we have to create uh our item all over again and why is that it's because our four tests are being run in different environments actually it's a new render so it's a new it's a new well it's a new render of your application so everything is going to be new uh all the variables are going to be resetted and that kind of stuff here i just copied the creation of uh of an item but i'm gonna delete all of the assertions that i have made so because i do not need them since i have already validated the creation of an item i don't need that assertion anymore because if for instance something happened in our application and we we weren't able to create items anymore i would have like multiple errors pointing to the same same thing and that wouldn't be good that would just create a lot of noise which would not be helpful in the time that we were to solve those problems but that's it so what i have to do here is i have to like create my item blah blah blah and and instead of searching for like the created item text what i have to do here is i'm gonna create a new variable called delete item button and let me just erase this letter here and what i'm gonna search for is for an uppercase x because that's what i used here and this button should already exist so basically in order to delete my an item i have to interact with this button so i have to click on the click on the delete item button so i'm gonna use fire event dot press again and i'm gonna delete press the delete item button so now if our if our application is working correctly our input our to-do item should have just disappeared so basically what we have to do now is we have to search for the text of the created item and make sure that it returns a new value to us but we cannot use get by text because as i mentioned earlier uh whenever get by text doesn't find for the value it's searching for it's just gonna throw us an error so if i do this get by text and pass created item text as a parameter and run my tests it's going to return us an error and you're going to see what it tells us just wait a minute and no instances found with text first to do and it's going to return as an error so when we are querying for texts that we aren't sure that exists in our document what we want to use is actually another method called query by text the way it works it's pretty similar to get by text but basically it doesn't return us anywhere whenever our text doesn't exist so here if i replace my get by text with query by text uh the error should disappear as you just saw in my vs code extension that always spoils my test for us uh but basically we haven't done any assertion here so what i'm gonna do is i'm gonna call this deleted um deleted item and i wanna expect this to be new uh we're just gonna use the same to be new uh built-in method of expect but instead of using the negation we're just gonna use it in the raw way because we do not wanna negate it this time so expect deleted item slash to be new and my test should work just fine again following my golden rule of never trust a test you haven't seen fail i'm just going to add a negation to it and see how it behaves so yarn test yeah my test fails so we can just return it to the way it was um so we have just finished another item of our list so uh now how it is left for us to test we now have tests on an item is it challenging so basically the way that we the way that we make the the error component be shown in our application is when we try to create an item without any text on the input so if we do this we are going to see this error so let's let's just reproduce this in our tests so it should display and and her when trying to create an item without any text and then i just write my arrow function inside of which my tests are gonna be written so i'm just gonna use render and i'm going to render our app component nothing new here and basically i'm gonna get get by text because that's the function i'm gonna use to search for my add item button and for my error component and what i'm going to do is i'm going to copy this line of text so basically i'm going to query for my add item button i'm going to search for it again nothing new happening here and i'm going to press it i'm going to use fire even the press add item button and hence we didn't have any any text written inside of text input because we have just not interacted with it uh what should happen is this message should pop up on the user screen so how we can test this we can say cones we can create a variable and call it her message and we can just get it by its text so please insert a valid text and we can just expect it expect error message slash not slash to be new and if i haven't messed up our test should be running just fine and yes it is you can see here but let's just yeah it just works but again i'm just going to screw it up on purpose just to make sure that i'm not having any kind of false positive so wow let me see what i can change here let me screw this text up and see what happens yeah so now my test is gonna fail because we haven't find any instance with the text please insert a valid random characters text so okay it just works and now we just have one test left to be done which is whenever we have this error and after it we create a valid item the error should be wiped out of our screen so basically we just have to copy the first part of this test that we have just known let me just change its description so it should it should remove the error message after creating a valid item and basically we are going to go through the same process because we have to make the error be shown in the first place to make it disappear afterwards but we're gonna remove the assertions and what we're going to do after we have made the the error be shown is we are going to create a valid to-do item so what we're going to do here is i'm going to do this and that's it so i have a text input i have to just get this get by placeholder text method from render and created commented item blah blah blah fire even press and i wanna use the same uh assertion for my for the second past but i want uh the error message not to be no i want it to exist and let's see let's run this test and it is broken why is it broken broken oh yeah because i'm using get by text and whenever you use get by text if um if the text you are looking for isn't shown in your in your component uh it's gonna return an error so let me just use query by text and use it and run my test suit all over again and now it should pass just fine uh yeah it just passes i don't need to screw this one up in purpose because on purpose because you have just seen it being screwed up by accident uh and that's it that's my tutorial we have just tested an application together basically what we what what you have to do for to use this in a real case example it's just create a file for each document that you want to be tested so each component each route of your component i don't know do whatever fits your situation the best i usually create one integration test for each route in my applications but feel free to do something different if you feel that that is if you feel like that makes better for your application i really hope i was able to help you [Music] i really hope i was able to help you on your testing journey uh this is my first video so i don't know if you feel like anything should have been different please leave a comment behind please leave a like and subscribe to my channel if you liked it and that's it as you can see on my computer today it's december turn 31 so i'm gonna enjoy my new year's eve and that's it goodbye folks uh i happy so that's it goodbye folks i wish you a happy new years you're probably seeing this after new year so happy 2021 and let's be awesome this year and each day better and let's be awesome this year and just kick some ass and that's it bye
Info
Channel: Mobile Magic
Views: 3,768
Rating: 4.9069767 out of 5
Keywords:
Id: vXrTXC5KiCU
Channel Id: undefined
Length: 43min 1sec (2581 seconds)
Published: Tue Jan 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.