The Laravel Podcast

In this episode we talk with Nuno Maduro about the PHP testing framework Pest, a PHP testing framework that focuses on bringing you a more simplified, fluent, and powerful way of writing automated tests.
-----
Editing and transcription sponsored by Tighten.

Creators & Guests

Host
Matt Stauffer
CEO Tighten, where we write Laravel and more w/some of the best devs alive. "Worst twerker ever, best Dad ever" –My daughter

What is The Laravel Podcast?

The Laravel Podcast brings you Laravel and PHP development news and discussion.

Matt Stauffer:
Hey, and welcome back to Laravel Podcast. This is season five, where every single episode is about a different package. And today we're going to be talking about Pest, which is a testing framework created by my friend Nuro. Nuno, could you say hi to the people. You corrected me on your name earlier, and now it's just got me all thrown off. Nuno, could you say hi to all the people and say your name correctly, and then just start off by telling us a little bit about what is Pest about.

Nuno Maduro:
Hi everyone. So my name is Nuno Maduro. And yeah, thank you so much for having me, Matt. Pest is a PHP testing framework with focus on simplicity and it was crafted kind of to bring the joy of testing to PHP, gives you tons of cool features like good reporting on a console, Parallel testing and more.

Matt Stauffer:
I love it. So I know that it's going to be difficult to show a little bit of what's so cool about Pest because it's a very visual thing, but we're going to do our very best for all of you all to kind of explain a little bit about what the pitch is about, the experiences of working with it, even though we can't perfectly show you the things. So before we even get into the next steps, which is how do you install it? What are the setup steps, dependencies? I really want people to understand why Pest?

Matt Stauffer:
And so let's say that our audience is either somewhat or very familiar with PHPUnits. So if you all aren't just real quick, you'd make a class. And each method in the class would be the name of a test and it would be all in underscores. It would be something like test underscore. It underscore gets underscore data underscore correctly. And then inside of there, the body of that method is where you're doing your tests. Could you tell us a little bit about what's different just from the front, obviously there's other functions, there's other features, but just from day one of working with Pest, what makes it different in working relative to working with PHPUnit?

Nuno Maduro:
So great questions. The main job Pest tries to solve is really giving people a simple way to test their applications. So we kind of followed a lot of our philosophy here of trying to make things very simple. All the features that are very simple, documentation is very simple as well. And we want people to feel that testing is not actually hard. It's not something that actually takes time. And actually I prepared a very simple example for you all-

Matt Stauffer:
Love it.

Nuno Maduro:
With Pest, you can actually test if a page is okay with one single line. You just get the main end point and you assert okay. And you can add this line on your PHP file with just PHP open script on top, and then this line just below, and you can have a simple test with one line that tests a lot. And for me, this is really important, just really giving people a lot of power in the very, very, very simple way.

Nuno Maduro:
Another two examples I have here is the possibility of running earlier tests on Parallel, which just makes things way faster. And all of this happen, but just by passing an option, which is the flag Parallel. And yeah, we have so much cool things on Pest today. Like the most beautiful error reporting I have ever seen on a testing framework in the world is actually building on Pest. And I'm not even joking. I am working with tons of testing frameworks and Pest is really the most beautiful testimony reporting I have ever found. And yeah, so many building features that don't exist in other testing frameworks in PHP like PHPUnit, like Parallel testing, doesn't have doesn't exist in PHPUnit, all of these cool things that normally takes time to set up, they are just easy to do with Pest.

Matt Stauffer:
I love that. And so one of the things that people see when they first look at Pest is they notice that the syntax is different. And we can talk about that in a second, but I think what I really appreciate that you just named is, it's not just that the syntax is different, is that a lot of things that are either hard work in PHPUnit or manual configuration on each new project just come out of the box. Like you can do Parallel testing in PHPUnit, but it takes work and it takes knowing how to set it up. And then it takes setting up over and over and over again at every new project. Whereas with Pest, it just comes out of the box.

Matt Stauffer:
With PHPUnit, it's basically impossible I think to get the sort of simple syntax that you're doing in Pest. It's possible to get nice, pretty printers in PHPUnit, but it's, first of all, none of them are as nice as Pest. And second of all, it takes a whole bunch of work, right? So it's a combination of the quality of things you're getting for Pest, but also the ease with which you get them out of the box, right?

Nuno Maduro:
Correct. It's exactly that Matt.

Matt Stauffer:
Okay. So again, one more thing before we get into the actual normal questions of the thing. Can you talk a little bit about the syntax of an average test and how it differs from the syntax of an average PHPUnit test?

