Angular Testing In TDD | Shai Reznik | AngularConnect 2018

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] okay let's start a talk remember the name writing a feature guided by a responsible maniac angular testing in TDD you'll see why okay so a little bit about me yeah so I'm sure Resnick and a web developer and consultant I'm a blogger I'm a teacher I hope you'll know it that about me but I'm actually an actor also as well I acted in a Harry Potter I was the Thunder okay and I'm a famous speaker okay and I ran high risotto which is an online school we have the free video courses about angular and testing and stuff like that so check it out so a few months ago I sent a survey to my high-risk community and asked them what is the reason you're testing your code what problems are we trying to avoid so I got answered these are two out of the dozens of answers but basically it came down to two reasons first they want to avoid bad quote quality okay we want to avoid it and second lack of confidence in the production code itself in the actual product so let's talk about bad code quality what is it okay this is an actual file of one of my clients project I that's why it's blurred butts watch the line number okay yeah actual file that I had to work with and long function so long file long functions basically it comes down to too many responsibilities also bad names and basically if you do that while under pressure people hate you and they basically want to hit you and and also secretly they are wishing for you to meet a murderer's rabbit in the bathroom okay awesome so don't do that what you want instead is to do yeah okay can you laugh again okay you want small files okay and you want small functions that both have one single responsibility aspire to one single possibility and basically it helps with the maintenance of the code and the productivity so you don't have to look for stuff when you're changing the code what is low confidence so you know I personally hate when I need to deliver a feature and then do not know if I'm gonna you're gonna crash or not you know the production app and get the phone call in the middle of the night of like production is done okay I need to fix it so I hate that feeling okay so what you want instead is confidence right you want to have confidence in your code so the project can evolve if you are afraid to touch a certain part of your app whoever was afraid come on okay yeah we all so that means that the project you know it's going to take longer time to change stuff so that's why we have automated tests and so if like I don't know I've been doing testing for a few years six months ago I decided to focus only on that because I got sick and tired about the the tools that we have the amount of time the complaints and I get from clients and stuff so I decided to focus my energy on that and create open-source tools better way better better ways to do tests better syntax and also what I'm about to talk about now is unit testing but it's not the only type of test we need to write in order to get the better confidence that's why I created this website test angular comm to focus only on testing angular yeah and and and I'm gonna release in the next like two weeks a free workshop of all the types of tests we need to write and basically that not that much but to cover everything maximum coverage so yeah you can check it out and the technique that I found most useful to deal with two problems is TDD test-driven development what does it mean you write a test the test runner fails and then you write the production code the code that goes into production and then the test runner show the green sign that is succeeded and now you can refactor your code as much as you like as long as it's green you're good okay so a few months ago I gave a lecture at angular app in Israel about TDD and the feedback I got afterwards is that it was too theoretical so I like to deliver value to my audience so I decided to so I submitted the same talk before I got the feedback and I got the feedback and I completely redid the whole thing to make it more practical so we're gonna do a live coding in TDD style today yeah I didn't see a lot of talks that do actually show the TDD but we're going to do it live so let's talk about the feature we are going to build okay and most of the time we see talks about to-do lists right or calculators and stuff like that no not I hope I'm not offending anyone but we're not that those are not the type of apps we are writing and we will see these demos because it's hard to create the whole app okay and to demo a real use case so I decided to build an entire app just for demoing real use cases in tests and this is a real website it's called a llama date okay it's where llamas go and find their love okay and the feature we are going to build is a small small feature called let's let's not Google okay so the feature we were going to build you can see wait yeah it's a matching Queens it asks you questions and then you could you can answer then it basically shows the Thank You page and that's basically it okay so great so that's that's you know for the machine learning to work and to meet you Valerie Lama okay so this is what we're going to build we're going to build a small slice of it because again takes a lot of time and an effort to do that and it's the last talk of the day but I want to show you how I really developed my code like in real life with the syntax that I'm using and such so I didn't like converted it to the normal syntax we all know so I want to go over a few concepts each one of these concepts can take me a half an hour to expand so I just going to go over them very briefly so we'll be on the same page okay so the first concept is a test driver it's concerned from my friends at weeks who are heavy testing writers and basically it it comes down to what who knows what what is a page object okay where ever wrote protractor test okay so pay job page objects basically when you have a component on your screen and you want to query it to get the Dom element so you can write a page object with like helper methods so that queries the you know get the object for you to get the Dom element that's a page object okay that's bad who use test bed writes test wish to write this but don't have time who hates test will convert to you someday okay so test bed test bed is the way is the API from the angular team which gives us the ability to configure our test you probably see the configure testing module and where and probably when you deleted the spec file after you generate the component this is what you learn so okay so so tails bad we use it to control the test and to trigger detection all that stuff I find it a bit complicated to use all these stuff so I created the test driver which is an upgraded API it's a facade that lets you also configure the test and use it as a page object we'll see how it looks like the way we create the driver we use what I call a setup function which is basically under the hood just configure the test bed but it's a much easier API and it produces the factory that produces driver we'll see that as well so the third thing is it you probably also saw that when you delete a spec file before you delete it this is the actual function that runs the test and there we expect stuff we verified that stuff are true or not or will exist and okay this is the date function and you also have the before each function which runs before each test each each function so imagine we had like two before each function and an each function okay so the reason I'm showing you this is because I use a different syntax which basically does that okay I'm using a syntax called given when then okay which basically means given when our before each function you can translate them to before each functions so they run before each then function which is like the each function that's it okay that's the syntax I'm using I find it much more easy to read the test afterwards and it has lots of benefits we won't get into it I have a free course on high res that shows the benefits stuff like that go there okay and the last concept is spies if you ever written a test you probably heard about marks spies test doubles all that stuff basically it means when you were writing a component and want to isolate it and test just that we can fake its services and replace them with spies that we can interrogate afterwards like how much okay so these are spies and this isolated component okay I wrote like this is actually released i really suggest you think just mean otto spies it gives you a much easier api and its auto spying your classes one last thing is that we need to pay attention here in this talk that if we don't understand certain syntax it's okay the more important thing to focus on is the process is the decision-making process okay look at how like i'm thinking and stuff like that and get like extract the benefits out of that and not like trying to focus on oh I don't understand what this function does and stuff like that don't worry you'll see the video later but focus on the decision making process awesome now okay the last thing I want to talk about is the brain okay so you'll see why so the brain we have lots of parts two of them are the amygdala which is a very small part that is in charge of the our emotions and the reward system and all that stuff and basically if we had just that we will be running around slapping random people in the streets and falling in love with people and and getting angry and all that stuff but we have the neocortex that controls it I hope I don't mess up the definitions here but okay it basically controls the amygdala and don't let it that's the voice in your head don't know de don't do that don't say it code of conduct okay so so this is the new Cortez okay but it turns out that in recent years they discovered a new type of brain the tdd brain and since right next to the amygdala okay and it helps us when we write tests okay so why do I tell you all that whenever I speak with people about TDD they I always get like it's too hard I will never be able to do that it takes time I rather just write the code or write the test after the code all that stuff and I always say that I wish you could hear my thoughts while I'm coding to realize the benefits that I that I am having from TDD in my code so me and all shocked and if you know we developed a device that can read minds okay and instead of telling you about it let's show it okay so worried and welcome over to the stage okay okay no drama just put it okay okay okay we should get everyone he has a light bulb also let me let me tune it okay you can hear it let's see if I can connect it to the speaker here okay now let me tune it out [Music] testing testing testing hey can you hey TDD brain is it you yes hello yeah hi welcome MIT TDI brain everyone yeah give her a round of applause um you realize you just clap to a voice in your head anyway so TDD are you ready we're going to develop a feature I'm gonna have someone hi who's that you're what no I just wanted to DD so if you can go away okay wait okay sorry guys probably they're close together as I showed you so we're picking up on both of their voices so just be quiet okay don't bother us we need to develop this feature don't worry I'll be quiet okay thanks yes I'll be quiet just like this crowd of 1000 people sitting in front of you staring I'm I'm not scared sure you're not don't worry I won't tell anyone how sometimes you feel like an impostor and you want to quit your job move to New Zealand and praise hamsters for you but don't tell that sure sure Oh who's that oh that guy in the front row doctor yeah he's looking at you like hey let yourself fall in love [Music] way way way okay okay stop it we need to develop the feature okay we don't have time for this show we start the STD brain okay we're starting we're starting this okay great okay this is the feature okay just don't worry about him just ignore him whatever you say doesn't sound true okay so let's go over the feature once one more time great where the question and we had like the answer so just like four elements and we're gonna do a partial TDD of this component again because we don't know ty ku great now so you can see here I have the link and currently we don't have anything because I just generated the component and it's empty so let's switch to the code and what you can see here is that we have the template and the component and they're empty basically this is what we have here so what I like to do first is to start by the just a little template and start by adding that the elements to the to the page here okay so now we need to add the buttons and just wait wait wait remember you must write a failing test before you write any production okay I think I will go with the TDD brain this time okay so let's let's let's delete all that stuff and we'll move back to the spec file okay and now let's run the test first that's the first thing we need to do and here you can see I already have running tests right and good covers number the coverage is just there for like given giving us indication that we didn't miss anything okay awesome and now what I like to do is to first do like start by writing the setup function okay like I told you the sub function is in charge of creating the test driver so this is a very simple API basically gives it give it a configuration object which expects the component class and the component driver class so let's so first okay we'll go to the driver and this is basically you can see that it extends the component driver and we start by writing the driver on the under test and import the component driver so basically what we are doing is that we're creating the test driver and we're taking the compare component set of function and we'll use it to create the component drive so it it has a method called trade component driver and that's basically it and by the way if it's too small you can then guys if you sit in the back just come closer okay but it's easier that way okay also so so what we have here is the the component driver and basically I I don't really have an idea to continue I always get stuck in this moment when I did a ding okay I say what you're thinking about it why don't we check out Twitter to see if we got any new notifications that's a good idea okay so let's open Twitter oh okay this is sorry we'd go back to the code yeah we still have the the tester to do party pooper joy let's try and think what's the easiest thing you can start testing well basically I can just like test I don't know let's just test this fake question just that the element is there maybe or something like that okay so do that test that okay so let's let's delete that and go back to the spec file and just okay now we'll create like a sub describe we'll every time we want to to check like bindings and stuff we do it after the components gets initialized okay so this is the in it what's the unit for and now we need to think about what's the use case were actually testing so we'll do like even questions available then show the question text okay that's the easy thing I can think of just use the snippet to create the given when and then okay so like I told you is this is the before each function and they're given when and then you have like the each function which is the death basically okay so now what I like to do before I actually write the code is to create a few comments okay so this is just again for like the structure and I like to create the set of command the action basically the given is the setup the when is the action and then is the outcome okay so now let's think what we want to develop here so first of all in this setup what we want to do is to want to fake just have the fake question on the component instance okay this is how we set up the code so basically anything regarding the component instance we need to trigger change detection so let's right there okay once we set anything up on the component and the outcome basically we yeah we want to verify that the question text is in the template okay that's basically what were our words a fake question not the real question okay so it's important you know what's not fake okay okay stop okay we need to we need to do to continue with the okay later so so let's see okay choice how are you going to implement this game plan so first of all what we can do it just like use the driver okay so like I said I have like so I have the component instance everything in one interface so I can just create the fake variable and just give it a fake I like to use fake a lot as you can see and let's declare the variable and make sure we are resetting it okay that's important now we can you know what like I told you the given is just like the before each function okay so this can be replaced with that so we can just replace the before each function with a given function and now let's see we have this test but we don't have any question text right in the components so let me show you a nice trick the typescript gives us we can I could do the quick fix and declare the property automatically on the component so we don't need to skip between and and voila we got the property created automatically on the component let's go back to the spec file and now okay so now what we want to do is because we set it up on the component instance we want to trigger the change detection so we use again the same API the driver API to do that so it's all in one thing and now we want to expect that the component under test is we have some kind of a selector on it okay so like question element and we want its text content I want it to be equal to FFA question text right want this to be equal to that but we first need to do something about the question element right so what are we going to do we can if we want we can just create okay just use the driver on the test API and we can query the the component template okay and just like you know give it like a CSS selector to get the question element and to get the text content but there is a better way like I told you about the page object what we want to do is basically to do it on the test driver itself I showed you before that it was different it was a different file right so let's go to that file and create a getter function that just query for that question element and we'll use the query but we'll use a better query method which is great but test I did is I learned from Kent C Dodds article about test ID which is better way to select so to select elements so now we have we have we need to wonder how big bacon Darwin looks like in an evening dress okay just ignore that so we have that yeah we have their HTML amount and we need to create it on the template so let's just create it just an empty div and we'll give it a test ID which we can use to for the query afterwards let's run the test now okay and oh okay so now what we can see if we go to the spec let's let's go to the spec and we'll see okay so it expects we see that it expect that the test content which is currently empty to be equal to the fake question which is the fake Russian text so we need to somehow fill that up so let's go back to the template and just what we want to do what we want to do binding what a silly thing to say okay yeah so you want to bind so we have this question text so let's bind to that and now let's run the test okay and yeah just awesome shy really now do you know what you deserve for being that awesome that's right YouTube time okay so let's go aren't you forgetting something oh right yeah we need to add the button and yeah we need to add three buttons so let's go back to the spec file and first we'll delete the comments okay we don't need it because we wrote everything already and now we just need to add more button so you know we can just create use the same method that we use and just duplicate this line and just create another query right so we can create another query for the button but now we need the fake answer verbal so let's just create create those okay I guess let's let's see oh we need probably we need three and you know what I don't I don't I don't want to create too many variables in my test let's let's just use something else or something like that because you're lazy I know it's a good thing okay so let's create that the just a data structure and we'll call like let's create let's look for it Oh somebody already written a data structure for that yeah why are you so surprised you created that interface right okay so let's let's see this data structure we have a question and three answers and that that's basically what we need it so let's close that go back to the spec and just use it now we have like a simple data structure we can use instead of lots of fakes fake objects but now okay first let's delete this line and want to basically change our code right when to get rid of all these fake question text to refactor it to the new data structure okay don't you dare touch this code it's currently working and I don't want us to add more bugs that will cause us not to watch Game of Thrones Season seven like you promise me that we do once this lecture is over so don't touch anything that's okay that's the whole beauty of TDD because the tests are passing now you can refactor your code with ease as long as the tests are green you know you didn't break anything so you're good to go okay awesome so you know what let's refactor it okay so let's first delete it and now we see a bunch of errors okay so let's first start we need to change everything to the new variable so let's start with the first line let's just reset that okay as the best practice let's say change that and make it an object and now yeah just like to the question there and now yeah it complains about the answer missing so let's add that as well and it's at three of those right to satisfy the type screen basically and now we need to switch that so let's take the data structure we need the question so replace that will copy it let's copy that line right and okay let's run the test and check the result also okay we still have a green test you're going to watch Game of Thrones user deserve something sweet go and find a jar of Nutella and eat the whole thing yeah not so fast you two you still have the buttons to add all right right right right okay cool so let's let's add the bottoms okay I keep getting distracted okay so we'll add the bottles like before but now we have the fake answer text that we can compare it to or verify so let's create two more of these and now let's run basically run the test and oh a failure here you see that okay so it complains basically that we're missing these stuff what we need to do right we need to go and just duplicate the whole thing and just write the second one here and your email check your email I'm not listening okay so we created the three buttons and now we have we have done we need to go basically to the template now and create those three elements so let's create a button the first button give it the data taste test ID duplicate it and just change the name and let's see the test oh now they fail okay so they fail and basically they complain that oh we didn't bind them well as you can see so we need to add the bindings there so now let's try and bind to our data structure but now we don't see it right so that means that we need to go and edit to the here through the components and just will edit here and we can remove that let's go back to the template and add the question data and bind to the answers and move you forgot to call your wife that's okay I'm busy now let's just add the somebody's gonna get angry it's okay I know and okay we replace the question and now hey why would we add a skip button here that way people could skip to the next question okay first of all you're in the middle of fixing a different failing test and second if you want to add a new feature you need to write a test for that as well another test screw that I'll need to skip button anyway what a lousy idea where's my Nutella okay so you're done okay so let's run the test and okay we see that it's still it fails okay we can cannot find the question text right in the component so let's just yeah okay we need to change that to the question data and delete this and now let's run the test again and they are touching okay also that's cool [Music] the hell is that Wow this is your victory music that's not my victory music okay celebrate so early why just check out the website okay hell is that so it seems like our component is kind of messed up yeah we don't were not you done shy you ruined it no it's we didn't bind okay let's go back and I'll prove it to you prove it okay and just see that it works okay so let's just give it like the fake data from our test just so you'll see that we actually have a component and we didn't like do stuff for nothing okay and go back to the website let's save it yeah okay now you can see right you can see our component so it is working let's delete that okay and let's go to the spec file now we need to fetch the real data not the fake data so what do we need to do now we need to first we fetch the question okay from the server and then we get we need to random select a random question okay because it should be random and also we need to remove it from the selected question list okay and so there won't be any duplicates and probably we need to do more stuff like that basically it becomes a lot of stuff should I write like test how do I write this follow that yeah just drop this testing stuff and just code you know to code so just code forget about the testing well that is tempting but you can turn difficulty into an opportunity an opportunity to be lazy and to the latest decisions to a later time so whenever you encounter anything that does not directly relate to your component you can practice what I call lazy driven development I like lazy tell us more please imagine you've just met a genie and he grabs you one wish what would you wish for ooh to have John Papa bake me a pizza while wearing nothing but via scold I think he's talking about like technically what what what do we want to do okay right so what I want to do basically is to have like I don't know like service okay like I don't know or it's just a method get' random question or something like that that saves me all this trouble so let's just imagine you had the magic service with that method on it okay something like magic service get random questions something like that yes it will do all the steps you just wrote so you can delete those comments okay okay but okay that's that's magical you can rename it to something similar to the name of the component okay so probably like the component match squeeze service okay so we can have like the name the same name okay also what you really don't need to worry about the details right now you can just fake it for now oh okay so I don't need to create the test for it and stuff like that okay cool so it's just you spice like like we talked about before so we'll use a spy and I told you I created like the testing library just me not the spy so it gives me a cool API for zero balls that I can call just next weight and give it like the data to emit as as soon as someone subscribed to it so I can just edit here and can basically now delete this line we don't need it anymore because we have the spot so let's delete this line and now will generate the service the new service ok you can see it better now okay awesome so I told you if you want on the back okay so let's yeah will you see just an empty service but it doesn't matter because we we can just like use it as a fake but now we need to declare it or add it to the injector so we can use another property called services to stub a magical property that we can just add the class to it and this configure the injector and now all we need to do is to create a spy of this service okay so we can use again a special type I created called spy and it gives us the original methods but we type safety for the end and end property ok so now we can just call the same API again call the injector give give it the match quiz service and now we get the match respite instance that's how we define spice and that's it now we can use it but now we see an error okay and again the same trick wouldn't work here with the types way because it's spy but there's another trick I wanted to show you basically you can create a new instance on the fly and call the same method and just use this to auto-generate the method okay how cool is that okay so now let's yeah this is the generate method and it's auto-generated with throwing error so we'll remember to implement it later on okay so we can delete that and now what we want to do here is basically to get the guy in the front row okay not now okay also so this basically we need again this is details we need a decorator I created from the judgment no to spy and it expects us to return it analyzes the return value type and by daddy knows it knows to create the the helper methods so we just need that in order for it to work and now let's go back to the spec file and let's run the test okay to see if it works oh no it's okay it basically creates the okay it expects that this is undefined basically it says that it doesn't recognize the question verbal okay so let's go to the component and yeah we need to basically now inject the service so now that we have a failing test we can just inject the service and we need to call it subscribe method and and to expect data and to like assign it to our property and now let's run the test and okay we have the test awesome what someone said something about the subscription what we can yet what are you asking what am I going man can I do instead of it that's a stupid question that's a good question okay we can use a sing spy and stuff like that but for this feature I'm using a different method then again we'll see like the error handling and all that stuff later on Game of Thrones Game of Thrones you realize do have more stuff to do right I know I know we can again okay so yeah we need the subscription here and okay like you said and we can unsubscribe from it okay not only that no Game of Thrones but also cover just one use case of where the question is fetched successfully lousy piece off but what about the use case where you fetch the question and it fails okay so basically we can just write and I protest for that okay we can like cope just write another subgroup and given that fetching the question fell then we can expect an error okay just show an error so can use the same basically the same given when then and and do that but it takes too much time okay so let's I created let's stop here okay the development of the feature we can continue it more and more basically I have like the final version so let's get check out that and I just show you everything and now you can see that we have all basically all the tests for this component we have the disused case and you have the error use case and we have what happens when when there's no more questions and what happens when we click on the button and you know and the answer one is clicked and all that stuff let's move to the spec file and basically all of this I also wrote in in TDD here and you see all the all the stuff that are here basically are covered and if we look at the test you can see yeah you can see 32 tests are passing now because everything is Harvard okay so now let's go to the website and check the final feature to do this once we we have all the tests okay what do you want us to answer okay what which kind of movies do you like Bollywood okay let's do let's select Bollywood okay how do you like to get better yes okay also I like yes so I will choose yes okay thank you oh okay awesome so now let's wrap it up okay so how did he helps okay let's see how so basically what let's go over what we did okay we had with two thing called quality and confidence we needed to refactor right whether the Syndrome point whether to refactor so we could because the tests were green so it helps both the confidence and the code quality because we can make the code better what we what we also did is we use the yagnik principle you ain't gonna need it right with the skip button okay so we didn't add anything because we needed to write a test so the test made us stop and think which is a good thing and also we had modular modularity okay so we didn't want to continue writing the test so too many things so then it was a great opportunity to just you know extract it into a different service which has a single responsibility so that's also goes into the code quality so we gain that and we also saw like different use cases so often when I TDD I always like stop an S okay I tested the successful scenario what about the error what about the complete under observe what about those kind of scenarios so they give us most more coverage I will also saw that when we go over test we it's kind of like a documentation we can see all the use cases this component needs to do and stuff like that so this is for the cold quality for them productivity aspect and we actually write the test okay while doing TDD so there's no like it's the end of the Sprint and we don't have a lot of time left right and we just like do it on the next bridge okay we actually write a test while using TDD okay so yeah so again free workshop if you want to learn more deep dive this will be the first one out of the series of courses that my goal is to take anyone from zero knowledge to full TDD with all the api's and all that stuff to gain the confidence and the quality and one last tip I want to wanted to leave you with is when you start make sure you pick a body if you want to start with EDD often if you're already testing your code just write the test to simulate the bug have it fail and then fix the bug then you get like an easier way into TDD ok so just I want to leave you with that and with that thank you very much ok [Music] [Music]
Info
Channel: AngularConnect
Views: 22,920
Rating: 4.8712645 out of 5
Keywords: angular, angularconnect, angular conference, angularjs, javascript, shai reznik, Test driven development, TDD, Angular testing
Id: k9LWSh2xxjM
Channel Id: undefined
Length: 49min 27sec (2967 seconds)
Published: Fri Dec 14 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.