Starting Homepage TDD0:00
We are ready now to tackle our first to-do here. And the first one I want to start with is that a guest can see the course's overview. You will see now that I don't start with creating new models for Vue or the routes or controller, because with TDD we work with to-dos or features and they lead us to what we need. So let me show you what this means. We already have a page response test for the homepage because this will be our homepage. So I can start with a test just about this page. And I'm going to create now a new feature test and I'm going to do this with the Laravel Idea plugin, which I highly recommend if you're using Laravel because it makes your life just so much easier when creating new files or doing a lot of other stuff.
which I highly recommend if you're using Laravel because it makes your life just so much easier when creating new files or doing a lot of other stuff. If you don't have this plugin, just create a new test with the console tool artisan or just create the file for yourself. So I like to call this test, it's a page, so I like to start with page, page, home, test. And I know that I already want to refresh the database because we need some courses which we want to show on the homepage and Laravel Idea also knows that I have PEST installed so I can make the test a PEST test. So because I've checked that we want to refresh the database, we are now using here the refreshDatabase trait, which you already know from Laravel itself,
Defining Homepage Test Cases1:25
So because I've checked that we want to refresh the database, we are now using here the refreshDatabase trait, which you already know from Laravel itself, but now we are using it through the user's method of PEST. So this is how you can run a trait before every test with PEST. So at this point now, TDD forces us to think very clearly about this new feature and what it needs and what other things that we can test. So I like to create some empty tests here just to get out of my head the things that we want to test. So we already have one test here. So the first one, what do we want to do? We want to make sure it shows courses overview.
So the first one, what do we want to do? We want to make sure it shows courses overview. So that's the most important thing because it will be the homepage. It should show our courses. Then let's go to the next one. I have here another snippet in PHPStorm to just create a new PEST test for me. And how do we call this one? It shows only released courses. So that's one thing that I already know that we will have courses and courses that are released. And we only want to show on the homepage our released courses.
So that's one thing that I already know that we will have courses and courses that are released. And we only want to show on the homepage our released courses. And next here, let's go to the last one. It shows courses by release date. So we want to make sure that our courses are shown in a specific order. So what do we need our application to be in which state? So what are the data that we need? This is what we're going to do here in the arrange method. And in order to show courses in the overview, we need to have some courses in the database. And now we're just starting to write code which we have.
And in order to show courses in the overview, we need to have some courses in the database. And now we're just starting to write code which we have. For example, I want to make use now here of a Course model, which we don't have yet. And I want to make use of a factory for this model, which we don't have yet. And then I'm thinking about how to create a new Course. And I know that I need some title for this Course, because this is what we're going to make the assertion later against. So this will be courseA. And I think we're good to go. And let's create now three of them.
And I think we're good to go. And let's create now three of them. And let's change this now to course B and course C. And again, I'm not just going to create now the model. I want to write out the full test as I wished it would work. Now again, I'm going to want to act and make an assertion similar to what we had before. So I'm using the get method again. The route is again our home route. I need to import the function. And now we want to assert that we see some specific text.
I need to import the function. And now we want to assert that we see some specific text. And I can also provide here an array. And let's say we want to see our title of the first course, course A, and also of the second one, course B. And if we now try to run this test, it will fail because the class Course is not found and not given. And now the very cool thing about TDD is now that our failing tests are now telling us what to do next. So as mentioned before, do I have to create now a view, a Course, a factory, migration?
Creating Course Model Factory4:46
are now telling us what to do next. So as mentioned before, do I have to create now a view, a Course, a factory, immigration? There are many things that I already know I'm going to need. But I'm not going to think about it until my tests tell me to do so. So first, the Course is not given, so I'm going to create now a new model. Again, I'm using the level idea plugin just because it's so fast. And I'm going to create now a new Course with a migration. All right, here we go. I'm not going to, by the way, here inside the migration, I'm not going to add now the fields directly.
I'm not going to, by the way, here inside the migration, I'm not going to add now the fields directly. I'm going to run my test again. The class is still not found because we haven't imported it yet. So let's do this. Let's run this test again. Let's see. It's failing again, called to undefined method factory. That's because we haven't created the factory yet for our Course model. Let's do this.
That's because we haven't created the factory yet for our Course model. Let's do this. I'm also doing this with Idea, create database factory. And it will be called CourseFactory and for the model Course. Here we go. It's empty. Let's get back to our test. Let's see what's next. It's still failing. Yeah, and that's because now I haven't included the factory to our model.
It's still failing. Yeah, and that's because now I haven't included the factory to our model. So it has factory traders, which I need here for my Course model. Back to my test. Now phpStorm also knows about this factory method here. Let's run this again, and we should see now a different error. A query exception. General error, courses has no column title. Yeah, so we are trying here to create a new Course with a title, but we don't have a title field for our table.
Yeah, so we are trying here to create a new course with a title, but we don't have a title field for our table. So now we can get back to our migration here. Now creating a new string field, which is called title. Running our test again, and you can see we see now a different error. So we have here some kind of output here, and we have failed asserting that in this output here, we see our course title. So that's what we did here in our test. We are making a get request to our homepage.
So that's what we did here in our test. We are making a GET request to our homepage. We're getting a response back, HTML, and then we want to make sure that we see here some specific output, but we don't see it yet. And when we think about it, yeah, we can't see it yet because we haven't done anything with courses. We have no controller, we have no view. There are many things which we don't have yet. So at this point is where we first finally have to think ourselves.
There are many things which we don't have yet. So at this point is where we first finally have to think ourselves a little bit more because our tests are not telling us now what the next step is. But from time to time, it's okay if we have to think a little bit ourselves too. So how do we start? Let's get back to our route. Currently for our homepage, we are returning here this welcome view file. I already know that I don't want to do this.
Wiring Route to Controller7:46
Currently for our homepage, we are returning here this welcome view file. I already know that I don't want to do this. So what I actually want to do is I want to connect this route to a specific controller. And the controller, I'm going to call it PageHomeController. And here I would want to provide the class. I'm now trying to run our tests again. We see a different error because we have an invalid route action. This is because this controller is not given. Okay, let's create the controller.
This is because this controller is not given. Okay, let's create the controller. Again, I'm using levelId here. And let's call this page HomeController. And what I like to do is use a single action controller. So this means that we only have an invoke method inside our controller. And that's why we also don't have to define the specific method in the route definition here. And of course, I don't need the controller here because it is already defined here.
And of course, I don't need the controller here because it is already defined here. Okay, let's go back to the route. Let's import this new controller. Let's run our tests again. What do we see? Okay, we see a different error now. Failed asserting that nothing and empty string contains our course. So this means we are now not returning the welcome view anymore. But we have just returned nothing.
So this means we are now not returning the welcome view anymore. But we have just returned nothing. And of course, our courseA is not inside nothing. Okay, this also means the next thing we need to do is we need to connect our controller to a specific view. So I want to call here view called home, which we don't have yet. I can create this view here, which is not given yet, also with levelID. It's also a feature of this amazing plugin.
also with level ID. It's also a feature of this amazing plugin. So we have now here our view, which is empty. So again, the error still remains the same because we just returned nothing. So this means from inside our controller, we have to get our specific courses and then provide it to the view, and then we can finally show them there. So let's get our courses from the database.
Rendering Courses in View9:47
and then we can finally show them there. So let's get our courses from the database. I'm just grabbing all of them, and then provide them with the compact method to our view here like this. The compact method just creates an array of our courses variable, which then says courses equals to the courses variable. Okay, again, if we run our test again, nothing has changed yet because we also have to show our courses now in our view file.
nothing has changed yet because we also have to show our courses now in our view file. So I'm going to see here now for each of the courses, which we get from our controller, what do I want to do? I want to have probably some kind of headline. And let's grab the course title. And if we run our test now, it will pass for the first time here because we now have our titles of our courses.
it will pass for the first time here because we now have our titles of our courses on our homepage. Pretty cool, right? So we have now our first full test for the homepage, which just makes sure that we see the titles of all of our courses on the homepage. So after you have successfully created a test and it's passing, you have three different options on what to do next. First, we can move on and go to our next test
you have three different options on what to do next. First, we can move on and go to our next test and try to make this work. That's one option. The second option is to start refactoring our code because it's now working. It's now a good time to refactor the code because our test will tell us if we have done anything wrong while refactoring. So that's the second option.
Enhancing Test With Description11:24
if we have done anything wrong while refactoring. So that's the second option. And the third option is to enhance our test. Currently, we only check to see the title of our course, but I also know that I want to show the description here as well. So let's adapt our test and make sure it gets a little bit more specific. So this means instead of only providing here the title, I'm going to provide here the description as well. And I'm going to call this description course.
I'm going to provide here the description as well. And I'm going to call this description course. And if I've copied this correctly, yeah, we have now those values here. All right, and now I want to make sure, let's copy this as well, that next to showing just the titles of the course that we also see the description. For course A, course B. Oh, it seems we also forgot to check for course C.
For course A, course B. Oh, it seems we also forgot to check for course C. So let's do this as well here now. And then also for the description of course C. Like this. Okay, let's try to run our test. We see an error which is saying we have an Exception for the database table has no column called description. That's true. Let's create it.
That's true. Let's create it. Let's go back here. For the description, I want to use a text field. Call it description. Let's run our tests again. We now see a different error. We failed that we see the description. We see only the titles of our course. And that's because here we haven't defined it yet.
We see only the titles of our course. And that's because here we haven't defined it yet. So let's do this as well here. And let's add a paragraph for our course description. By the way, if I'm going to run here, the generate helper method of Idea, we will also get some auto-completion for the fields, which we already have defined in our creation. So this means description, we see it here now in the list, which is pretty cool.
So this means description, we see it here now in the list, which is pretty cool. Okay, let's run the test again and you can see that it is now working. So this means our test not only shows that we see the titles on the homepage, we also see the specific description for all of our three courses. So one thing you might ask here, so why have we not created a second test? Where are we going to check if we see a specific description for the title?
Where are we going to check if we see a specific description for the title? Because it seems for some tests we are creating new tests and for some we're doing this in the same test. And the answer to this is I really want to let my test tell me about specific things that we test. And a great way to check this is by opening up the file structure in phpStorm, because this shows now all the methods of our current test class here. And here we can see that we are testing.
of our current test class here. And here we can see that we are testing. It shows courses overview, it shows only released courses, and it shows courses by release date. So for the first test, we're making sure that we see some details like the title and description. So it doesn't bring more value to me if I see that we test the title and the description and maybe some other fields which we are going to have. But I think it's very important to make sure that we only show released courses.
But I think it's very important to make sure that we only show released courses. So that's one thing that I want to see here. And I also want to make sure that the order is correct. So this is why I ended up with those three very specific tests here. And you probably have already heard that tests are like documentation for your code. So if another developer wants to know how our homepage is working, he or she can just go to this test here, open up the file structure, and by reading the titles of our test, he or she knows what's going on here.
he or she can just go to this test here, open up the file structure, and by reading the titles of our test, he or she knows what's going on here. So this is very important to me to get a clear overview of what we are doing here. And that's why it's very important to think about first what we want to test, but also in which test we want to test it.
