 Okay, so we'll start off by installing the Chai HTTP extension, importing it into our test code. So just as before we need to import Chai and then we need Chai HTTP until Chai to use this module and then import our server file. So this is very similar to before, it's just that we additionally include our HTTP dependency. And then we write a test. Tests look fairly similar to before, so we have this describe to set up a test suite and we have it to describe a single test. And then we use the same Chai expect as we had before, but now we use different methods that help us to make a request. So we have test suites and tests as we did before. Then we can use Chai HTTP to run a request. So you see here it says Chai.request, the URL.get, which path we want to address and then .end sends the request. And in this .end we wait for a response and then we do our search. So for example we can say the response should have status code 200, the get request should have been successful. Once requests are asynchronous, so they may take some time, we have to use this done function, otherwise your tests will always pass and you will not realize that something went wrong. So that's very important. Let's try this. As I said we'll go into this basic express application we had before, we have to get endpoints slash and slash test. Both of them return 200 and a text message in the first case and a JSON object in the second one and we'll just try to test it. Now of course there's not much logic here so there's not much to test, but it's a good starting point. So I'll just copy some code from my slides. We need the HTTP module. So we tell node to import that and then we tell chai to use it. Then we import our express application and we write a test. And as on the slides we can do chai.request, then we need the URL, then we say we want to do a get request and here's the path to slash and then we send it. And now in here we have to have a callback function and now I can test my response here. So I can say expect response to have status 200. And as I said before if I run this without done it will probably just pass so we have to include the done statement here to tell chai that only now the test is completed. Let's quickly check whether I've done everything that's in here. This looks reasonable and now we can run our test. So we can do slash node modules mocha bin mocha and then run the test and you see that it passes. And as I discussed in the other testing lectures when you have a passing test always check that you can actually fail it. So if I do for example 201 here the test should not pass and you see that it fails. So this means that the test is doing something. We can similarly check if I would forget the done statement here then our test would pass but if I now change something it would probably still pass. Now I get an error okay. But the test itself actually still passes so test passes and then I get an exception. So be careful with that you always try to actually break your tests so that you see that the testing framework works. Okay so this is what we can do. There are a number of other options we'll look into that later. Let's write a second test for our second endpoint. So the second endpoint also returns 200 so we could check for that. So now we go through to the other URL and have status and you see that it runs as well. And same as before if I change the status code to anything else it will fail. The same works with other methods so assume that I change this get request into a post request I return the same stuff then I can instead of get I can just write post here and unless I've forgotten something this is just as well wrong. It says get here because of the string up here so I would have to change that. So this works just as well. So this is sort of the first test we have done it's not very useful yet it just checks that 200 comes back but it's a good start. We actually test our endpoints. Now we can look into the different methods the different options we have. So as I've already shown you you can use all the different HTTP method works here so we can do a post request a delete request we can of course change the path so we could for example append an ID if we want to delete the specific item a specific object and we have other things we can do useful options are for example to set the header. So here we set the content type header to JSON we essentially tell the application we are going to send you a JSON object similarly and that might be useful for the fourth assignment we can set the authorization header and then include something there. So that just causes the HTTP request to include specific headers and then finally we can send an object so if we have a post request we might want to include something in the request body and if we do a dot send and we just put a regular JavaScript object in here then it will be sent to the server. And then as discussed the important thing here is that we actually call the done. We can check the status code we have already checked that. We can check the headers. We can check the body to have specific methods and this is just whatever comes back here is just a JavaScript object so we can test different things on that. Let's look a bit at the different options we have. Maybe we start with the actual headers and the different words. So let's assume that we change our endpoint and we say we have a variable. Our resources are let's say users and the endpoint is called users and in the beginning it's a new array and I just quickly write some kind of method that is not very good but it might work and just copy some stuff from my to-do application from before so let's use the body parser here and now we just write some kind of post request that actually does something. Let's not check for anything we just do this very naive we just expect the user to send everything that is useful so we just create a new user we add it to our array just ignore the nodes for now and we say next user ID is that and then we return 201. So now the response should actually be 201 and the JSON object we can also do one check maybe if there is no user name then we send back 400 just to have something some alternative to test. Now we can write a test for that so we just do post slash users so we want to do a request to users and we'll just leave it at that and see what happens and now the endpoint test fails because it says we got status code 400 back and that's because this is the case so the user name is not defined we haven't send anything to the server so we get 400 back that's actually an okay test but what we might want to do is add something so first of all we're actually sending JSON to the server we want to send the JSON object so we set the right header and the way you often see this is that these methods are just under each other so we tell the server here is a JSON object and we actually need to send something so that's the next thing we want to send an object now we can just test this for example we can say the username is Grisha and what else is there the age is 10 now we send this and then we expect if this works we should get 201 back the server should send us 201 created so let's try this this seems to be passing and we can add another test that tests the failure case so we can say if we for example skip the username then we should get 400 back we should get a client error and this also seems to work there's just something I have messed up on the server so I should actually fix my code here that's the return now I don't get any errors and as before please try whether you can make the test fails fail if you cannot then something is wrong in this case both of my test failed after I changed the expected value of the endpoint the status so this seems to be working okay now we have made requests this works but our checks here are not very useful yet we only check the response we only check the status but there are a whole lot of other things we might want to check and that's here these response assertions so we have done the status that's okay now we want to go into detail actually look at the response what has the server send us back we can check the header so here for example this check would check that the response is in text format this is something we can do for our first test so if you look at the first endpoint here here we just send text back and so we can go up here and actually say the status should be 200 and the header should contain text this will probably fail now yes because the header does not contain text plain but actually text html char set utf-8 one thing we can do is we can actually use regular expressions here we could do now I have to find the right one but I think here we go and this is something you'll have to google but this one exact essentially means that the content type header starts with text so it's some kind of text response we don't know exactly which one so let's see this now passes again that's great and now we can continue we can go into more details we can actually look at what it is the server has sent back check what's in the body for example or in our case here if it's such if it's just a text response then we can just check it with to have text and what are we expecting we expect hello world exclamation mark so I'll put that in here and I'll see it doesn't pass I'm not sure what happened now why this failed again maybe the text responses not correct we'll need to look this is what I want to check so the text response equals hello world and now it passes and if I change anything if I change the response to hello then the test would fail so it's actually checking that it's correct so that's what we can do here now we can go down to our to our post request and the first thing we can actually check is apart from the status is the content type so again we can search for is this jason and the right content type for jason is application slash jason that's a lot of work there is a short version for that in chi htp and is simply to be jason so then the library takes care of that the responses jason let's put that down here as well no down here we actually do we have a jason response yes we do so now both of these tests should still pass yes so now we have checked the status code we also have checked that the body is in the right format and now we can again go into what exactly the body is let's have a look at the slides so as already discussed this is a regular javascript object so you can check all sorts of things on that for example we could and this is exactly as before it's in the other tests we did so far we can just check certain properties of that to be i object see whether i remember this correctly yes so now we first check is the response in jason and then we check is the body actually an object if i would just send back a number this would not work we can check individual properties so here we actually expect that we get a user back and the user has a username h and id so we can check this to have property username so now we check that there is a username again let's run this still passes and now we can even check that the username equals exactly what i put in nothing else so now we check in summary we check is this a jason response if yes is the body an object does the body have property username equals to grisha now we can do the same with all the other properties so we can check the age 10 we said and we can check that id also exists we cannot check the value because the server generates the value we don't know what's coming back here and how this worked there is also a way to check how many elements are in object we'll see what i expect that one remember that one i think it is like this let's have a look no let's look at the documentation there is nothing in here so we'll just have a look at my slides because i probably have that here somewhere yes okay it's the objects.keys almost so now we check that there are only three properties in my object nothing else and it finally works so now if i would go to the server and i would actually add something else i would for example add property test five then this last part of the test will fail will tell me there are actually four elements in your object you only expect three so that's also something i can check if i want to check that the object has exactly these properties and nothing on top of that okay so that's essentially what i can do here let's quickly do the rest do this for the failure case uh so in the failure case i also get a jason object back but there is only the error message in there and nothing else so i expect that there is exactly one element in my object and it says no username defined so i can check my error exactly okay and this works so i've successfully tested my backend now let's quickly discuss the the rest of this what i haven't done is check the state of the server or the database so i have done my post request i have gotten the user back but i've never checked whether the server has actually saved it anyhow in the case what i just shown you it would have been in the server in the local variables if i would use a database check in the database um and this really depends on what kind of testing you do so there are two there there's something in between but essentially you distinguish white box testing where you check the entire system you check the internals you check whether the server has the right state um and there is black box testing where you test the entire backend just as a black box you only look at what's going in what's coming out you do not check what's going on inside and that's really what we have done here um so white box testing is you test what's going in you test what's coming out and you test whether the internal state is correct and black box testing is the same you just skip the last step so you just treat this as a system which you cannot look inside and that's exactly what we will do in assignment four for example so you have don't have to check what's going on inside the system you just have to check the response that's a very common testing approach okay so in summary um we have done endpoint testing to test individual HTTP requests in an API because those are not function calls so it's not regular unit testing but we actually want to test HTTP requests and responses um they are really concerned with checking that the right response is coming back when you send the request something I have not gone into but this is of course depending on the time I think mocha and chai have a default timeout of two seconds for example so if your HTTP request would take more than two seconds to be processed you would get a failed test so this can be tricky um it's something to think about if you do black box testing you only look at in an output request and response exactly like we did it right now if we wanted to do white box testing we would also have to check that the system is in the correct state so for example if we go into our code we would have to check that the array and the next user ID are set correctly afterwards this is something we didn't do here this is also something that is not that straightforward because you somehow need to have access to the system even if the variables are hidden from you or so okay so that was lecture 21 uh the next one 22 is now a summary lecture of the second part of the course so summarizing everything we have done there uh looking a bit at what is missing maybe and then there might be time for repetition and there we need your input so if you have anything we should repeat we should do additionally please comment on piazza thanks for listening