Nuno Maduro:
Absolutely. So PHPUnit offers you this kind of class oriented API and that API it's basically the things people already are used to, which is a name space, a class that extends something. And then you see a public function to actually see your first test. So you need to write all of this boilerplate to even do a simple assertion that your page is okay.

Nuno Maduro:
So what we have done with Pest is kind of getting back into our routes to the routes of PHP and see, all right, what is the simplest way I can see just the simple assert okay? Well let's just remove all of the boilerplate and just simply write where we want to test. And yeah, this philosophy is very inspired by Jest, which is, the one of the most popular JavaScript frameworks in the world. And I thought an opportunity here to also bring some of that simplicity to PHP and I think I've made it well.

Matt Stauffer:
Yeah, definitely. And one of the things I love is, so I often talk to people who are trying to come into PHP from the outside. And one of the things they complain about the most is they say, I show up to a new Laravel thing and there's dozens of files. And each of these files have all these names facing and stuff and there's reasons for it. And they just have to learn it. But I love the idea of something where if there's a potential for us to make it possible for people to write these things without having to learn about all the name spaces and the classes, or even just getting rid of the visual clutter, as, you know, some folks say of all of those things, it just can make your tests a lot simpler. I wanted to say one more thing about the syntax and I'm just going to go directly at it.

Matt Stauffer:
So in PHPUnit, if you're making something and I'm just going to go to the Pest home page and look at whatever example you have there. So you've got something that says it's a test that asserts that a user exists in a database. So you're going to check that a database has, in the user's table, an ID, an entry with an ID of one. So doing this in PHPUnit, and again, sorry for, you all just listening, but I'm going to do my best to try and describe it. You're going to say public function test underscore it underscore has underscore users and then parentheses and then squiggly brace. And then inside that method, you're going to then say this arrow assert database has, and then whatever user's ID of one. So it's a very simple test in PHPUnit. It's not a ton of work to write, but to have that one test to PHPUnit, you have all the other things, which is what Nuno is talking about.

Matt Stauffer:
So in this particular test here, and also you might have to do migrations and seating, in this particular test here, it's literally a function named "it". So "it", and then parentheses. And then you're writing these test names in actual sentence case. So, has space users and then ended their parentheses.

Matt Stauffer:
So you have a little bit more expressive way of writing these things where you're not having to constantly like figure out how to write underscores and then immediately chained off of that, you're just doing your assertions. So again, you don't have to then open up the method and then inside of the method, use this, all that. You're just literally chaining the actual steps of your test off of either off of that, or as a closure that you're passing into that either way. So it may seem like not a lot, but I would recommend all of you all of your interest in this, just go to PestPHP.com and just look at what the tests look like, because there's all these other things we're going to talk about today. But I think that if you're not seeing just the base understanding of how simple a test is and how much cleaner it is to read in Jest or Pest, you haven't even quite understood one of the foundational pitches of it.

Matt Stauffer:
So now that we've kind of like talked about that high level stuff, let's go into, what does it look like to actually install pest into an existing Laravel app? And are there any key steps or dependencies or what's the installation story look like?

Nuno Maduro:
Well, the installation is super simple. It's a composer required away from you. So basically once you required, you can immediately start using Pest. This was a very important key for me is that I wanted to make Pest progressive, meaning that you can install Pest on the existent project with, or without PHPUnit tests. And then you don't have to change a thing. You can immediately run past and your test will will just run.

Nuno Maduro:
Then if you want to opt in with a new API of actually writing the thing, you just described it with the eat functions and things like that. You can use it, but if you don't want to, you can simply use Pest for the beautiful error reporting. You can simply use Pest for the beautiful output for Parallel testing coverage and all the plugins it has. But if you want to opt in using this function basic API, you can also do it, but it was really important for me that you just install Pest with the composer require and you don't have to change a thing. So there is not really complicated things here, just the composer require.

Matt Stauffer:
So even if I'm making a brand new app and I like writing the PHP syntax, just because I prefer it, I will still get value from Pest because I will get, you said parallel testing support. We're getting the beautiful output. Is there anything else you're getting on top of a PHPUnit app? If I continue doing the traditional PHPUnit syntax, is there anything else I'm getting from installing Pest?

