 So basically today the talk we will be giving is on testing like a pro so we'll be running through basically how to test basically your software and telling you what are the different things that you should adopt or the best practices you should adopt when you're doing testing. So let's start. So before starting we would like to ask you if you know about those very useful commands. Who knows about that command? Nice. And who is using that command? Well as a matter of fact these are the commands that you should try to forget. Why? Because skipping tests is usually not a good practice unless you have very good reason for doing so. I mean it could be something like you do not want to be part of your build. I mean there's one reason but most of the time you shouldn't be thinking about this at all. So try to get it out of your vocabulary. But I don't really really need to test. I like to test my current in production. You like to test your code in production? Yeah. Well I mean this is possible only if you are Chuck Norris but let me remind you guys most of you are not Chuck Norris. So why is testing important? Because testing allows you to when the bugs get propagated to production, usually it's much costlier than bugs being found in development or even before development stage. Just for example for Toyota they have an incident where they had this problem with unintended acceleration about a couple of years ago. So it was about 2009. So they found that this was actually due to a software bug and this caused a lot of cars being recalled and that eventually caused them about $3 billion. And this is the cost versus if you have found it in development there will definitely be much lower. So this chart is basically a highlight of what actually are the costs as you go towards production and maintenance. So this is a sample of this illustration basically is talking about how you should build your test cases. So the foundation of your test should always follow this kind of testing pyramid. You should start with the unit test first because those are the easiest tests you can do. So this test usually targets methods or classes. And these are the tests that you will be I mean you will want to write more to cover all the different various cases that you have. The next kind of test that we're talking about is integration test. So integration test basically is like testing on a component level. So you have basically different multiple classes coming together and you would like to test a group of functionality. So this test usually is slightly slower than unit test because you need to set up some dependencies but they're still significantly faster than the next step which is the functional test. So the functional tests are basically what some people will call acceptance although there's a fine line between acceptance or functional test. So basically functional tests are tests that as an end user I will be doing. Some people would think of it as a manual test but in an automated fashion. So these tests are usually the slowest one that you probably... I mean when you run it you probably take the longest time. So let us start with unit testing. Oh come on. You feel like you're going to talk about TDD right? I see you guys don't want to talk about TDD. Who wants to talk about TDD? So it's... So have you guys... I'll show a hand. Who has heard of TDD? So I think it's like... TDD is not applicable, too difficult, no case to TDD. But who has actually tried TDD? I mean that's quite a number of you guys. So that's good. Basically TDD is a methodology that's actually pioneered by Kenbeck. So it actually allows you to simplify the design of your software. And by putting tests first you actually drive to your development work. So probably you can do a short demo on TDD. If you don't like TDD, let's do a demo of TDD. Yeah, let's go. So let us select what kind of TDD should we do because I don't see any test case that fulfills TDD. Okay, so basically we're using Spring Pack Clinic as a sample. But we're going to do a simple one. So basically we're using a function that most of you guys should know about. It's called A2A2I, basically Alpha Numeric to Integer. So you're going to start by coming up with some test cases to drive this development. So let's say you have a simple method that converts Alpha Numeric to Integer. So what should you do first? So let's think about what we want to do for this test case. Probably you should start a simple test. Maybe something like... Can you increase the font? Oh, it's too small? Okay, let me switch to presentation mode. Okay, this is good. So let's start with a simple test. Maybe you should call it converting a single character. Test convert single digit chart to Int. Okay? And I'm using this library to assert J. So maybe we know something like this. Okay, let's start with a simple one. So as you can see, right, when you run your test, basically it doesn't even compile. So it's read. So that's the point of it. The point is to convert this read to green. So how do you want to change it so that it passes? Okay, so my job is to write the implementation, right? Yeah? Okay, so go ahead. Can you take me to the implementation mode? Okay, there you go. So basically I will write the implementation to make the test pass, and then we'll see. So what was the name of the message? Passed it. Okay, like this. And then you gave me a string. So basically, as you can see, the test actually drives what was the name that you gave for your implementation. All right, so return one. So the test will be passing? Yeah, I mean this is the shortest way you can get it to pass, which is actually the point of it. Of course, when you do something like that, it passes. This is the shortest route. Give it a round of applause. So the guy that's writing the test right now will think about, okay, so you got it to pass, babe. So I'm going to give you something more difficult than this, right? So let's try something like... Yeah, I'll give you a couple of test cases. Maybe, yeah. Okay, let's try the couple. So we expect this to fail. More complicated? Yeah. Can you switch back to the implementation mode? Okay, all right. So I think I have to make my function work somehow. Okay, so how about this? So now you have to start scratching your head. How about this? So you can start running the test by control shift. What is that? Okay, so it's passing. All right. Okay, so well done. So you got a single character working. What's next? So that's where you have to think again. So after you have passed your single character, right, what's next? Probably you have to think about, maybe he has to get the implementation mode on more than one character, right? Okay, all right. So let's do something like that. So as you see, it's right in my chest, right? I'm trying to get it to be more descriptive because ultimately this is like a documentation of what are your requirements. So the more descriptive your test is, the more easier it is for other people to understand your code. Let's start with a simple one. Okay, so now I have to make some kind of loop to loop on each number. And I think I will store the results in some variable. So let's start like this. And then take a mistake. So you guys can keep it in 5 years, yeah? You can notice all this. And now I think I have to multiply my number by 10 on each loop and to add the current number. So as you are rewriting this, right, you're thinking about how you're going to refactor this code and make it pass the previous test as well. So there's also some regression testing involved because the previous test actually covers the case for single digit. The result, right? Return result, right? Yeah, result. So let's try. So let's see whether that passes. So great. So as you can see, both the regression test passed as well as the current test. So this is basically the idea of TDD. So as you can see, it's not as difficult as you guys think it is. I mean, it's actually applicable for small methods or things that are not really big, but you can apply it for single methods in the process. So that's... You want to go on? Yeah, to summarize what we just saw, applying TDD will help you thinking about your design because if you want to go to the full method at once, maybe you will have to see more. But if you start with a small test and you introduce it step by step, the implementation will be more very easier to do. So that's the first part about why TDD is very nice. So one of the good things with TDD is that you don't have to write a lot of documentation because by reading the unit test, you understand how the lesson works. So it helps with the documentation. And this documentation is always real and always working because if you write it on a Word document, you will get outdated. But this documentation is tied up to the code so it always works. So you know that it's actually doing the correct thing. If you want to have a good TDD pattern, you just have to follow the steps. So you write an implementation, it fares and you have to make it work and you improve the test. So this is a red, green, red, green pattern. So you just have to follow this. So if you follow this pattern, slowly your code will start to evolve. As you add in more tests which revolve around your requirements, your implementation will start to evolve as well. So next time, your boss asks you to prepare a test plan for him. So which TDD is generally the test plan? The test plan is the unit test. Okay. So I would like to explain a little bit about what unit test toolkit it can have. So basically we have a Mockito. Have you guys heard about Mockito? So it's a mocking framework that is very handy when you're writing unit tests. So basically it can help you mock certain dependencies that you have in your methods. And included in Mockito is a class called YBOX. So YBOX is something that allows you to inject objects into your classes. So that you can actually have, you don't need to create setters for your classes which might actually interfere with the design that you intend to have. So YBOX allows you to inject objects into it directly. And there's also a very cool library called AssetJ. AssetJ is basically something like your JUnit assertions but basically it allows you to assert like into, I mean assert stuff like collections and allow you to do a lot of Java 8 Lambda stuff. And there's an interesting plug-in called MoreUnit. So this MoreUnit plugin actually allows you to generate test templates easily. Like what we have done just now. So we are able to switch between your tests and your implementation pretty quickly. If you have an IDE and you install this MoreUnit it actually eases your development for tests significantly. Let me just do a demo on this. So I have a test case. So basically in the SpringPack we have one REST method that actually relies on a clinic service. So this clinic service is actually used to find from the database an owner by IDE. And this basically is a REST endpoint for you to communicate with this clinic service to retrieve back the owner. So basically when you write a unit test you don't want to reach the database. That's why we are going to mock the database so it won't reach the TV. So let me show you an example. So you can actually create a mock clinic service. So this is basically our clinic service that we are going to be inject into the unit test. So just to show you guys what is the unit you are testing. So this is the REST controller I was showing you earlier on. So we are going to be injecting this clinic service, this mock clinic service into this unit. So this white box is the utility I was talking about. So basically with this white box you can actually set the internal state which basically is replacing whatever properties within this unit with the object that you want to place inside. So in this case it will be our mock object that we are going to place in. So this is called clinic service. So if I try to run this test we should still pass. So basically I will just try to create something else. So with this mocky tool you can actually set up behaviors. So whenever you have a method that has been called on your mock, you can actually verify that it's being called. So for implementation, our clinic service is actually calling the owner by ID. So you can put a verification here and verify that your mock clinic service has this method called. So it can be any integer. So I'll run this test again to make sure that it's passing. It's because there's a condition here that says that the owner ID is not now. So actually this clinic service is the one that's calling this safe owner. So let me change this implementation. So it should be safe owner. One third but not going to invoke. I need to call the E. So basically after you've invoked your unit so you can actually verify that this service has been called. So one other thing you could do is actually to have an argument kept off which actually can capture what pass to the mock object itself. So let's say we have an object here that you want to capture for the safe owner. You want to know what is the value that you're passing to the mock object. Sorry. Sorry about that. So basically if you have an argument kept off you can actually capture this argument. So the object that you want to capture that is being passed to the mock object is actually your owner class. So you can actually create this argument kept off. So now after you have captured the argument, you can actually check that this is the correct argument that you have captured. Let me shut it off first. Sorry about that. So this is a captured owner. So after you have actually captured this argument you can actually assert that what you've passed into your unit is the same as what you've captured. So this is one way that you can assert. Let me extract out this owner so that I can make sure that this is the same guy that we are capturing. So running the test we can see that we can assert that the captured owner in the mock is actually the same as the one that we have passed into our implementation. So to verify that this test is actually valid let's say if we don't use the same owner that is passing from the method, we construct a new owner, we expect this to fail. I mean this is just an example of a test. Let's say we have done some changes to your implementation and we decided to construct a new owner and pass it to the method. So we expect this test to fail instead. So this is one way to mock the services that your dependency is on. So let's go back to this slide. So as you can see there's also assert J that we've used. Assert J is basically what I've used early on in the implementation. So there's a lot of methods that you could use it for assertions. As compared to JUnit right here, assert equals and that's about the limitation that you have. But for assert J you can see that there's so many different kinds of assertion. I mean it's actually much richer than using just JUnit alone. So we'll hand over to Alan to talk about the database testing. Sometimes in your application you are not sometimes open. You are reaching database and making some queries. But this is the code that we don't often test. And this is problematic because sometimes you have a problem because the query is not returning the result that you are expecting. And there are some techniques to test your DAOs. Everyone knows about DAOs, right? So with Spring we will see that you have some way to test that your SQL is running correctly and running into an in-memory DB. So who knows about HCPo? We will see how to set up an HCPo DB in your Spring project with a different profile and we will see how to test your DAOs. So we have a demo right now? Yep. Can you switch to... Can you exit that one? We'll go back and see. How can I see the explorer? Which one do you have? Which one do you have? It's okay. Who is using Spring Boot with Project? Okay. So Spring Boot works the same as Spring but it loads for you of configuration by default. So I will be using Spring Boot for the demo. If you're not using Spring Boot it works the same with classical Spring. So I'm not sure everyone see but anyway if you want you can go on my GitHub and check out the source code later to run it again and make sure everything is working. So for the demo we will be using Spring Data JPA it's generating instant repositories so you don't have to write SQLs. And the interesting part to see is that we have a production profile and a development profile and the difference between those profiles is the DB. Inside the production profile we can see that we will connect to a remote MySQL DB. So this is the MySQL DB and I created a test profile and with this test profile I'm saying that I will run an in-memory HSQL DB. So in that way I won't impact a real DB. I can do my test on an in-memory DB so when my test starts Spring we create a HSQL DB it will load some SQL scripts this is here so I can create my model inject some dummy data I can run my test and when my test stops everything is destroyed. So this is the good part So I have my init scripts in some folders so the SQL is different because between MySQL and HDB the syntax is a bit different. So we have already some implementation of a service let's say for example we have a clinic service and we have some method that calls repositories to make some queries in the database so this is the part we are going to test to make sure the SQL runs correctly so I will go in the test package this is this one right we can go back to the presentation mode so the first thing we are going to do is put an annotation to say I'm gonna run this test with Spring second maybe yeah so I'm just saying that to run this test I want to load the Spring boot configuration so basically it will load the same configuration that's in the production profile so I will have the same injection, the same objects everything is the same except the database that will be an in-memory database then I have to tell to tell Spring that I will load the test profile so if you remember the property file was application-test.properties so by putting test Spring will read that file and then the SQL DB will be loaded so if you want to do many profiles you just follow the same syntax you do an application, dash whatever you like and you can load that profile inside this is not active this is active profile okay right the last thing we are going to do is to put the transactional annotation so by putting the transactional annotation it's saying that between all the tests we are going to write we will persist the SQL because by default if you put transactional you can insert some data in the database and between each test data will be resetted there will be a rollback by default so for this test the last thing I just want to commit okay so let's write the first test so I want to test that I can find the owners in my database okay to inject my service so let's say for example I want to inject the clinic service so this is how you usually do when you want to inject a class so it's the same for the test and because we said we want to run with the spring configuration spring will instantiate all the beans and will inject that bean in my test so now the collection yeah right not used to that keyboard so now I can call my service and I can say for example find owner by last name I know that in my db I have that person and then I can just control shift it's not working so basically the test can take longer to oh you need a test right so basically it takes some time to instantiate because spring will load all the bean and all the configuration so as you know it takes a few seconds it creates the db and then it will run my test with the service and then I make sure that in my db I have two people with the name Davis so this is the case because I have an init script that is inserting Jumi in my db but let's say for example you want to test many dao you can inject you can insert an owner and then make sure that the owner is existing in your db and the good part is if you run this on Jenkins it will work because you are not reaching a real db somewhere so I will just show a quick second example so I'm gonna delete someone so I'm gonna delete this guy sorry for him yeah I should have copied this one yeah I will copy this one so my second test is I'm deleting Davis and then I'm querying Davis and I hope there is zero Davis because I deleted it nice so this is just an introduction about how you can test your db don't hesitate to do that yes what is the difference between your test cases? get that again you have that difference between your test cases so if you change the order you need to write all the reports if I change my owner in one method it could be changed in the second so if you call the second one it works so basically you have to deal with that putting there is an annotation in Jumi to say I want to order my name and then you have to put your name with an alphabetical order I think that is something we need to do so it shouldn't be a lie that you look correct but this is the way let's say for example you want to test a different operation that are incremental you don't have to make a choice you have to do like that but in most of cases this should be ethnic should run regardless of the order so for example here the bonus for this job is something I love to do if I want to have an order I will just rename my method with A, B, C and I can put a commit annotation I can put something like that between my method and then it will be committed for the next method but you have to respect an order okay the database is built for each test case you can do this it's initialized when you it's initialized when you load this test case because string initializes it and then it's the same dv for all the tests you're going to run you can before class you can do that you can actually use notages like before class you can use a class rule you can run a cleaning script you have multiple ways to do what you want there is a lot of annotation to do that okay so then thanks for the demo on the database testing so next we go on to the integration test so basically integration test is 5 minutes so just run through this so integration test basically is the next layer on top of unit test so what we have is actually you need to set up certain services that your integration test requires it could be a db or it could be some external http service that you require so you can even use docker containers if you want to emulate the service and for example you have docker image of the rest services you load the docker image you have the maven target to run that container then you do your test on the docker container and you stop it after the test and that's all this is the way you can emulate services and you have a lot of ways to emulate distant services so don't hesitate to use it in your integration test to test that all layers are communicating well so this is the thing that you are mentioning right so basically for you to have a consistent state when you are running your integration test you can actually use before or you can use the rule which is provided by junit for you to set up some data beforehand or to make sure that you have something cleaned up before you run your test so what's the different thing before rule and before in the rule so before is basically something that you put on the test itself where else rule is something that you can externalize into a class and which applies before you run each of the tests and the same goes for before class and class rule so these are basically the tools that you can use the notations that you can use to run your integration test yeah so actually we have a demo which goes straight right to the functional test yeah so well for functional test we have selenium selenium is actually used for web testing so there's many ways to run selenium you can use selenies you can use recorded test through a plugin you can use javascript or you can use java as well so for this case actually we have some demos that's written in javascript maybe we just run through it quickly so the advice for running functional test is basically to run it after your unit and your integration test because usually unit test and interviewing test are the test that runs fast it should be part of your development workflow but for functional test basically sometimes the scale of functional test can be it can run for hours so you don't want it to be part of your build I mean you don't want to just run a build and then go you can have coffee and have half a day off basically before you come back to look at your test results so this is what I mentioned so separating functional test from them workflow if it makes sense so you must also be sure that when you're writing functional test it's the critical path that your application will take I mean don't try to test everything using functional test because you don't have the luxury of testing every single path so only test the important critical paths that your application might have and try to target the environment as close as possible to production because there are some cases where when you try to run it the environment has not so much production like you might have surprises when you actually run it like for example if you have a load balancer sometimes you have session state information that is lost when you load balance but you can't test it when you have a single server running there so maybe you should go quickly to this just run through this you just have to understand that if you want to run those tests you have measurement plugins where you can say just run the karma test and if you run and you do it so I mean a lot of us are Java developers but sometimes we know javascript test but actually you can actually integrate it as part of the Maven build as well so we might have some javascript component inside your spring application so you can make use of this this Maven plugin is pretty good so you can actually download NPM your karma and all the dependencies that javascript requires into your project and you can start to execute javascript run tasks or jasmine tasks so there's also another tool called Protractor it's coming from AngularJS we can actually use it to run functional tests so I was talking about functional tests being run on Java so there's also javascript way to run functional tests to summarize the presentation some useful tips don't forget to follow the pyramid to do the unit test most important then if you have time go with integration test test the TV and other layers and please don't forget the front end test don't forget the front end blower it's a very important test that the workflow is working well this is a question people often ask do I have to test everything obviously no sometimes you will have some layer just pastoral to know the layer don't waste your time not testing this this is just a function that's called another function you don't need to be tested and of course if you have some metrics take some time to exclude the generated code because it will lower your code coverage so this is very useful as a quick fix so let's say your boss wants to erase the test coverage we want the 100% of code rate we don't need 100% by removing all the generating code and the useless layers then your code coverage will be more accuracy so finally yeah so this is what happened someone told me I need 100% this is not possible ok so I hope you guys have a good testing session and the oil test pass don't disable the test the first line is the most important never disable the test let me should we run through a do we have time? we can do two questions yeah so you guys got any questions regarding testing they love tests I think they have everything covered alright that's all