 Welcome to this ninth lecture in the first part, which is on client side testing and debugging And overall we talk about quality assurance. So it's not only testing and debugging. It could also be other techniques now The ones who have taken the software engineering course, so that's that should be the software engineering students They will already know the first part of this because I'll essentially repeat a Bit of the theory around testing levels what kind of testing types there are and so on and most of this I cover as well in the software engineering course, so it's a bit of a repetition, but that's fine This is to give a background on how does all of this actually work together What kind of testing can and should you do and then we dive into the later parts of this module We dive into the practical stuff mainly focusing on JavaScript We look at unit testing in detail, so that's the biggest part we'll do in this course We look a bit of debugging And then I'll show a bit of system acceptance test And maybe linting if there's time if not we do that in the later testing lectures The learning outcomes are again. It still has to do with developing client side applications Additionally, there's a bit of web application testing you should be able to discuss that and maybe contrast the different techniques should be able to debug basic web applications and Then it goes into the larger Learning outcomes saying that you should be able to analyze source code for errors improve existing web application code and so on Now testing is not really covered in the course book, so it's not in the literature references The first reference is just on the testing level, so this first part of the lecture The second one is done a bit on the JavaScript debugging. How do you debug? Simulator third one is how do you do that in Google Chrome? And four to eight are just links to tools, so If you're interested in using them you can do that But there's of course a bit of documentation for example in Mocha and Chai which other tools we use for unit testing So that could be interesting Now if I explain testing I first have to go into how we develop software And I'll just do that very quickly But essentially what we used to do in the well for the last 40 50 years is the so-called waterfall process where you would start Figuring out what the requirements are for your product. What is it? You need to develop? What is it the customer needs? Then you would build an architecture. It's just sort of the high-level picture of the whole thing Then you would go into coding and that's really what you have all been Doing most of the time so far in your university career and Then you would do the same with testing Going back up basically you would test the code you have just written You would test it on a larger level when you put multiple pieces together and finally You would test the entire system Nowadays, there's a lot of talk about agile development. So instead of doing this old-fashioned V model here or the waterfall we do everything in small iterations So you only code and you test for two weeks and then you should have something that is Functional now The idea is a bit that you don't need that much requirements in architecture The reality is a bit different. This is sort of a fairy tale. You need all of these things But they're not really sequential phases. So it's not like you sit down for two months and write requirements But you just do that quicker And the same goes for the testing so just Because you don't have a requirements phase doesn't mean that you don't do system testing It just means that you do it more regularly on a two week basis and the reason For testing at different levels is basically the costs of fixing an error And this is just a it's just a sketch. So those numbers are not appropriate But you usually say that if you find it a bug in your development. So If you while you're coding you find a problem, it's reasonably easy to fix it If you have already put your your software together into multiple modules pieces that kind of work Which other is much more expensive and that continues in the worst case you find a bug when the product is deployed It's running and then it's much much more expensive So the the main message here is the later you find your bugs the worse it is And that's just a cost but of course this also has to do with reputation So if you find the bug during deployment, it means that maybe your customer or your client your end user Has seen it already or has is actually the person that has found it that might not be good for you So ideally to test early is good because then you might be able to find bugs during development Now we can do testing at very different levels as I already discussed you can do it at unit integration system level and That basically has to do with how much how many pieces work together So we have unit testing and that's what we'll do mainly in this course But you test a single unit of your program and that usually means functions So you have 20 functions and for each of them you write individual tests And a test in software testing means you call the function with a certain input Parameter and then you define what should come back depending on what you Put in so and you can do that in essentially two different ways You can do the success case you you put something in and you specify what should come back if you have used the function properly And you have so-called error cases you put something into the function that is maybe not valid For example, the function wants to have a number and you put a string in instead So then the function if you have written it properly should not crash the program But it should maybe return an error message That's an error case So these are the things we typically do And as you already see there are multiple cases. So if you test one function, you can have a lot of different test cases The cool thing for unit testing and that's why it's so incredibly Popular is it's very easy to automate. So there are lots of tools that you write you write the tests in in code In our case, I will be JavaScript And then you can automatically run them and the great thing is you can do that all the time whenever you check in something new Into your version control system, for example, you can run these And just so you remember this is exactly what we would like to have because it means during development We already get feedback on what works and what doesn't so it might be much much easier than finding those things later So we'll focus a lot of unit testing and Not so much on the other things. I'll just show tools for that The next step is called integration testing. It's basically when you put several things together for example, if you remember the JavaScript lectures, I had Some function that would call another function and that would call another function That would be an integration test if I test all of these things together Or if I have multiple JavaScript libraries that somehow interact with each other So these are typically more complex scenarios already. It's not just a function. It's something It's more of a use case something that happens And then the last step is system testing. That's the entire system everything you need together And that's really use cases from the user perspective So for example, you might want to test the login in Gmail So you test the entire procedure from opening the website entering your name entering your password pressing login And checking whether this works properly. So the test cases in system testing should cover something and somehow a real-life scenario This is really difficult because this includes the entire system. So it's the user interface like the HTML code For example, it's the JavaScript client side code. It's the database. It's the back-end code It might also be the hardware is your server working correctly and so on So it's a lot of different pieces that can break And if you want to automate this, it's actually not that easy And then finally we have something that's called acceptance testing That's very similar to system testing we test the entire system, but it's sort of from a customer perspective So in the past what you did with acceptance testing where you went through the requirements that you had written down and you checked each of them But it basically has to do with a functionality that the end user would really see in the end. In system testing you might test stuff that is not really Concerned with kind of visible functionality sort of things in the back This is even harder to automate for the same reasons as system testing But additionally also you somehow have to include the customer So you need to and the customer is usually on the programmer. So they might not be able to write your acceptance test cases so basically The higher we go up on the hierarchy the more of the system we test and the harder it gets to automate down here We have small tests for small pieces of our code and they're very easy to automate. So we will focus a lot on this Then there are other ways of looking at this so far I've kind of looked at the levels to the abstraction of our system You can also look at testing types. So you can test UI you can test user experience You can do so-called functional testing testing your functional code You can test the performance how quick is the system and so on. So these are kind of different concerns different quality attributes that you might want to test And of course if you for example do performance testing what you do is you execute some code and you measure How long does it take until I get an answer? For example, how long does the answer to my HTTP request take? and finally There is also a question about how do we actually test we can automate testing automate testing We have manual testing very common still We have something that's called exploratory testing where you don't have a refined test case, but you basically explore Like a user clicking around the website, for example, we have one thing. It's very important. That's regression testing That basically means that whenever you find the bug in your system You write a test that would reproduce the bug something that would cause it And then you fix it. So for example, let's say I have a website I have to enter a username I have to press login and I figure out at some point if I leave the user name field empty And I press the button then the system crashes So then I would write a test that would exactly reproduce this behavior. I would Keep the input field empty press the button and then have a check that the system is still running So basically you then have a test that if this bug ever happens again We will automatically find it and the reason we do this is that quite often bugs disappear You fix them and then later they come back So if you already have a test that checks automatically for these bugs You will directly figure out when it's coming back basically And there are other things mutation testing fast testing. There are more advanced and we don't go much into that I will most of these techniques. I will not describe really and it's also not very precise You can you can classify this in a much better way, but the important thing is there are so many different testing areas and This is really a lot to learn And talking about that if you're a good tester, that's a really really good thing on your CV. So Usually that means you're also a very good programmer because you understand how to test the system in a good way If you want to know more about this there's an entire course on software testing So I don't have to cover that here One more thing that will cover is different practices What you did in the old times was You wrote your system you wrote your code and then you did all the testing Either you do it manually by just spending three weeks and actually clicking around for example in your website or a bit more modern you used to write automated testing But that was done after the actual coding and a reaction to that was to say we do test-driven development instead We write the tests before we write the code And a good thing about that is the first of all you make sure that you actually do write your tests It's not like okay now we're out of time. So we just skip it It also forces you to think about the problem really Because one of the issues is when you write your tests after your code You often just write tests for exactly the Function that you have written not how it should be tested But that's maybe a bit advanced. We'll do more of that in the software engineering course And there are two more things that I want to mention because they often come up in the web context You might run across them one is called BDD behavior-driven development That's an evolution of test-driven development. So you write your test before you write the code But additionally the guys in BDD use a specific format for the tests So they basically have this given when then format. That's all I'll mention about it But the testing tool we use has a similar structure. So it says okay given that I call a function when I get the return value then something should be true and you'll see more of this and Similar there is something is called acceptance test-driven development is the same idea as test-driven development But it's for acceptance testing. So the idea is the customer actually writes an acceptance test that is automated And then you start writing the actual code and then once the test passes, you know that the acceptance criterias are Passed the customers happy basically now I've thrown all of these words at you And you'll figure out when you start working that there is quite a quite a variety in industry how this is used So unit testing that the lowest level of it is standard and that's why we do it in this course We also you will encounter this in different courses. We will do it in software engineering again You will do it if you take the testing course Just because this is not very easy you have to learn this But it's also standard. So when you go to industry people expect that you know what unit testing is and how to do it It's very common regression testing is also very common often in combination So you basically when you find the bug you write an automated unit test that reproduces it All the rest I've shown you varies a lot Some companies really don't do much more than some basic unit testing I've seen companies that do everything that you can do essentially The big companies of course are very good at this Facebook is known to be very good at testing automated testing But it also depends on what kind of company do you have what kind of products do they work with? Is it a Information system that no one cares about or is it a is I don't know an airplane that might crash. So of course this happens There are different Dimensions to this and again, this is something that becomes much more important in the software engineering course for now We'll just skip that now practically. What does this mean for our course? We have so far covered three things HTML CSS and JavaScript And the question is how do we test this? We would like to test different things, but we'll essentially focus on JavaScript for multiple reasons We'll also do a little bit of debugging because that's quite useful What important thing is and I learned that much more last year in this course testing is really difficult for a lot of people to understand Because it has a slightly different mindset than regular programming And we'll come back to that but in testing you essentially always try to write a test case is very concrete It tests one specific thing So that when you fail when the test fails, you know exactly what went wrong Programming in general is a bit different because you often try to solve a problem very general So it should work for all kinds of inputs, for example So testing is slightly different You'll see that and in this course, I'll just show you a selection of techniques I'll just show two tools or three tools actually for system and acceptance testing Just so you've seen them that whatever you have the need to use something like that. You might remember them We'll do unit testing or integration testing with Mocha and Chai there. We actually do a bit of coding And I'm not saying anywhere that this is anyhow the best selection But generally you will see that that the principles are all the same So whether I replace Mocha and Chai these two frameworks with something else really doesn't matter It's always the same principle, especially unit testing Even if you change programming language, usually it's exactly the same kind of thinking So that's not much tricky Stuff there now. What do we test in HTML? What we have done so far is we have validated so we have checked is the code conformant to the HTML standard and this is not really testing It's just making sure that you follow conventions so that you prevent errors later on As I said in the very beginning if your HTML is faulty it might lead to errors for example when you do scripting What else can you do? Well, you cannot actually do that much you can You can check that certain things exist so you can have tools that say okay when I load the page the image should be in the upper left corner You can check that HTML functionality works like the links when you click on it. It actually gets you somewhere But really it mainly makes sense in combination with CSS and JavaScript So we're talking about system testing when you test your entire web application Of course, there is some HTML involved, but you do not typically test the HTML code separately For CSS, that's exactly the same thing So you can somehow check that things look right that the responsive design works. So you resize That's actually a bit of functional testing. You can do those things But again, we generally want to do system testing. We want to combine the things with with functionality with JavaScript So that's why I don't show much on this Finally, we have JavaScript and here you can really do everything You can do unit tests test single functions in your JavaScript code. You can put things together You can test multiple functions that work together And of course you can do system testing and also include other things and this is also great because it's really Automatable so you can have all of this automated That you do not need to do the testing manually So what I've shown you in this first part is just a lot of options on how to do testing when to do testing What to include and the message is basically you can never test enough Most companies will tell you yes, we would like to do more testing. We just don't have more time So that's often a problem, but there is never a point in time where you say, okay, we have tested enough It's really hard to do that In the next part, we'll start pretty basic. We'll just do debugging Debugging means as the name suggests we find the buggy and remove it and that assumes that we have actually found the bug We know something doesn't work, but we don't know exactly why or where and we try to find it So that's what we do debugging and then we go into the other accepted the other testing techniques