Nuno Maduro:
Yeah. So besides all these options that you can pass next to the password, which is coverage Parallel testing, the watch plugin, the rich ripe again. So there is a fully stocked plugins that you can find on the website. We also offer you something, we call the expectation API, which is an alternative to the assertion API from PHPUnit. And to make it really simple, so when you are working with PHPUnit, you basically type the word this, and then you can call the assert, and then a bunch of methods to actually assert that your code is working as expected. Now you can still use this on Pest if you want to, but we offer you an alternative, which is the expectation API. Now the expectation API solves tons of things that can be better that I think I have found on PHPUnit, multiple things such as you can chain expectations on the same value.

Nuno Maduro:
So for example, you can do things such as I expect a lot of our podcasts to contain podcasts, but also to be a string and to be, so you can do multiple expectations on the same value. The methods are just shorter and a little bit more simpler in my opinion. And I mean, there is multiple things into this expectation API that I invite you all to check it out.

Matt Stauffer:
Yeah.

Nuno Maduro:
But yeah, I mean, there is small add-ons that you can opt in that you can basically use if you want to, but if you want to use past simply to enjoy the beautiful error reporting, you can do it that way if you want to.

Matt Stauffer:
Love it. So what we're saying here is even if the new syntax is something that you're not familiar with, even if you have a massive code base full of tests, or even if you don't want to learn the new syntax anyway, layering Pest on top of your existing PHPUnit tests gives you, like you said, parallel testing, easy coverage generation, the beautiful reporting, and a suite of plugins that you can choose to opt into i one day you want them. So the expect is a really beautiful one that I really like, which once again, takes us from this arrow assert equals thing comma thing. And let's say, you're testing that same thing three times in a row. Now you have three of those exact same line versus this one, which says expect, that's a function name, expect, you pass in the value and then you're just chaining all on your expectations on it.

Matt Stauffer:
So again, it's just this nice fluent, convenient syntax that Nuno is talking about. I really love that a lot. So one of the cool things about this is we don't lose anything by installing Pest. You don't have to convert all your tests to this newer API.

Matt Stauffer:
You gain something immediately, you get better test reporting and everything like that. You also gain the potential of coverage and Parallel testing, which when you have it, when you need it, if it's super easy to do at that point, it's going to feel great. And you get the potential to add all these other plugins. I think there's also plugins, I have not used these, but I think there's plugins that make it easier to do testing with live wire. And I feel like at least one other thing, oh, you talked about the watch plugin as well. I haven't used either of those. So there's other things like the watch plugin and the retry plugin have to do with how you actually run your tests and it's like watching for changes and you rerunning the files, rerunning the test then, right? Can you tell us a little bit about that?

Nuno Maduro:
Yeah. The watch plugin is very useful. I was actually doing a presentation, a talk in Italy a few days ago and I was constantly changing the code then rerunning my test, changing the code and go into the console, rerunning my test. And the way I was pitching this watch plugin was like, did you watch how many times I actually had to change my code?

Matt Stauffer:
Yeah.

Nuno Maduro:
And then rerun the test on the console.

Matt Stauffer:
Yeah.

Nuno Maduro:
It was like 50 times. It wouldn't be cool if I could have Past watching my file and just rerun itself every time it changes? Well, we can use this in Pest, by simply press the option watch. And the watch is basically this process on Pest that every time you change a test, that you will rerun the test itself. It's pretty useful if you are just constantly doing some kind of TDD approach, you know? So, very useful. Yeah.

Matt Stauffer:
Love it. All right. So our next question is, are there any less use features that are cool or cool things you've seen people do with it?

Nuno Maduro:
Yeah, so actually there is a feature which I think is really polished on Pest, which is datasets. And data sets on Pest allows you to basically rerun the same test with multiple information. And this is very useful and is a feature that I don't see people using that often, but I think it's very powerful. And to give an example, you can have this Pest test, which you just call it, test email validation, and you probably want to test this with different emails, like 100 different emails.

Matt Stauffer:
Yeah.

Nuno Maduro:
And data sets are very useful in this scenario because you can simply say test email validation, write the test, and then at the bottom you just say with, and you provide an array of emails. And what Pest will do is basically rerun the same test multiple times with all those different emails. This is one of the features that I think it's really polished on Pest, but people don't use it quite often. And it's most commonly known as data providers on PHPUnit actually.

Matt Stauffer:
Yeah. I was just going to say it's like PHPUnits data providers, but so much simpler to use. So I love it.

Nuno Maduro:
Yeah. So, because in PHPUnit, you need to basically add an annotation with the name data provider and they need to pass the function name and then you need to create the function that actually, you need to type all these things like public function, then the data provider name, open parenthesis, and then return kind of a set of arrays. I think it's very complicated.

