How To Write Tests For Laravel Apps in PHP
There’s surprisingly little out there (that I could find) about writing tests for Laravel applications. Of course, there’s the Laravel documentation, but in many cases I have found it to be either not detailed enough, or in a very counter-intuitive order. I would have really liked more examples. So here are some of my own.
Test That A Route Exists
It sounds really simple, but testing that code changes don’t land any of our pages not loading would be a good thing to be able to check. Especially on apps that get very large.
$response = $this->get('/'); $response->assertStatus(200);
So, in line one, here, we go to the route of domain.com/, and in line 2 we check that that route receives a 200 status. 200 is the status of ok. It essentially means there’s a page of some description at the route.
Test That A Route Contains Certain Strings
If we wanted to know more than that a route exists, we could search the http response for certain strings. We can look for one string, or several strings in order.
$response = $this->get(); $response->assertSee('Website Name');
Line 1, here, is the same as in the previous test. It simply loads the route. But in line 2, this time, we’re saying we expect to see the text string ‘Website Name’ somewhere on the page.
If we want to check for more than one string, we could either repeat line 2 lots of times, each time with a different string. Or we could use the following assertSeeInOrder method, and provide it with an array of strings.
$response->assertSeeInOrder(['Website Name', 'subtitle', 'welcome to this website']);
Note that PHP reads code from the top left to the bottom right in lines, and for this test to pass, all the stated strings must be present in the order they appear in the array.
Testing Pages Behind User Authentication Middleware
This was one of the most difficult things to find and I’m sure there will be developers out there who disagree with the way I’ve done it. But this does work.
$response = $this->post('/login', ['email' => 'email@example.com', 'password' => 'password']); $response->assertRedirect('/dashboard');
What we have done here is simply posted an array of data to the post /login route, which is what the login form does when you click ‘login’.
We’ve then confirmed that when we do that, we are redirected to the dashboard, which would indicate that login has been successful.
Now, within the same test, we can add more, and perform a task.
Let’s suppose we have a simple app in which a user can update a profile that is public on the web.
So they can go to an update-profile page from their dashboard, and they can enter new information which will then be visible from their profile at /profile.
First, we’re going to visit the page at update-profile to confirm the page exists and has a box we can put text in. Then we’re going to submit the content to the post route associated with that page. Then we’re going to check the public profile page to see if the text is there.
$this->get('/update-profile')->assertSee('Update Your Profile'); $this->post('/update-profile', ['new_status' => 'this is my new status']); $this->get('/profile')->assertSee('this is my new status');
There’s surprisingly little out there (that I could find) about writing tests for Laravel applications. Of course, there’s the Laravel documentation, but in many cases I have found it to be either not detailed enough, or in a very counter-intuitive order. I would have really liked more examples. So here are some of my own.…