 Some of this presentation will center around testing code. And we have already, so some of the projects used for testing we have seen before, right? So that's why this is going to be a little bit faster. And I have a few other projects and a few other, well, actually sample applications on the same github repository that I showed before. I think that the link will be up here in just a moment. So you will see all the different things that you can do. Now, let's see, same basic idea, yadda yadda, you know this, hope that I was able to do this in the past. We'll see. Okay, you know that. Okay, again, that's the link where you can get all the information, all the different projects. And all of that, again, is open source. So that should have been a problem. If you find an issue, if you would like to have a new feature or something like, please let me know, send me a pull request, it's all open. Okay, so the first thing is assertions. Because one of the things that we need to do with our test cases is to figure out if the code is doing the right thing. Now, I am culprit because I did this in the past when I was learning and I saw also my teammates to do the same thing. When they told us the management said, you need to write test, sure, I'm gonna use junitree and that's it. And we executed our code and then we verified that the code was doing the right thing. Using printouts, yeah, kind of works, but it didn't, right? So you have to use proper assertions. Now, junitree and for have an entry point for assertions is called the assert equals method, which you can use in many ways, but there's another project that you have seen before called Handcrest that allows you to do this thing. The one in blue, that's in this presentation, whatever you see in blue is what is specific to that particular project. So those are the same set up as before and we have some class on their test and we verify that that thing is doing what is supposed to be doing. So returning the value that is equal to that thing. Now, Handcrest is quite extensible and pretty much everybody knows it. The problem with Handcrest is that when an assertion error occurs, the generated message may not be as descriptive as you want. Believe me that this is much better than what we used to have before. Before crime, Handcrest, we had to have the expectation and the actual value and the generated error will say assertion failure error, this value, that value, not equal and then what? So description was kind of lost. Handcrest gives you a more descriptive error message. If this fails, it will tell you expected value test but actual value, the other one. Pretty much gives you descriptive conditions and it's easily extensible and comes bundled with JUnit 4 so you don't even have to define an additional dependency for this. But given that it's a little bit difficult or not really nice kind of messages that you produce with Handcrest, there are a few other projects that you can have a look at. For example, assert J. Assert J has also its own assert that method. It's done in this way so that you can just replace the original input for the other but notice what is different here is that here's the invocation, this is the value and what follows is fluent interface. And this method can only be invoked based on the type that we have here. So if these were to be a collection, then I would have access to the size of or the size equal to method or something like this. If it were to be a map or a match or something else, then I would have access to different collection of methods that make no sense to the other one. And this, again, actually would allow me to continue doing more assertions for the same value. The messages provided by assert J are a little bit better than Hankress but the most important feature provided by assert J is the capability to do the assertions in a fluent interface design. Assert J was inspired by another project called FEST, FEST Assert, which is a swim-based project and now, well, it works for any kind of Java project. The author of FEST Assert joined Google some years ago and I don't know if it was a direct influence by him or because some people at Google discovered Assert J and FEST Assert, they decided to create an own version called Truth. What is the main difference within Assert J and Truth? Well, looks exactly the same, isn't it? And the entry point, well, it's different but it's the same name. So technically speaking, they are the same thing. Actually, they are inspired by FEST, they are based on the same code but the type of messages that you can do with Assert J, the Google Truth, are much more descriptive and it has some additional features that Assert J does not give you. So regardless of this, if you use Hankress, Assert J, or Truth, you have now three different options to do your assertions and the last thing that I want to say about Truth is that even though Hankress and Assert J are extensible to using your own custom conditions and extensions, the way that you extend Truth perhaps is much friendlier to the developer, in this case yourself, the ones that need to create these kind of conditions. And the last thing, there are no advantages that is supported by Google. So if you like the stuff that is produced by Google and if this thing is good enough for the big projects that they have at Google, then it might be good enough for your own projects as well. Anybody here use Go, the programming language? Yeah? So you know that in Go, we have a big team of built-in version of testing that is quite easy to get started. So one of the features, one that they have is that you can run a test and do a bunch of assertions together and have one single point of failure instead of multiple, because what we have been told in the past with JUnit is that it should have as little assertion as possible was in the same test method because if we say we have five assertions and the third one fails, what happens with the fourth and the fifth? They don't get executed, right? But what if we want all those five to be executed regardless of the state of the other ones? We need something like the concept of soft assertions. This is something that AzureJ gives you. This is something that Thruud also gives you. Nothing that Hempgres gives you. But GoTest gives you that and JGoTesting gives you that as well. So how does this thing work? You use a JUnit rule to instantiate a JGoTest rule, give it any name you want to, use test or T, which is the convention in GoTest and then you can log as many messages as you want. This is just a printout of any statement and then notice that we do fluent interface chaining of these methods. You can do test, assert that, or check. It's up to you. Because the concept behind a JGoTesting and GoTest is that instead of following just one check, you want to do some multiple checks. Say for example, you got a card. This is the basic example. If there is something wrong with your card and you don't know what you do, you go to the mechanic and say, here's my card, please fix it. And then what does the mechanic do? And the first thing is he's going to check, oh, let's do a surface review and then, ah, I see. One of your taillights is broken. Okay. Then what happens? Does he simply stop there so they fix it? No. And it continues going on. There's a problem with your motor and there's something like this. And it gives you a full list of all the things that need to be fixed, right? It's exactly the same idea. You got a production test class. You run it. There may be five problems with this thing. You just get, run all the checks and then you say, boom, five errors instead of the first error fixed. Ah, another error fixed. So the feedback look is faster. That's the whole point. To make sure that you got information as soon as possible. So with this thing, we can use hand crest matchers or we can use Boolean expressions or we can pass the value directly. And at the end, all these things will be evaluated and you will get a full report of all the things that fail thanks to that rule. If by any chance there is an error and any kind of exception that occurs during this execution, it will be also caught by this one. But unfortunately, once that error occurs and if you have other code and any other checks, those checks will not be able, will not be executed because the whole method aborted using an exception. All right. So now let's go into general. This is a pointer to the same application that we saw before, the gif of API. And so I say it's quite the same thing. So we saw JUnit programs. Now we saw much better what needs to be changed. So the things in blue. So we know this. Then Moquito, again the things in blue just a quick refresher. I promise there is new content coming up. And Junkito, all the things that are different. Spock, for which I will show you a different way to do the parameterization because you can do it in this way which kind of looks weird, right? Because of these characters. What about that? Does it look better? Okay, have a look again. Odd data table. Same thing, right? But now it's much better to see, okay. So for all the values of the input variable for this will be the first test row. And so that's also output. And here's the second row and third and fourth and whatnot. And you can have as many columns as you want. Much, much better. Bad, good. There we go. That's what I like, Spock. That allows you to do great things like this one. Okay, we saw that. I waitability, we saw that too. Wiremock, we saw that too. Now comes the good thing. Let me see if I got this application going. It's the to do example one. And we do run, I believe. This is a web application using the Spark Java framework just because it's very easy. And now I'm going to say curl localhost 8080 and I think it's to dos. Oh, no, sorry, that's not the port. 4567, silly me. 4567. And we got a JSON payload. Nice. But I'm gonna make a full out of myself, try to remember how to define a header, I think is accept, content type, text HTML. Is this the right way to do it? Yeah, here we go. Now it gives me the same content, but using HTML. Okay, so my application is a bit smart and knows how to do content negotiation. Ooh, so early 20s. All right, now what I'm gonna do is, let's kill the application. And I showed you the code for this application. Here we go. It also uses juice. Let's make it a smaller. Like this. And there's a Spark Java. There's some bootstrap for the data and that's pretty much it. Whoa, that's cool. Because the important thing is in this object called routes. So let's go into Spark and routes. And here's this class. And this class is just an interface, aha, so it's coming from this. Which gives me access to the actual Spark behavior. Okay, so we're getting further down to the rabbit hole. So the actual implementations found in these classes. So these are interfaces. So the default methods are this one. So perhaps let's go with the list. The list does this. This is a Spark Java object. Nice. Creates a pojo, adds it to the model and returns it using a repository. And what is it to do repository? That's where we start getting into JPA or some other means. Actually, this project makes use of another library called SQL2O, which are very lightweight. SQL2ObjectMapper is not really an ORM, but it's quite small and quite fast. So for in order to do this testing, if we need to test the repository, which is right here in the database, that interface, we need to test this interface and we need to test the application. So testing the interface of the repository does not a problem because that's plain Java object. So that's it. Let's see. We use Yukito, okay. And we define a custom test module. We'll see that in a moment. So you remember Yukito is JUnit, juice and Moquito together. So these injections will come out from the good use injector. We invoke the bootstrap so we got some basic data and they will start to do assertions with the repository. And for example, we can do the find all. There's handcrest matchers, another matcher. Then we save, we find and we start to do things. And then the next thing is this module that we saw before. Here's something that Yukito allows me to do is that I can override default bindings for a particular module. So for the case of the bootstrap, instead of using the real production bootstrap, we're going to use this class, which is right there, which does nothing. Did we do this because this app module here, this is the production module, it does define a concrete binding for this interface that will do the right thing in production. Well, we want to change this for testing code. All right, so again, this is just like any regular Java code. What if we were to test out the actual route? This will require the real server, don't we? And let's see what happens if we run the test case. It's kind of working, there's one test executed, then the other one, come on. Waiting, waiting. Everything successful, you trust me? I said you trust me, you kind of do. You shouldn't, never trust a test you haven't seen fail once. Let's make sure that this thing fails. Do we have no null value? Not null value, change this condition to that, run it. We should get at least one failure. And there we go, yes, it fails. Now we know the test was okay. There's the other one, the application test case. This one, test out the application object itself. So if we see the application, it's this. So this is kind of like an integration test case where we need the real repository, the real routes. So we need to hit the real server somehow. So we need some kind of client. Remember we are building a web application. We need a client that we can use with fake queries perhaps. All right? And that's exactly what we do here. Okay, using Yukito, here's the application object. We start it, we finish it, and here comes the Groovy. And by Groovy, I mean actual Groovy code. This looks like Java, it is Java code, but the code that is behind this implementation is Groovy code. Given certain port, when that particular URL is in bulk, then I expect somebody using this notation, this code right here is actually run by Groovy code inside. But you don't have to be aware that it's Groovy code, it's cool. And then again, using Handcrest matches, we make sure that these values get transformed into the right thing. And here's another one when we expect, this is when we empty, and this is when we create a new item. So we post, we expect the list to contain now more values. So the great thing about this is because Spark Java is so easy to get started. For the test case, we can start the real server and shut it down. What is new here is this API. This is known as REST Assured, which is exactly this thing. REST Assured is a DSL for defining web clients on which you specify your expectations, you can configure the delays and timeouts and the port, and then you can do get possibly, you can do all the HTTP verbs, and then you can verify on the body using simple expressions. So regardless of the, remember the response is XML, or actually HTML or JSON. If I pass an initial length header here, if I were to return XML, the format, at least in terms of the content is quite similar to JSON in the sense that there is a to-dos container that has to-do items that have description property. What is going on here, this is known, well, if it were XML, you know you can use something called XPath. But in JSON, there is something called JSONpath. And in Groovy, we have something called Gpath, which works for a graph of objects. What's happening here when I mentioned that there's some Groovy behind is that the actual implementation is intelligent enough to figure out, oh, is XML? I do this. If JSON, I do that. If it's an object notation, then I do the other thing. Using JSONpath and Gpath. So you can switch here to JSON or XML or the other. Your expression will be exactly the same. So it allows you to validate JSON, XML, and HTML. Here's another thing, because it's very unlikely that you're using Spark Java. Probably you're using a standard Java EE or a Spring Boot. If it's a Spring Boot, it comes with its own testing facilities, which I'm not going to discuss here. But who's using a standard Java EE? Wow, no one. Interesting. What you guys are using? Besides Spring Boot. Is there something else? Drop Wizard? What else is out there? J-Hipster? Grails? Come on. You're not web developers? Wow, okay, cool. Well, if you have to work with Java EE, the problem with Java EE is that you have to run your application on a container. So in order to test this thing, you have to have a container. How do we set up a container in the right way so that we can have the application in the correct state in order to run the test case? That is the problem. But there is a solution. That solution is called Archelian. It's a test framework that we're going to see next. And for that, I got another version of the application. This is a standard Java EE application. Let's see. That also uses juice. Here's a servlet. And here's my to-do servlet. Let's make it bigger. Let's expand this a little bit. All right. So it's a regular servlet that has injection, that has its own routes. It has a bootstrap and does the handling. That looks a little bit like what we saw in Spark Java. But how we handle this in the default list route, exactly the same as before. Grab a reference to the repository, then pass everything and then send it to something that looks like a model in view. This is specific to this class here, to this application. The simple pojo again with our good friend Lombok. And we go back here and wow, what is this thing? No, do the list here. We got another interesting project called Mustache. Anybody done Mustache templates in JavaScript? They're quite good, quite fast. Mustache Java is very, very fast. The best, fastest templating solution for Java. Anyway, going back to this is how do we run this application? We need to have a real container. But if we use Archealian, not a problem. For example, here's my test case. Looks pretty much exactly as the other one, isn't it? The difference is that we're using another port because I'm running this test case embedded in Tunkat. Okay, so that's exactly the same. What about the other thing? This, my friends, is how we can tell Archealian to create the web application, the war file, that is going to be deployed on a particular container. If you're using Maven, which I guess most of you use Maven I suppose, then Archealian knows how to resolve all the dependencies that need to be added to the dependencies. It's quite easy, but because I'm using Gradle, I need to do extra stuff. Say, here's the way, where is the way for Maven? Here's the way for Maven, by the way. You do Maven resolver, and then you can give it a name on the point file or the location of the particular point file and tell it, give me all the test dependencies or all the runtime dependencies that will grab all the locations for the jars. You have it here, and let's just add it to the web archive. I'm doing this because I'm running with Gradle so I don't have a point file. And then also with Gradle, I grab all the dependencies that are needed for runtime. There we go. So what else do we do here with this archive? We say that it's a web archive, so it's a war that contains that particular resource. So we'll see what is in that resource. And then we're also going to add another resource, a web.xml, and add all the files and also where are all the classes? This gives me all the classes right here that I need. Okay, so everything is fine, and this will generate a war that gets automatically deployed to a container. And there are three modes to run the container. Embedded mode inside the test case. For every test method, a new container is going to be started, deployment is made, test case run, done. There is the managed version where you got a local container installed on your machine that is shut down, is not running. And when you run the test case, the test case will run the container, do the deployment, and run the test cases. And the final thing is the remote. You got a container already running somewhere. It might be on the same machine on all the server. And the test case will do the deployment to that location and run the test cases. So let's see what happens when I run. And let me make a mistake here. For example, at java.one. You could never trust that test case. You haven't seen it fail once. Okay. Hopefully Gradle will not gobble up all the messages because by this moment, it will try to launch Thumbcat to the deployment and then run the test case. You can put the configure Achillian with some resource files like this one, where I'm telling which kind of mode I'm running. Thumbcat on that port and that's everything that I need to do. So this is a resource that is going to be found automatically by Achillian. You can have different containers, with different names, with different settings. So you can have a managed version, a remote, or a embedded one as much as you want. And it fails. Perfect. Build, report, test, test in the XHTML. There we go. Takes a moment. And of course, there's the assertion failure that we got. And in the standard output, where does this print out? This is printing out the contents of the wire file. So we can verify that it contains all our production classes, which are these classes right here. And all the gyres that are needed. Where this thing is coming from? Where is the application test case? At this line right here. I like to use this so that I can quickly verify if it has the right contents, or at least what appears to be the right contents. Because you can shrink, if you don't need a whole application, you can say, perhaps I'm just testing a small subset. So I want to include these classes of this package, or exclude this package perhaps, but include the other one. So you're free to do all that is needed in order to create the deployment. Okay. So that's basically Archealian. And the other miscellaneous options. Any of you have had the need to create a PDF and then assert that it has the right contents? Well, if you ever had the need, know that it's something called PDF unit. PDF unit, it's aware of the document model of PDF. So say that somehow you have generated a PDF using some reporting mechanism, like Jasper reports or something like that. Then you create an object of type page region and start doing assertions like this. What is the document on the test? It will read all the document and start to look at the different elements. So you can figure out if it has the right number of columns and if there is a value in the right cell when it's suspected. Instead of doing a visual verification. That is much better, I would say. There's another one called XML unit. I would expect that sometimes you need to work with XML and that you need to verify that it has the right contents, right? XML unit does it for you. So in this case, we have to extend from XML test case. There is no way to do composition. It has to be inheritance. We have some basic content here. This is actually a real test case for all the project that I have. Remember that I mentioned that Java has just a few, actually a lot of Java libraries. There is a real test case for a project called JSON live. It's the third project that created JSON to Java and Java to JSON and then added XML. I know it for a fact because I'm the author, it's kind of like 10 years old. And so when I brought this test case, I needed to figure out that XML was written correctly from Java and JSON. So this thing serializes some Java objects from JSON to XML. So that's the JSON. Then writes it at XML. And it needs to verify that the response, that thing is actually the same thing as that. And there are more things that you can verify with XML, but at least you can check that it has the right number of tags and it has the right content. And with that, I promise that I'm gonna make it this quick. It was close to half an hour. I wanna close down that again, really remind you that everything is open source. You can use it right away. If you can contribute to open source, the easiest way that you can contribute is report an issue if you find it. Please leave as much information as possible, what the running environment or what happened, the steps to reproduce. The next thing to do is getting in touch with the community, getting in touch with the authors and the project team so that you have a conversation going on. And if you can supply a test case and if you can supply a patch, that will be great. But again, the easiest thing to do is just submit an issue or file a report if you find something. We all benefit because of open source. And I think that's pretty much it what I have. Thank you very much for listening my rambles for close to two hours. And again, let me repeat that I'm very happy to be here. I'm here for two weeks. So if you want to continue hearing me rambling on on different projects and some stuff, please let me know. I'm available for the next following weeks. Thank you.