Matt Stauffer:
Yeah.

Nuno Maduro:
So with datasets, you can simply just write the test and you just chain them at it with, with an array of emails, and that's it.

Matt Stauffer:
Yeah.

Nuno Maduro:
So, very powerful. Then there is little things that exists on data sets that you can, for example, extract your dataset into a different file and reuse it, which can be also useful.

Matt Stauffer:
Yeah.

Nuno Maduro:
But yeah, another two things that I actually have here about a feature that less use it is actually the coverage.

Nuno Maduro:
I mean–

Matt Stauffer:
Okay.

Nuno Maduro:
I understand that the coverage have this kind of bad reputation of being something that doesn't really tells you like the quality of our test suite, but now that coverage with Pest doesn't actually have to be complicated, something I think people should do is simply ensuring that at least new tests do not decrease the test coverage.

Matt Stauffer:
Okay.

Nuno Maduro:
Even though if the test coverage doesn't tell you like the quality of the test suite, it's kind of a nice metric to have to at least ensure that new pool requests contain some tests somehow. It doesn't matter the quality, but at least tests are there a little bit. So kind of a feature that I don't see people using that much, even though the reporting on the console is kind of pretty, I think.

Matt Stauffer:
Yeah, it is. It's some of the nicest reporting I've seen. And I like your idea because one of the reasons why coverage has often been a problem is not because it's not a tool that we can be using, but it's people use it the wrong way. Like people use coverage to say your code's not good unless it has a hundred percent coverage. And once it has a hundred percent coverage, it is good. And like you said, just because it has coverage doesn't mean it's actually a good test. And just because something doesn't have a hundred percent coverage doesn't mean it's not good tests.

Matt Stauffer:
But there's other things you can use coverage to look at. And one of the things you said is let's just not decrease coverage over time. You know? So if we're at 62%, let's make sure each poll request keeps us at or above 62%. And that totally makes sense. Especially in open source projects where you've got people contributing new stuff and sometimes it's hard to remember to check for that kind of stuff. And I can certainly imagine the value of just being able to say, hey, there's a rule in the poll request template it says check to make sure the coverage doesn't go down, you know, kind of thing or something. So that totally makes sense.

Nuno Maduro:
Correct.

Matt Stauffer:
Are there any other lesser used features that you want to share with us?

Nuno Maduro:
I actually have here some cool stories if you want hear about.

Matt Stauffer:
Yeah. I'd love to do that.

Nuno Maduro:
Things that, yeah.

Matt Stauffer:
Things people have done with that?

Nuno Maduro:
I think one of the most impactful features, because I actually want to talk about the fact that some of the features I'm mentioning here, you probably have seen them now on Laravel. And this is kind of a Laravel Pest thing because, because I'm a lot of our core team member and I also work for Pest, there is some features that you probably have seen on Pest that are now available on Laravel to use with PHPUnit or Pest.

Nuno Maduro:
One of them is kind of the Parallel testing thing, which is in my opinion, one of the most impactful contributions I have ever made on Laravel in Pest. I have seen like entire test suites going from 10 minutes to one minute, this is really life changer in my opinion. Because you don't have to wait 10 minutes for your deploy to start.

Matt Stauffer:
Yep.

Nuno Maduro:
Which is very cool.

Matt Stauffer:
Yeah.

Nuno Maduro:
Also, I get very happy when I see people saying I have 2000 tests already in my test. We written in Pest, which is actually even more than I ever have wrote in Pest myself.

Matt Stauffer:
Yeah.

Nuno Maduro:
So I get also excited about that.

Matt Stauffer:
That's awesome.

Nuno Maduro:
So that's kind of cool stories yeah about Pest.

Matt Stauffer:
Very cool. Yeah. I mean, if anybody follows much of the Twitter community, the Laravel community, and obviously the Twitter Laravel people are only a small subset of the Laravel community, but it is fun to watch the adoption of Pest kind of starting to hit a really inflection point right now, where it's gone from like occasionally a few Pest advocates were using in the past to now more and more people. It really feels like it's the momentum is picking up exponentially.

Matt Stauffer:
All right, so do you have a development roadmap for this package you'd like to share? Do you have any big plans coming forward or does it feel pretty good as it is right now?

