Pest is a fairly new testing framework, it sits as a layer over the top of PHPUnit which the majority of people reading this are likely more familiar with. Pest refers to itself as 'a Testing Framework with a focus on simplicity that was carefully crafted to bring the joy of testing to PHP'. Honestly, it's not wrong, Pest has dramatically changed the way I test, I enjoyed testing before Pest and I enjoy it even more since adopting it.
In a recent project of mine, Octohook, I was able to fully embrace Pest, right out of the box, and it has been one of the most pleasant developer experiences I have had in a long time. I would not hesitate to use Pest in any project moving forward.
I promise this isn't going to be some fan-article gushing over something new and shiny, nope, I'm going to break down some of the micro-simplifications that Pest affords us and that will improve your quality of life at the micro level.
Removing namespaces and classes
I'm starting with what I think is one the most powerful of the micro-simplifications Pest offers and it's probably one you wouldn't notice without trying and, perhaps, without also working on a decent size codebase running PHPUnit directly, that needs lots of new test files all the time.
When going all in on Pest, and I say this because you can still use Pest with regular PHPUnit classes and methods, you no longer need to concern yourself with namespaces and classes, on the surface, this feels like such a non-issue but, I'm going to be dead-pan honest with you now, I loath writing PHPUnit tests now - for this one single reason.
Having to care about your test suite having the correct namespaces and having to name your class the same name as your file is non-sense. It's a test, the only thing I care about is that I can find the test related to my controller or command etc and that it is testing my code.
The thing is, I love writing tests and I want to write as many as I can to feel secure that my application is executing as expected. When you start having to constantly write-out namespaces and class names, it gets repetitive, it's pointless and it makes testing boring.
When the only thing you are obliged to start your test file with is the opening
<?php tags, you become liberated. You no longer need to worry about these micro-details you are free to put more energy into the tests themselves, you know, the important part!
Writing method names
The PSR specs suggest you should write your method and function names in camelCase. writingLikeThisIsNotNatural nor_is_this. No matter how you spin it there is not a nice way of writing a method name that feels natural, let's be honest, you've just gotten used to it.
When naming a test you want it to be descriptive, you want anybody who looks at the test to know what it's testing and why. Writing something descriptive in any case is an inconvenience, whether thats awkwardly pressing
shift in-between words or having to install a string manipulation plugin to your IDE and doing some funky keybindings (which is what I did). It's awkward.
Pest simplifies what we are used to with PHPUnit, makes it functional and gives us these beautiful methods
test(). Both take a string and a callback, the string being the test name and the callback being the test itself.
Being able to write the test name as a string is one of the nicest feelings, having the freedom to type as normal and without some less-than-natural grip takes away this micro pain-point. It also encourages you to write more descriptive and expressive names, whether you realise it or not.
The naming of these methods as nouns also play their part too; test this thing does that, it can do this thing I expect to happen. They subtly encourage you to naturally write better, more descriptive, test names.
Not only is this a fantastic micro-simplification but it will actively make you a better team mate, if you are a at least a half-competent developer you will write tests with better names, no question.
Encouraging the use of helper functions
If you, like me, spend your days in a framework writing object-oriented code you've likely forgotten what a function is. Think of it as a method that doesn't belong to a class. Madness, I know, right! 😛
Because your code in Pest doesn't deal in classes, Pest encourages you to write helper functions to take care of repetitive tasks e.g creating a user and a team, you can bundle this up into a nice clean helper function.
The thing that hit me when writing these functions is actually how much cleaner and simpler it was to view all my helper methods, they were no longer two indents deep inside a base class which contained other helper methods too. They were just here, in one PHP file, all left aligned, clean and tidy. This structure, albeit a micro change, made these frequently used chunks of code much more readable and accessible.
The reduction of noise surrounding these helpers and being able to contain them in one place without worrying about naming and (to a point) inheritance makes this feature a really great micro-simplification for me.
Pest offers way more features than the few I have mentioned here and the documentation is incredible, I highly recommend reading through it when considering using Pest. Features like higher order tests, assertion functions are all amazing features but they don't count as micro-simplifications for me.
Nuno, the creator of Pest, is widely known in the community and is now an actual, real-life, Laravel employee. He has done such a fantastic job with Pest and I really hope it helps you write better tests but also gives you some additional energy to focus on the bigger decisions.
There are probably a number of alternative frameworks available that take similar approaches and I don't want to be the chap to say you should only use Pest and never venture further so I've included another framework that I have some experience with that is well worth a look;
Kahlan - I've very briefly used Kahlan myself and I've seen it being used a handful of times in some decent sized projects I worked with. It has a similar syntax to Pest but includes some built-in additional (or at least makes them more obvious) features like dynamic mocking and monkey patching.
Final thoughts 🧠
This is the first article in the micro-simplifications series and I really hope it sheds a different kind of light onto Pest, there are plenty of people raving about it for lots of reasons at the moment but I wanted to give you my, slightly different take on why you should give it a go.
Then, with all this new found decision-energy you have from these micro-simplifications, you can really focus on the difficult tasks and, of course, writing better tests.