Tutorial: Mastering Test-Driven Development with Angular (first 33 minutes)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this course I will teach you the basics of test-driven development while building a simple angular web application my name is Eric murga leaf and I've used this driven development to professionally build front-end applications for the last five years after completing this course you will have confidence to use test-driven development when building your next angular application in this course you will build an app with a few simple features where for each feature you will write a test first make it pass by adding code and then refactor it to meet these standards I designed this course for developers who want to start using test-driven development and all of its benefits but struggle to write that very first failing test enroll for this course now and write this first test within minutes in this video we jumpstart our project we start with installing angular CLI then use angular CLI to create a new application then for that application create two components header and Holmes now let's open the project in vs code and update the main HTML template to use those two new components now let's check it out in the browser there they are and the last step is to install UI kit CSS framework we'll use NPM for that along with the UI kit we also installed jQuery because it's a dependency then we head to angular JSON file and add jQuery in UI kit JavaScript libraries to the application scripts then go to Styles less file and import the standard UI kid theme save make sure the app reloads successfully and we're done in this section you will build this application header using test-driven development in real scenario the design for this header can be a mock-up from a designer or simple wireframe here in your notebook or even an image in your head the most important thing here is that test-driven development forces you to think about figuring out the most essential functionality first and then the looks in appearance second so let's get started in this video we are going to build the top part of the header which is the navbar which contains logo search and menu so let's add the logo first using test-driven development where we add the tests first then make it pass before we do that let's start our test runner and at the same time start the webserver for the application here we see the default tests passing and then in another tab we'll load our application and remember for now it's nothing but just two fresh components they have nothing but these strings so we are going to turn this header into a nav bar open vs code navigate to the test file and create a first test that checks that the logo is displayed we'll call it should show logo add a little bit of spacing around and then use the fixture object and its native element to query the template to check that the logo is present on the page and instead of using CSS classes for querying elements we're going to use a specialized data test attribute now let's check our tests runner and it is failing because the logo is not present yet so let's add the logo in vs code navigate to the template and make this test pass in the simplest fashion possible by simply declaring the element with the data test attribute equals logo now check the test runner and we just made our very first test pass now let's repeat this with search and the menu back to the test file add a couple more tests should show search and should show menu check the test runner see our failures go back to the template and add the missing elements check the test runner again nc passing tests and at this point we completed the most essential functionality that our navbar supposed to have which at this point is just displaying logo search and menu now we move on to the refactoring step of TDD which in our case is simply styling the looks according to the design spec which is remember the image where it looks like this but what we've built in our app we see is just these three elements so now we need to turn these into what they supposed to look like and since this course is not about styling but about test-driven development I'm going to skip the step where I turn that into a pretty thing and just show you the end result where I add all the necessary markup and UI kit classes to make the navbar look like the design spec but the most important thing to note here is that logo search and menu still maintain their data test attributes that indicate that these elements are still present on the page as you see here here and here so if we check our test runner we'll see that all three tests are still passing and if we check the app we see that it now has properly styled logo search and menu next you will build the bottom part of nav bar using the exact same approach in this video you will build the bottom portion of the header which is the list of filter buttons and remember what we have in our application already is the nav bar with logo search and menu so we just need to add the bottom part we start with the tests navigate to the test file and add a test for the filter buttons so there are six buttons let's add assertions for all of them first is home type then dates then guests then price rooms and amenities check the test runner see the failure and then go to the template and add those filter buttons again it's home type dates guests price rooms and amenities check the test runner all tests are passing and their fulfills the main function of the header displaying the navbar and the filter buttons but again if we look at them now they don't look like the design specification and to fix that is the third step in the test-driven development which is refactoring which is in our case making it look pretty so again I skip the styling part here and just paste what I already have that achieves the look of the design spec but at the same time it maintains the data test attributes that keep the tests passing so let's double check the test runner again it's passing and the looks are now are according to the design as you just experienced TDD can be very simple if you choose to use it in this way it can be a simple lightweight guide to building the most essential functionality in your application where it helps you figure out how to make your app useful first and then worry about the appearance in the next section we will take it up a notch and use TDD to help us build something more complicated than a simple header in this section we'll build the part of the application that shows a list of homes of course we'll use tests to guide our development first we'll build a rudimentary list of homes with stubbed data and no styling then we'll add details to each individual home such as home title location and image after we're done with the presentational part of the Homes list we'll add and mock a data service that will be used for fetching homes from a mock back end then we'll update the service to make real HTTP calls and lastly we'll style the homes list to look like the design specification but before we dive into this section I would like to ask you to consider giving a review to this course it doesn't have to be something long or complex the reason I'm asking for a review is because it will help other students decide if this course is right for them and it will help me improve this course in whatever the way you think it can be improved thank you in advance and let's get started in this video we'll write our first test for the homes component that will verify that the component displays a few homes then we'll make that test pass in the simplest quickest fashion possible so let's jump into the test file for homes component and repurpose this default test to testing that the component shows a few homes again we'll use the fixture object and its native elements to query elements that we expect the component to render but in this case we use query selector all method which is in comparison to query selector returns an array of all elements that it finds instead of just the first element that it finds we'll be looking for the elements that have data test equals home attribute and we will expect that the length of this array will be equal to 3 meaning that we expect three elements to be rendered by the component that have data test home attribute now let's see our test failing there it is it expects three homes but zero found let's open the component template to fix that and the simplest way to pass it is to hard-code three elements with data test equals home attribute check the test again and it's passing but of course that's not how real-world applications work in the real app the list of homes will come from the API back-end as a result of an HTTP call so the component would make that HTTP call and typically it would save the result into a property so let's go to the controller file of the component and declare that property will call it homes the dollar sign indicates that it will contain an observable then usually in ng on init function we use some kind of service to have it make that HTTP call for us and then we grab the result and save it into the homes property but since we don't have this service yet we can't use it so let's comment it out and instead hard-code the result of calling that service into the homes variable using of function from rxjs which returns an observable now it is the import on top of the file so here we add an array and which you would typically get from the backend is an array of objects where each object is an individual home and let's say each home will have a title an image URL and the physical location let's say this will return three different homes one in New York one in Boston and one in Chicago once we have data in our homes property we can go back to the template and update it to loop through that property and display each individual home from the array you use ng for structural directive from angular core for that where it will be led home of homes property any need to subscribe to it because it's an observable and now this should produce three elements with data test home and keep our tests passing let's check the test and there is passing and when we load our app in a browser we see this list of homes here which is just for now next we'll update inside of this ng for loop to display details but each individual home such as title location and image since we have the code for listing individual homes in this video we'll add a test for verifying that the component shows title image and location for each individual home and then we'll make that test pass so open homes component test file and add the test for showing home info and the first thing that we're going to do here is to grab the very first home that the component renders using query selector method and then we query this home to try to find its title and its inner text property to verify that it equals to home 1 which is according to our stubbed data from the homes component controller now the test should fail because there is no home title yet so Open Homes component template file and and the element that will show the home title make sure to add data test equals title attribute so that our tests can find it then we can see that our test is passing now let's take care of the part of displaying the location in image for each individual home so open homes component test file and add a couple of assertions for location and image note that for image we're just verifying that the element is present rather than trying to look inside of it this is just to make things simpler now the test is expectedly failing so let's go to the homes component template file and add the elements for showing location and the image make sure they have our data test attributes and that makes our tests pass and if we load our application it looks like this and never mind that images are broken for now we'll fix it later in the next video we'll fix the stub data in the homes component controller so that it properly comes from a service now we have all the essential functionality of the homes component built out it displays the list of homes with details about each home so now in this video we'll remove the hard-coded list of homes from the component controller and replace it with a call to a data service that will fetch the list of homes from the API using HTTP Col behind the scenes so from the perspective of the homes components it will have no knowledge of how the list of homes is obtained it will simply rely on the data service to do so and that will make it easier to properly mock the list of homes in the homes component tests so the first thing we'll do is comment out the hard-coded list of homes and uncomment the line that we added to imitate the call to the data service to get the list of homes and obviously this data service doesn't exist yet so let's quickly make sure that our tests are properly failing and they do and to fix that let's open a terminal window and generate the data service we'll use angular CLI for that and after its generated we open homes component controller and inject the newly created data service and now it highlights that we are trying to call a method on this service that doesn't exist so let's go ahead and add that for now let's have it returned unobservable with an empty array and added to do that later we'll turn this into a real HTTP call to get homes now the call to get homes is not highlighted red anymore so it's a good time to go and check our tests and now it fails not because of some error but because by default your home's returns an empty array and therefore there are no homes are displayed during the test run so the next thing we need to do is to mark the gear homes method to enter in our marked data to do so we'll install a Jasmine es6 spice utility using NPM and then go into the test file of the Holmes component import the spy on class utility from jasmine es6 spies and then update the providers property of the test configuration to provide a marked version of the data service instead of the real one this will allow us to mock its methods but before we can do that let's add a variable that we will use to store the reference to the mock service and then we can use it in our first test to grab the reference to the data service and the beauty of the spy on class utility is that you can mock methods doing data service get homes and return value and then will have it returned our mock data from the controller you and one little caveat here is that when you mocking things you need to move the detect changes statement to run after your mocking statements and then our expect statement stays as is and it's a good time to check our tests but first we need to restart our test runner because we just installed a new testing utility and once that's reloaded we see that our test for verifying that there are three homes or displayed is now passing but our test for verifying the home info such as style location and image is failing and that's because we didn't mock the data for the second test so let's open the test file again and fix it by extracting the marking code into it before each statement so it runs before each test and that fixes all tests so even though the tests are passing now if we load our app in the browser we see that it doesn't show any homes and that's because the data service gave Holmes method temporarily returns an empty array next we'll update the service to make a real HTTP call to fetch the list of Holmes now it's time to update our data service to make a real HTTP call to fetch the list of homes using HTTP client and guess what we will do it in a test driven development fashion where we add the tests first and then build the service to make it pass before we dive into the tests we need to update app module file to import HTTP client module from angular core now open the data service test file and repurpose this default test to make sure that the data service properly works to do the single most important thing it is designed to do which is return the list of homes and sometimes with tests like these I make a few notes using comments on what I think I need to accomplish to make this test work so in this case we'll need to do a few things first we'll need to spy on and mock the HTTP client then we'll need to use our service to try to get the list of homes and then we'll need to verify that the service returned or mocked data as it's supposed to and then we'll need to verify that the service called the correct HTTP endpoint so let's go ahead and import HTTP client testing module so we can properly mark things out we also declare a variable that we will use for referencing our mocked httpclient now let's grab that reference from the test bed and then create a variable that will contain our familiar array of mocked homes and then we'll spy on httpclient kept method and have it returned unobservable of our array of homes then the next step is to grab the reference to our actual service that we're testing let's declare that reference as well and then create a spy that we will use for assertions and then subscribe to the data service get Holmes method with our spy and then we expect our spy to have been cold with our mocked data and this is our test so let's go ahead and check our test runner and see how it expectedly fails now let's open the data service an update get Holmes method to actually use HTTP client to try to fetch the list of Holmes for now we'll have it calling fubar end point because it doesn't really matter if we're trying to make our current test pass our current test doesn't assert against which end point it is calling so now artist is passing now let's head to the test file and take care of the fact that the service should be calling the proper end point and in our case our back end will be a simple Holmes JSON file in the assets folder now let's see how the test fails because we're not calling the expected end point yet so let's make it past by updating it Holmes method to call the correct end point and now the test passes however if we try to load our application in the browser it still will not display the list of homes and that's because our assets folder does not yet have the homes JSON file so let's go ahead and create one and we will use our familiar array of mocked homes in a JSON format and then if we load our application in the browser we see that it displays our homes the only thing we need to fix here is the image that's missing from the assets file so let's add that and then when we check the application we see that it loads it successfully so now we have hundred-percent functionality in and the next step is to style this list according to the design spec now we have everything working as expected and it's time to make the home list look according to the design specification and after updating the homes component we'll use our existing tests to make sure that we didn't break any existing functionality so remember at the moment this is what our home list looks like and this is what we need it to be so let's open Holmes component template and here I paste already prepared piece of code that uses all the fancy UI kit classes to style the home list according to the design specification it puts the entire list into a container so that it adds some nice margin and padding to it and then it adds page title which is Holmes and then it puts the list of homes into a grid so that it becomes responsive for different screen sizes and then it puts each individual home into a card again for some borders and pairings and margins and then it puts the image into a media top element of the card and then it puts the title and location into a card body and then at the same time it maintains the data test attributes for image title and location to allow our existing tests to still find these elements and pass now if we reload our app we see that it looks like as it's supposed to and when we check the test runner we see that all the tests are still passing in this section you've learned how test-driven development can help you with building the homes list feature of the application with every part of the homes list feature you've started with a simple quick test made it pass in the quickest way possible then refactor the code according to standards you've started with building a simple list of homes then added title location and image to it and then updated the code and tests to work with a data service for fetching the list of homes from the back end then you style the homes list according to the design specification in this section we're going to learn how to use test-driven development methodology to build more complex functionality compared to the previous section so what we're going to do here is to add the ability to book each one of those individual homes so we'll start by adding a book button to every one of those and when you would click on that button what you're going to see is something that I sketched out on a piece of paper and it will be a dialog where it will display the title of the home and it will show what's the cost of the home per night and it will provide you fields to enter check-in date and check-out date and based on that these dates and the price per night it will calculate the total cost of the booking and then you would click on the big book button it will submit a request to the fake back end and then when the back hand returns a response the dialog will close and it will show you a success message and you'll get back to this list of homes all right let's get to it before we get started I'd like to mention that every lecture in this section includes a link to github that looks like this it takes you to the compare page where it compares one branch with another branch and when you open such page what it shows you is the exact changes in the codebase I introduced with each lecture so for example this page shows all the changes that I made in the lecture where I am adding a book button to the home listing so here you could see that I added this button to the homes component and I added the tests here too and then all the related changes that I had to introduce I think this is very helpful when you are following along with the changes in the video so I suggest you would open each one of those links with every lecture that you follow and it should help you to understand what's going on in the codebase and I hope you find it very helpful all right let's get started
Info
Channel: Irek Mirgaleev
Views: 6,136
Rating: 4.8734179 out of 5
Keywords: angular, test-driven development
Id: JOYNHkRN_YY
Channel Id: undefined
Length: 33min 31sec (2011 seconds)
Published: Tue Sep 03 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.