Nuno Maduro:
Well, actually you mentioned a good point. Pest V1 is actually feature frozen right now. Meaning it's super stable, but we are actually working actively on Pest V2 already kind of under the table because I mean, PHPUnit 10 is underdevelopment as well, which is kind of the foundation for Pest. PHPUnit 10 doesn't have a release date yet. So that's why we are not talking too much about Pest V2, but we already have a list, a nice couple of additions on it. The Retry plugin is kind of new only for Pest V2, allows you to basically you run test suite, the test will fail and you run the same past thing with the retry option. It will just pick up from the test that I failed.

Nuno Maduro:
We are actively working on a new video series for a platform that we all know, but I cannot talk about it yet.

Matt Stauffer:
Got it.

Nuno Maduro:
But we also have a blog, official blog for Pest as well under development. So yeah, that's the kind of thing that we are into right now. But don't think that because, rewriting Pest for PHPUnit 10 is a lot of work. It may sound like not too much, a simple migration, but when you are kind of sitting on top PHPUnit, there is a lot of small things that you need to change. So it's still a work in progress, but I think we'll make it.

Matt Stauffer:
Very cool. So speaking of the fact that you're doing work right now and also speaking the fact that you use, you said the word we, and actually let me stop there. I know that you're the primary creator of Pest and I don't I'm not asking you to name everyone who's ever done a pole request. I'm sure you're grateful to everybody who's done anything. But do you have any other kind of primary core team members of Pest or are you really the main core right now and everyone else is helping out hopefully, but not as a core member?

Nuno Maduro:
That's a great question. And thank you so much for paying attention to that. Because at the beginning, indeed, like when I first released the project, it was basically me, but now we have this kind of core team or at least a list of members that I trust a lot and basically give a lot of ownership over Pest. Like we have Oliver Nybroe, which is kind of the PHP store plugin maintainer. We have Owen Voke, which takes care of all the repository GitHub Actions workflows. Kind of these heightened work that nobody sees, but it's really helpful.

Matt Stauffer:
Yeah.

Nuno Maduro:
Luke Downing, which is wonderful, like kind of discovering cool features and really making content about Pest. A lot of people, even Freek Van der Herten recently have been a lot of contributions to the plugins as well. So there's a lot of people who kind of are in my trustworthy group for Pest.

Matt Stauffer:
Love it.

Nuno Maduro:
And yeah, it's kind of a team already to be honest, nothing official, but really helps to have people next to me, just taking ownership of the project and making stuff as well.

Matt Stauffer:
That's very cool. And my next question actually dovetails perfectly in that, which is, would you like to request any help or support if somebody is interested in contributing back to Pest, is there something they could do right now?

Nuno Maduro:
Good question. So currently Pest is a project with, actually an organization with dozens of projects already. And there is this misconception, which is if you want to contribute to Pest, you need to be very good at PHP. So that's not, first of all, it's not true. And the second thing is that there is tons of things you can do if you don't know PHP and, or you don't know very well PHP.

Nuno Maduro:
The first one is creating content around Pest. This is something that you were talking about, the wipe about Pest. And trust me, like the wipe just happened because people started creating content around Pest.

Matt Stauffer:
Yeah.

Nuno Maduro:
Because the framework has been here since two years of now. So yeah, one thing you can do is just simply create content around Pest. It helps a lot. Recently companies have investing time creating Pest video courses, articles, and that really helps an adoption really takes Pest over the masses is really because of those content creators.

Nuno Maduro:
And then of course, like just contributing to the documentation is a very simple way to get started with open source, but also getting started helping Pest. It's very difficult to find people who are interested to actually help under documentation. So, if you're up to it's also a very good thing to do.

Matt Stauffer:
Love it. So if anybody's interested in checking out Pest and learning more about it, where do they go? And if they're interested in following you, where do they do that?

Nuno Maduro:
Yeah. So if you're interested on Pest, you can check out the website PestPHP.com. If you're interested to hear stuff about me, just follow me on Twitter. I think Matt will put on the...

Matt Stauffer:
It'll be in the show notes, yep.

Nuno Maduro:
On the show notes. So yeah, just follow me on Twitter and all my stuff is over there, basically.

Matt Stauffer:
That sounds great. Is there anything else you wanted to cover about Pest today before we wrap?

Nuno Maduro:
No. Thank you so much, Matt, for having me here.

Matt Stauffer:
No, thank you. Not only thank you for teaching us this stuff, but like Pest is a delight to work with. So thank you so much for creating this and having a vision for what a testing experience that is so much easier and so much more beautiful would look like for all of us. I really appreciate you, man.

Nuno Maduro:
Thank you.

Matt Stauffer:
All right. And to the rest of you all, we'll see you all next time.

Nuno Maduro:
Bye.