PHPUnit in Laravel: Simple Example of Why/How to Test

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello guys in this video I will show you a simple example of unit testing and laravel based on one of my previous videos about refactoring if-else statements so imagine a function that calculates taxes for the user for their account it is placed within a service or with some kind of class that is called from home controller so in the controller you call that function you calculate the taxes for the logged in user and then you just show them like this one so taxes to pay some kind of amount which is calculated from the database and I've seeded some dummy data for that user and that is working fine now you need to change that function to be more simple so your task as a developer is to refactor that method to avoid so many if-else nesting statements and this is exactly what I've done in a previous video earlier this week so the link will be in the description you can watch that but I did it without any testing and I thought to shoot a follow-up showing the exact situation how I would do that in reality and you could apply that to any complicated function that you need to refactor to make sure that your effector and didn't break anything existing so for that we would need to write tests first for those of you who are not familiar with unit testing or you are afraid to try it that would be the perfect video so imagine how you would do that without unit testing by testing manually after refactoring of that function you would have to check a lot of things manually so log in with some user and test if every case is correct so let's see what cases do we have so we try to find a user and if that user is not found the taxes should be zero so that's one case what would be two tests so try to call that function with logged out user and that would be actually pretty hard to test manually and then another test is if user is taxed so there is a filled in user database in the table so if user is not taxed the taxes should be zero so that's another thing you would need to test is log in with non-taxed users and see if it's zero and then two more cases to test calculate the income and if that income is above 50k per year then the taxes should be 20% otherwise it should be 15% so you would need to do quite a lot of manual work either generating that income records or using some existing users and finding which is above 50 K or below 50 K so wouldn't it be cool that some kind of robot would do testing for us guess what that is called unit testing so the most simple way to think about automated testing if you haven't done it before is just taking what you would have done manually and write that in the code so every time you need to test something the code would be run and would tell you if everything is fine so that's why in the long run you would save time with unit testing to compare with testing manually every time and this is what I've done here taxes test it's already written I won't life coding but I will explain everything so this is the file that you should generate in PHP artisan make test taxes test and every function of that class will be actual case that we describe just a minute ago so test if it's not taxed if its existing and stuff like that important part here is how we fake the data so it would launch those tests on some fake separate database and there are multiple ways to handle it but my personal preference is to create a separate database just for testing it would be empty and on every test it would be filled in with some kind of dummy fake data and that is handled by a refresh database so inside of your test case class you just go use refresh database and that would mean that every time the test is run the database will be wiped out and whatever you see inside of those functions those records will be created and then destroyed after the test is over that's why it's hugely important not to run tests on live database and I mean not even live live but in your local environment you could accidentally delete some important data for you to set up that there is a file PHP unit dot XML by default in laravel and there's one important parameter DB connection and by default it is SQLite so SQLite in-memory database and you could potentially use that but I prefer to use the same database as I would use in production which is MySQL in my case so I changed that SQLite to MySQL testing which will be a driver that I will create in conflict database file and I just copied and pasted everything that is in MySQL copy paste and change one parameter database would be DB test database so separate database name I would create it in dot ini' file so this way everything that we launched is on testing database now let's get back to our test and see what are we actually testing here first test as I mentioned is calculating that non-existing user has taxes zero and we pass user ID one which doesn't exist in our database because it's empty and the syntax of function assert equals is as you can see that expected result of that variable is zero if it's not zero it will throw an error and let me show you that for now I've commented out every other function and let's run that PHP unit testing how to do that is in your terminal you just do vendor bim PHP unit from the main folder of that laravel project and see the result is one test one assertion means one check and the result is green and that dot means successful test to show you a failing test so for example we will expect taxes of ten dollars and relaunch that PHP unit and now it throws an error which is f failed test and it would show you exactly the error so failed that zero matches expected tab and exactly on which line so taxes test 18 we go to that line 18 and this is our failure so the whole logic here is what we would do is we have that method we would write tests for it we will run that and make them green so all those tests will be successful and then we will change that method into much shorter like this one and then we run the test to make sure it's still successful for all the same cases so let's go back to our test and uncomment one by one next method is test that knock text user is not text and every method name should be quiet descriptive and don't be afraid to make it long but that is exactly the purpose and the point to make that descriptive to know which case is failing and every test consists out of two things setting up let preparation and actual testing and it could be a few things inside of the same method so preparation for preparation I use factories Factory is a class that could help you see fake data I use faker for something and factory for user class actually comes from the default laravel so if you go user factory that is default level and I didn't change anything so just sees the fake name fake email and some more columns so I create a factory for one user and I can override some parameters so in this case I need to override the parameter that is taxed is false by default on the database level in migration it is such a true so have that non-taxed user and I pass that as a parameter to that service function and then I check I assert that taxes for that user is zero and also we need to write another test so actually create the transaction for that user and then check that that taxes is still zero and also use a factory for another class income class income just an eloquent model and income Factory looks like this fill in the fields with random entry date a year from now a year until now random amount of money random description and user ID - which was just a local user for me and I can override it anywhere I want so in this case I overwrite user ID to the same non-taxed user and three date I need to make sure it's last year date so that transaction should be taxable unless the user is non-text unless we run our tests again phpunit see now to test successful but three assertions so three checks which means that in our second test we have to assert statements assert equals and assert equals and also you see two dots here one dot represents one test method and similarly we have other methods test income above 50k is taxed as 20% as I said it should be really descriptive clear and readable so we take variable of 60k income create transaction for that income and then assert equals this time not zero but expected income is 20% from the from the income I mean expected tax and then another method test income below 50k is taxed as at 15% which is this so those are almost identical we remove the comment and let's run our whole test suite it's called test suite now have four tests five assertions and everything is green and this is the first thing you need to reach first milestone before changing any code so you need to write out all the scenarios as you would test them manually to make sure they are still working and now we go to actually change that method so how I did it step by step you can watch in that other video I mentioned the link is in the description but basically it's the same thing just with less if statements with early returns I return that is zero if user is not found or user is not text then I calculate income and then use ternary operator to calculate income before I mean below or above 50k and now let's switch the names of the methods so let it be calculate taxes and this calculates access old and also before we running our tests let's make some kind of a type or some kind of an error here so let's say we did 0 0 2 instead of 0 2 so 2 percent instead of 20 we're running our test and it should probably throw an error and this is exactly what is the point of all of that to see an error after refactoring so same tests that were running before with green light and everything was clear now is failing and then you debug so taxes test 45 let's go here so this one is failing test if above 50k is a 20% then we go to the service and see what we'll probably be easy to identify the error we fix here click Save we run the test and now it's all green so this is a typical example pretty simple example but it could be applied to much bigger project if you need to refactor some big part of your application first write tests if you don't have them or maybe add more methods more cases if you need them and in fact bigger part of unit testing is not actually writing the code but more coming up with scenarios so on paper somewhere or in your head just list out the scenarios that you need then the work is to write it out in coding format in unit testing in PHP laravel and then you are more confident to rewrite that method or that part of the application because if you fail at something then your unit test or feature test should cover that that's it for this video if you want to know more about unit testing in Lara we'll have a special course called PHP unit testing for beginners in laravel the link is on the screen so you can check that out also subscribe to the channel which I'm shooting daily videos now and see you guys in other videos
Info
Channel: Laravel Daily
Views: 37,505
Rating: undefined out of 5
Keywords:
Id: DRhhfy2sG1E
Channel Id: undefined
Length: 12min 11sec (731 seconds)
Published: Sat May 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.