Introducing Pest 3.0
Nuno shows the newest version of Pest, the elegant PHP testing framework.
Transcript
00:00:02 all right so I guess we just start just waiting a little bit for my slides appearing here on the screen but there we go hello LaRon I'm insanely excited to be here today for those who don't know me my name is Nuno maduru I the creator of multiple open source packages in the PHP ecosystem I'm also laravel cor team member and the creator of one of the most popular testing Frameworks in the world pass PHP do you agree with that all right today we have a main topic which is past V3 we are going to see everything coming new to this major
00:00:44 version of past PHP before we do that if you don't know what past is is pretty much this elegant PHP testing framework with a focus on Simplicity we have released it past in Spring 2021 and since then we already have managed to convince more than 50% of the LEL developers that pass should be your default testing framework two years after we have released it past V2 and this was by far the most successful release we have done on past introducing features such as profile an analysis code coverage reports architectural
00:01:23 testing watch mode type coverage snapshot testing stress testing and more now this release also reached 80 million total downloads I want to Round of Applause for because of that we also made it finally as a default testing framework on LEL you go to the documentation you see past being featured first but also if you start a new project using Lille new you will see that past is your for is your default testing framework now today it's it's not about past V 1 or past V 2 it's about past V3 in everything we have been
00:02:06 prepared we have prepared three new features for you that are going to blow your mind all right so if you guys are ready let's just get started past V2 always had this feature impossibility of creating to-dos it's a very simple con concept where you just go to your current test Suite just like this and you change the to the to-do method now once you do this you pretty much see your test being marked as a to-do now what you can do later with this particular feature is basically come here and just do Dash Dash to-dos
00:02:40 and see what is left in your project now we always have this but now we have more while working on this project at LEL which we'll see tonight something I was constantly doing is jumping between my test suite and linear which is a task management tool used at laravel now I was do I was jumping between my test s in Linea to see what is assigned to me what are the GitHub issue corresponding to that particular task and more so I just thought would it be so cool to have some of that but on my task Suite right
00:03:17 on my fingertips so today I'm proud to introduce to task management for past PHP which is literally issues tickets notes assignes literally in your test let me just show in demo this to you I'm going to move here back into my Sublime Text and my terminal and what I'm going to do now is instead of creating just a to-do I'm going to assign this to-do to Nuno Maduro just like that I'm going to save it run past and now hopefully here I have this particular test being aside to Nuno Maduro also something I can do
00:03:53 is just come here and type comma and they and basically assign this to a particular gab issue so now if I run past I see that the S is Nuno but also the gab issue is 11 and I can just click on it like how nice as it bam just right there on the browser see the gab issue corresponding to this um chest now in the real world use case you probably wouldn't have just one test right you probably would have multiple ones so here what I'm going to do is basically just type it might be edited and also might be deleted and just keep every
00:04:28 single test assigned to the same person and to the same GitHub issue is as easy as that now we have some duplication here which is calling to do literally all the time so what I can do is just leverage these cry blocks so I can just type these cry posts for example which is this test name and then just group all of these tests within my descri block as easy as that so I can do this just basically save it and finally just chain the to-do at the end of the describe so I don't have to-do all the time bam it bam it there we go clear my
00:05:09 test suite and I have exactly the same result as before and without replicating to do all the time now in this particular use case as you can see all of the tests are assigned to Nuno but if I want to assign a different git of issue to each one of these tests something I can do is literally not specify that on the describe and just do here issue 11 this is the issue 22 and this is the issue 33 as easy as that and now we have three chests in each one of them assigned to noooo but belonging to a different G
00:05:43 issue now again so far we have worked with a single file but with the real world use case you have more than one file in your test Suite so I'm going to just go here to this likes post and I'm going to uncomment this file I'm going to do the same with this images po test and uncomment now I'm going to run this entire test suite and here we have kind of a real world use case where we have images assigned to muhamed S we have likes assigned to Taylor otwell but posts assigned to myself and I can just
00:06:15 filter this I can just come here just type clear past um just run past in the S noooo and I will see what is assigned to me I can see as well what is assign to tailor just like that right on my fingertips and of course I can also filter by issue so here I'm going to just filter by the issue 11 and I get to see exactly what tests respond to the issue 11 not only that but at some point you will be done with this todos hopefully right so what you can do here is basically come to any any test really
00:06:48 and replace to-do by done once you do this this particular test will run and as you can see is passing at the moment and you don't lose the context which is one of the most important things so if this test fails in the future you know exactly who worked on it and you know exactly the GitHub feature now this is task management and is coming for past three thank you all right so far we have seen the feature number one coming for a past in this release we have three now the next feature is about architectural testing so I want to come
00:07:34 kind of showcase to you what currently we do have on pest two already regarding architectural testing so architectural testing is by far one of the most popular plugins we have on the past PHP Community because basically it ensures consistency in your code let me just quickly them architectural testing for you so I'm going to place myself here on the project number two in open this architectural testing file which is hopefully empty and I'm going to do the same on the console and hopefully we have no tests at all which I don't now
00:08:08 architectural testing allows you to test three main things globals dependencies and style let's start with global so you can see what this architectural testing is about in in reminder this already exists on past so something you can do is basically ensure that some Global functions don't get used all the time now a global function we love is DD the best D burger in the world now what I don't like to see you love DD right but what I don't like to see is DDS in production so how can we avoid that well
00:08:41 we can avoid it with a single line I can just come here and type Arch expect DD not to be us it you can just read it expect DD not to be used like just like a natural phrase so I'm going to go here run past and now I have a failing test with because within this project number two I do have this user controller using a DD right there so I can just remove it and have a passing test read so this is one of the used cases of architectural testing and as you can see it's very useful the second case we have with
00:09:14 architectural testing is testing dependencies I don't know if you guys follow me on Twitter but if you do you probably have seen me tweeting a lot about actions it's one of my favorite favorite pattern these days it basically allows you to extract a particular action put that within a class and not couple that class to the HTTP layer or the console we can pretty much test that in isolation however on this particular action called an update user something I'm doing which is wrong is coupling this action to the HTTP request so you
00:09:47 don't want to do this and you want to avoid this in the future you probably would just pass a regular array of attributes here so how can you ensure that this never happens in the future with architectural testing I'm going to show you my favorite architectural testing ever you just type expect everything under app HTTP to only be used in app HTTP as simple as this so everything created under app HTP form controllers anything just gets used there and now we have past PHP telling me that I'm using HTP
00:10:21 object within actions as as you can see here I can just go there remove the import on top also as well instead of accepting a full thing I'm going to just accept an array of validated information do the same just below when I'm calling the user update so here will be validated and finally within my user controller instead of providing the full HTTP request I'm going to provide only the validated information okay clear my terminal and here we have another passing test read so again this is what we have today on pass two one final
00:10:56 thing we have on pass two regarding architectural testing is test in style now I don't know about you but when I'm working with controllers something I kind of don't like is extending the base controller of Flavel so I kind of tend to avoid this so how can I do that with architectural testing well it's as easy as coming here and just type this architectural expect everything under app HTTP controllers to extend nothing again you can just read it I'm going to clear my terminal run past it does complain about
00:11:29 that particular controller I can just go there remove both extends on my controllers and now hopefully I do have a passing test Su which I think is pretty cool so this is what we have today on architectural testing on pest what's the problem with this the problem is that while it justifies a time with big teams in medium-sized teams and small teams in one person teams it can be a little bit hard justify the time just writing this granular rule RS down so for p 3 I wanted to make the architectural testing plug-in really
00:12:06 accessible to everyone if you are medium siiz small or basically one person working in your project so today I'm proud to introduce you to architectural presets which is literally one single line in puts hundreds of architectural rules in your project let me just do demo this to you I'm going to go go back into my supp text and instead of typing architectural rules one by one I'm going to just type one one line arch preset PHP now the PHP preset is the most basic we have right now I have a passing test
00:12:44 site so let's make this test we fail by using something we shouldn't use on any PHP project I'm going to try to come here to this user controller and just D the code right there just end the execution of code and obviously this particular preset will just fail now the PHP preset is one preset that doesn't matter the framework you use you can use Rupal WordPress Symphony or LL it can be used on any PHP project so something I shouldn't do on any PHP project as well it just return the PHP info if you don't
00:13:17 know this function kind of leaks all the PHP installation so you don't want it to do that I'm going to just basically run past PHP now and you will see that you're basically complaining about the usage of that function I can just remove it and now we have have a passing test R again so this is the PHP preset and also coming for past now another preset we have which I think is very cool is a security preset and just like the PHP preset can be used and Sh on any PHP project and obviously contains general
00:13:47 rules of safety about security and I'm going to give you an example so hopefully here we have a passing test Suite which we do and what I'm going to do here it's basically coming to my user controller and and try to do something I shouldn't do security wise let's try to Ash with mv5 the given request secret so nothing about this line is safe anymore so if you're using md5 this year you shouldn't uh I'm going to run just past and past will complain about the usage of mv5 thanks to the security preset
00:14:19 something else I shouldn't do is literally eval the current request code to allow arbitrary execution of code so here if I just run my test we again I have a failing test we of course run past again and now it's passing so PHP preset and security presets are two presets coming for a past and can and should be used on any PHP application now I'm going to show you my favorite preset again if I go back in the slides here a little bit you probably have seen me I mean I've been working on this project at LL for months now and
00:14:53 something I was constantly doing is writing architectural rules down more than 100 architectural rules TOS for this project to ensure consistency and at some point I just thought would be just so cool to be able to reuse this on any of my LEL applications that's what I have done so today I'm going to show you the the LEL preset which is literally my favorite preset coming for p three I just type LEL and let's see what the feedback we have from the terminal r v running vender be pass in the first
00:15:25 feedback is quite interesting so P PHP is telling me that the post controller shouldn't have any more methods besides index show create store edit update or destroy which as you as you well know if you go to the L Val documentation it's kind of the resourceful controllers we recommend that you have in your controller so we are kind of ensuring that you don't have any other methods besides this seven so if I go to my user controller right here I have um post controller apologize here I have this
00:15:58 safe post which to address the issue I can just rename it to store and ensure consistency this way however I run past and now it's complaining about something else it's complaining that this post response doesn't have the suix controller I don't know about you I love my controllers to be suffixed with the word controller so I'm going to just ensure consistency here by renaming this post response to post controller and do the same with the file name clear my terminal run p and we have one final thing you know what it's funny here it
00:16:32 doesn't feel a little bit like tdd you are basically fixing one problem another one appears want uh until you are done in Ure consistency so the last problem we have here is that seems that I have an exception within app exception so I'm going to just go there and see that indeed I have this user type no longer exist exception which is supposed to be an exception but it's not implementing throwable and as you all know if you don't Implement throwable it's because you didn't extend the base class we have
00:17:03 in PHP call it exception so I'm going to just address that issue by simply first of all include the exception uh class and finally just come here and type extends exception and hopefully I have no missing things to fix so thank you so this is the Lal preset my favorite preset but I think I have one more or two presets that you may like as well I've been in this community long enough to understand that is literally two types of people in the Lal Community we have the more stct type which likes declare strect types final classes value
00:17:44 objects prefer private methods overprotected in all of this however we have the other type which we can say is a little bit more relaxed right a little bit more relaxed doesn't like the class streak types doesn't really like final classes prefer prot Ed methods over private so I have created a preset for each one of these groups let's go to the architectural test instead of typing LEL I'm going to just type strict run past PHP and the first feedback I have is that this app service provider is not
00:18:16 final so let's go to the providers and address this issue I'm going to just come here and add the word final run p and well as you may expect is now complaining about other class not being final so what is important here is ensure consistency you know if you are a streak type of within the streak type just ensure you use final all over the place that's kind of the person I am I'm not from the street or relaxed I'm more kind of in the middle I just want you to use one of them basically so I'm going
00:18:46 to go here and move this from the street but now to the relaxed uh preset so I'm going to just type relaxed clear my terminal run past and here I have this final keyword which I forgot to remove basically uring I have zero final final classes in my project which is the best feature in the world right so I'm going to just remove the final run past is now as passing as expected thank you if I were to for example just use private here we'll complain because needs to be at least protected so kind of ensures uh
00:19:21 consistency in all your project so this is the architectural preset and is coming as well for past three so so far we have seen two out of three features coming for past task management and Architectural presets now we have one more feature coming for past let's work a little bit together and try to understand what tools do we have today that allows us to understand the quality of our test Suite probably some of you will say well we have coverage and in fact P PP offers you two types of coverage let me just show in demo that
00:19:58 to you this is currently stuff we have on P two by the way so I'm going to move here into the project number three and I'm going to open this password controller and do the same thing uh on my terminal place myself on a project number three and hopefully we have a passing test Suite which we do now pass PHP offers you two types of coverage the first one is call it type coverage I can just go here to the console just type Viner be past Das Das type coverage now if you don't know what type coverage is
00:20:27 is pretty much this feature that tells you that your code is fully typed which is a good thing so here I have 100% type coverage what do you think would happen for example if I were to remove uh you know this particular return type I'm going to run past and now I'm going down from 100% to 98% if I'm not mistaken there we go and as well tell p PP tells me directly you are missing a return type on the password controller line 16 I can just add it back and then I'm back to 100% uh fully typed code now this is
00:21:01 an interesting feature however it doesn't really tell me the quality of my test Suite it just tells me actually doesn't even tell me that I have tests at all it just basically ensures I have my code fully typed what kind of C other coverages do we have well we have regular code coverage which I can just come here and type-- coverage and on this particular project I think I have 100% there we go and you probably have heard in the community people saying code coverage is a waste of time well I tend to disagree with
00:21:33 that I can tell you for sure that having 100% is better than having zero right so that's a good thing having code cover just basically ensuring that we have tests however there is a problem about code coverage that I would like to show you I'm going to move back here into my project and as you can see I'm going to just make this a little bit bigger clear my terminal as you can see here I have this password controller which the goal is obviously update the user password so I have this update method which receives
00:22:03 a request and the first thing I do to begin with is ensure the given request is valid so I check if the user is providing is current password and then I check if it's providing the new password and this new password needs to be strong enough if you don't know this rule in LEL basically ensures that your password is strong enough to be on the system and finally only and only if the password is valid I'm going to actually update the user password on the database now with 100% code coverage which as you all see
00:22:42 with 100% code coverage what do you expect uh expect what all of you expect if I would just come here and remove this method line probably you would say well with 100% cast coverage you remove one line as important as updating the password on the database shouldn't know your test R is failing however if I just run it again not only my test R is passing but also my code coverage still 100% so this is the problem about code coverage in general is that tells you that you have tests but it doesn't tell
00:23:15 you the quality of those tests but for past three we have fixed this issue let me just show you today I'm proud to introduce you to mutation testing which is the ultimate solution you have on past that tells you exactly the quality of your test Suite I'm going to just demo this to you because I'm insanely excited moving back into my Sublime Text and just adding back this request update I'm going to expand my terminal run clear and instead of writing Das Das coverage I'm going to Simply type-- mutate and let's analyze
00:23:54 the output of this mutate Al together the first thing he did was was running my test read and my test read is passing which is a good thing after e have created one mutation of my app one mutation is kind of a slightly different version of your app a little bit different the difference was as you can see here the line 23 P speech we have removed this method call so at runtime P speech we have removed the method call that actually updates the password on the database without me even seeing it but because the test read was still
00:24:31 passing after removing this line 23 that allowed P PHP to determine that this particular line 23 is fully untested okay because it doesn't really matter if you have this line or not your test we was still passing and thanks to mutation testing we have detected that indeed this line 23 is fully tested we can see the feedback just below test we pass it without detecting the mutated code and here I have the div that c PP removed this line and the test we was still passing after that so we have clearly an
00:25:03 untested line here which is line 23 and if I clear my terminal and I just expand this a little bit you know that this line is actually updating the password on the database so how can we improve the quality of our of our test Suite to actually test this line 23 well I just have to go to this password can be updated and what this password can be updated is doing is literally just from the profile update the user password providing the current one and the new one and then checking if we have problems on our form so the problem
00:25:37 about quality of this test is that at any point we have an assertion that checks the password on the database so clearly we have a test here but it's missing quality it's missing literally an assertion here so let's add an assertion that if we were to remove that line our test we fails so it's as simple as this I'm going to just go here and do the following expect the ash of the new password to match the user is password on the database just one simple assertion I expect this to be true now if I run my test Suite after
00:26:15 this uh assertion obviously if I were to remove this and run my test Suite without mutate hopefully I have a failing test we because that's what I have added the stion for if I add it back now it's passing and finally if I run mutation testing again here I have the feedback that that particular mutation is finally caught in here just below I have 100% off mutation testing this is what tells you that your test s have quality not your own eyes not your colleague mutation testing score let me Demo to you one more example about
00:26:53 mutation testing because for the sake of Simplicity here within my past PHP file I'm actually running only one mutation which is removing a method call in just one within my password controller so let's run all the mutations we have let's give everything we have against this password controller I'm going to expand this and analyze the output together with you so first thing happening we are running our test Suite which is passing and then instead of creating one mutation we are now creating 10 mutations in my test read
00:27:26 and remember for each one of these mutations P speech will rerun the test read if the test read is passing that's not good means that the mutation contains mutated code fully in tested if the test is failing that's a good sign so let's analyze again this output together place myself here on the password controller and I can see that the first thing pass PP have done is on the line 16 pass PP went here and changed this public to protected and after that the test R was failing which is a good sign as you all know routes
00:27:57 need to be published methods so I'm going to just add it back and the second thing P PP has done is on the line 19 and 20 pass PP automatically went to every single validation rule we have and remove each one one by one so remove the required we run our test read our test we was failing which is a good thing and did all of this for each one of these validation rules however there is one rule which P spech we have removed in our test which was still passing after that and that rule is called password
00:28:31 defaults as you can see here this one got removed and the test Suite was still passing so if I were to remove this and just run my test read you can see that the test Fe was still failing so it's still passing so it doesn't really matter if we have this rule or not it doesn't affect the outcome of our test read and that's exactly what mutation testing is telling us so what I can do is ensure that this rule is indeed in place using tests so I'm going to just make my Sublime Text a little bit better
00:29:01 and improve the quality of my test Suite by uncommenting this test I have below and this test is pretty much simple the only thing I'm doing is ensuring the password or the given password needs to be at least eight characters so acting as an user I'm going to try to update my password providing the current one but this time I'm going to provide a weak password which is 1 2 3 and of course I expect to have problems within my form validation and obviously if I were to go to my test Suite run it now I expect it
00:29:33 still to be passing however if I were to go to remove this password defaults I expect my test site to fail so mutation testing really tells you which code is untested which for me is just amazing and huge progressing progression versus regular code coverage now thank you and to finalize as you can see if I run Das Dash mutate all the mutants get caught and I have below 100% mutation testing score which is exactly what you are looking for and now during this demo I've actually uh run mutation testing
00:30:14 only against the password controller I'm going to finalize by removing all of these filters and literally running mutation testing against this entire project and running this in parallel so it can be super fast and as you can see we do have a lot of problems to address on this test Suite so I invite you once p pp3 is out run mutation testing let me know what is the score you have so this is mutation testing coming as well for past three and a huge shout out to Sandro for coding pretty much all of
00:30:48 this plugin by himself he's part of the PC team member and yeah pretty much coted this mutation testing plugin a round of applause for him please all right today we have seen three main features coming for pass three task management architectural presets and mutation testing three features that I think will make the past three the best release yet if you like it past please go to P php.com we have a beautiful website in documentation to help you getting started with past if it's something that you are looking for now
00:31:31 past 3 is coming out next week and something that I'm insanely proud of is if you are using pass through the only thing you need to do is running composer update so zero breaking changes coming for pass three all right one more thing did you guys saw pinkery yeah so Pinker is this new social media I've been created on Twitter and it's kind of a social media I've been tweeting about it and it's bu on top of tools we absolutely love it's been on top of laravel Tailwind Livewire all the tools we love in the ecosystem and on
00:32:14 top of that is fully tested using past three so to celebrate the past three release and to make it really good I just thought let's make pinkery open source today thank thank you so much for having me lakon it was a pleasure to be with you and see you all out there thank you you crushed it good job thank you okay uh mutation testing is wild that is a beautiful feature where do you so like as you're leading this open source project do you Works does this all come from deep within your brain how are you getting
00:32:55 this inspiration for these wonderful things uhhuh uh so a lot of it is inspired by other testing Frameworks for for example the API was fully based on Just for example however sometimes features like test management just come out of need you know I'm working on this project and I have this idea and basically just pour those ideas to past PHP it's basically that well it's amazing well done give it up for Nuno good job Nuno thank you you killed it
Highlights
π Pest 3.0 introduces task management features for better organization.
π Architectural presets simplify testing rules for consistent code standards.
π§ͺ Mutation testing enhances test quality assurance beyond traditional coverage methods.
π Pest has become the default testing framework in Laravel, achieving over 80 million downloads.
π¨βπ» Nuno Maduro emphasizes community-driven development and inspiration from real project needs.
π
Pest 3.0 is set to release next week with zero breaking changes for existing users.
π Pinkery, a new social media platform, is launched in celebration of Pest 3.0.
Key Insights
π Task Management: The new task management feature allows developers to assign GitHub issues directly in their test suite, improving workflow efficiency and tracking. This integration fosters a more seamless development process.
π Architectural Presets: By introducing architectural presets, Pest 3.0 ensures that even small projects can maintain code consistency, making it easier for teams to uphold best practices without extensive setup. This democratizes quality assurance in testing.
π Mutation Testing: Mutation testing provides a more rigorous analysis of test quality by assessing whether tests can catch intentional flaws in code. This feature pushes developers to refine their tests, ultimately leading to more robust applications.
π Community Impact: Nunoβs emphasis on community feedback and needs highlights the importance of user-driven development in open-source projects, ensuring continuous improvement and relevance in evolving technology landscapes.
π Seamless Updates: The promise of zero breaking changes in the upgrade to Pest 3.0 illustrates a commitment to user experience, making it easier for developers to adopt new features without fears of disruption.
π Celebrating Innovation: The launch of Pinkery, built using tools like Laravel and Tailwind, showcases the vibrant ecosystem surrounding Pest, encouraging developers to engage with new projects and share their experiences.
π Pestβs Popularity: With over 80 million downloads and becoming the default framework for Laravel, Pestβs growth reflects a significant shift in the PHP testing landscape, demonstrating its effectiveness and community acceptance.