Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

PHPUnit (Legacy): Testing with a Bite

2:54:09

What you'll be learning

While the fundamentals of PHPUnit haven't changed, this tutorial *is* built on an older version of Symfony and PHPUnit.
// composer.json
{
    "require": {
        "php": "^7.0, <7.4",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/orm": "^2.5", // v2.7.2
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "sensio/distribution-bundle": "^5.0.19", // v5.0.21
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.28
        "symfony/monolog-bundle": "^3.1.0", // v3.1.2
        "symfony/polyfill-apcu": "^1.0", // v1.6.0
        "symfony/swiftmailer-bundle": "^2.3.10", // v2.6.7
        "symfony/symfony": "3.3.*", // v3.3.13
        "twig/twig": "^1.0||^2.0" // v2.4.4
    },
    "require-dev": {
        "doctrine/data-fixtures": "^1.3", // 1.3.3
        "doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
        "liip/functional-test-bundle": "^1.8", // 1.8.0
        "phpunit/phpunit": "^6.3", // 6.5.2
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.4.30
    }
}
// composer.json
{
    "require": {
        "php": "^7.0, <7.4",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/doctrine-bundle": "^1.6", // 1.10.3
        "doctrine/orm": "^2.5", // v2.7.2
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "sensio/distribution-bundle": "^5.0.19", // v5.0.21
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.28
        "symfony/monolog-bundle": "^3.1.0", // v3.1.2
        "symfony/polyfill-apcu": "^1.0", // v1.6.0
        "symfony/swiftmailer-bundle": "^2.3.10", // v2.6.7
        "symfony/symfony": "3.3.*", // v3.3.13
        "twig/twig": "^1.0||^2.0" // v2.4.4
    },
    "require-dev": {
        "doctrine/data-fixtures": "^1.3", // 1.3.3
        "doctrine/doctrine-fixtures-bundle": "^2.3", // v2.4.1
        "liip/functional-test-bundle": "^1.8", // 1.8.0
        "phpunit/phpunit": "^6.3", // 6.5.2
        "sensio/generator-bundle": "^3.0", // v3.1.6
        "symfony/phpunit-bridge": "^3.0" // v3.4.30
    }
}

It's Friday night... it's stormy... the office is empty... and you're deploying fresh code to production. Suddenly, an alarm! What!? The fences are down!? The dinosaurs are escaping! Somehow, your beautiful code contained a bug! And as the raptors surround you, one thought keeps coming back: if only we had written tests.

Indeed.

In this tutorial, we're going to jump over the hurdle of learning how to test so you can save the day!

  • Basic unit testing
  • Test-Driven-Development: how to do it, when to do it!
  • Mocking and test doubles! Creating mocks in PHPUnit & Prophecy
  • Using data providers to run tests over and over again with different input
  • Running code before and after each test
  • Testing for exceptions
  • Handling the database in tests
  • Integration tests: testing with real objects
  • Functional testing!
  • Continuous Integration (CI): let the robots run your tests

So grab your keyboard, reboot the system, and start testing with us!


Your Guides

Andrew Marcinkevičius Ryan Weaver Leanna Pelham

Buy Access

Join the Conversation?

32
Login or Register to join the conversation
Default user avatar
Default user avatar Simon Carr | posted 4 years ago

Is it normal that we get one video per day? or will we see a few all at once?

1 Reply

Hey Simon,

We want to deliver our content as soon as possible to our users, i.e. we publish new videos right after they are ready. It depends, but most of the time we are able to process 1 video per day. It's a complex process, we need to recode video, record audio, then make them both together and add some special effects like a cool animation, video notes, etc. So we *can* release an entire course at once, but then you need to wait a few weeks when we record and process all the videos in this course. But as I said, we chose a different strategy - release new videos as soon as they are ready. If you want to see the entire course in the same breath, take a break and return in a few weeks, I think to that time almost all the videos will be released. Thanks for understanding!

Cheers!

Reply
Default user avatar
Default user avatar Simon Carr | victor | posted 4 years ago

Thanks Victor. It was not a criticism, just a question and your strategy serves everyone, like you say, I can just wait, but I think I will still watch them as they come out they are like a box of chocolates, you eat them as soon as you see them.

Reply

Hey Simon,

Haha, no problem! I just explained our complex workflow a bit ;) On the other hand I totally understand you, it'd be cool to watch as many videos at once as you want and take a break when you want :)

Cheers!

1 Reply
David_S Avatar

Hello,

I've found a problem with downloading videos:

The numbers for some videos for the downloaded mp4 File does not fit to the number of the lesson where this video came from. At least, the first of them also have a title the does not fit to the lecture.

So far:

21 - Clearing the Database => 14-Control-Database.mp4
23 - Functional Tests => 15-Functional-Test.mp4
25 - Test Fixtures & Fast Databases! => 17-fixtures-fast-db-updated.mp4

I know, this course might be updated in the future, but the basics are still the same, so would you mind to fix this, please?

Reply

Hey David_S!

Thank you for such a detailed report! You're right, and I just fixed all the video names you mentioned.

If you ever noticed any misprints in the file names - feel free to report, I would be happy to fix it :)

Cheers!

1 Reply

Hi,

Do you plan to update the course for Symfony 6?
I would like to learn the testing, but afraid I can't figure out how to adapt it to the current Symfony.

Reply

Hey Joshua,

We're working on upgrading this course, yes! Unfortunately, I don't have a specific date of its release yet, but it should happen soon. So far, you can track upcoming courses on this page: https://symfonycasts.com/courses?status=upcoming&amp;sort=popular#all

Cheers!

Reply

Glad to hear it.
I'm in progress learning the Doctrine, Symfony 6 & the Database course and getting better and better at understanding how to work with symfony.

You all SFCASTS team are rock!

Reply

Hey Joshua,

Thank you for your kind feedback! It's great to hear our tutorials are really useful for you :)

Cheers!

Reply
Diana E. Avatar
Diana E. Avatar Diana E. | posted 1 year ago

Hi,

Can I follow this course now or is it outdated/won't work with Symfony anymore?

Reply

Hello Diana E.

The fundamental ideas are still works, but some code and configuration will differ from actual PHPUnit and Symfony version. It's not too critical but you may get some issues with it.

BTW remember that we can help you with any issue in courses =)

Cheers!

Reply
Lijana Z. Avatar
Lijana Z. Avatar Lijana Z. | posted 3 years ago

Hello, I had discussion with one guy and he says he uses mostly stubs instead of mocks because stubs do not break tests so much when things change. I am now researching more info on this. But you could make a video about this.
I argue that I need to test that method was called for example once with specific arguments. Otherwise test should fail. He says I should do that with with return values. Like if method is called with X argument, it should return Y, if method is called with A argument, it should return B, and then I assert return value and so I know that method has been called with right arguments. And only test that that method is called with right argument when the method does not return values.

I am not sure if that will be beneficial because I am not sure if readability will become worse. But if lets say we change tested method name or class name, the test will break anyway. So where is the benefit? Plus when you read the test - there will be arguments and return values - and will this be readable when intention will be to check if the right method is called with right arguments.

Reply

Hey Lijana Z.!

That's an excellent conversation ;). I'm somewhere in the middle. What your friend is saying is VERY fair: by using mocks, you're really asserting how the "internal" of the function works. And, in theory, all you should *really* be worrying about is: if I pass argument A, I get return value B. You shouldn't - in theory - care at all *how* the function works internally. That's why, yes, using mocks will cause your tests to fail more often unnecessarily. For example, you might do some innocent refactoring of a method (where you don't change how it actually works) and your test breaks because you now call a method 1 time instead of 2.

So, I typically avoid mocks... until they're useful ;). For example, if I call a method and *one* of the things it does is save something to the database with Doctrine... and it's *critically* important that this is actually saved, I *will* assert that persist() and flush() were called. There's not really a nice way to assert that based on some return value.

All a long way of saying: your friend definitely has a point, and it's really cool to think critically about trying to test what you need to, but also try not "over-managing" *exactly* how a function is doing its job. But, at the end of the day, if you avoid using mocks, and you're still scared that your method might not be working correctly (what if I forget to persist() & flush()???), then mock. That's just my pragmatic view of things :).

Cheers!

Reply

Hey Chmlls,

Good catch! Looks like this course wasn't added to any track, so it's our fault. We'll fix it soon. However, you can find ALL courses even those that mistakenly were not added to any track here: https://symfonycasts.com/co...

Cheers!

Reply
Pierpaolo D. Avatar
Pierpaolo D. Avatar Pierpaolo D. | victor | posted 4 years ago

Just came here after noticing a link in the Design Pattern course thread.

25 Reply
Wils I. Avatar
Wils I. Avatar Wils I. | posted 4 years ago

Hi Ryan! When will the PHPUnit tutorial come out? Because it's just what I've been waiting for to improve my superpowers ;)

Reply

Yo Wils I.!

Haha, well then I have good news :). We will finish our Ansistrano tutorial (over the next couple of weeks) and then PHPUnit will be right after that. So, I expect it to start being released this month!

Cheers!

2 Reply
Wils I. Avatar
Wils I. Avatar Wils I. | weaverryan | posted 4 years ago | edited

Great! Thanks weaverryan!

Reply
Lijana Z. Avatar
Lijana Z. Avatar Lijana Z. | posted 4 years ago

good that there is a feature to run videos 1.25x or faster, using it really often :) without it, when you know lot of things, it would be boring waste of time. But I watch those at fast speed, maybe I will notice something what I do not know.

Reply

That's exactly why we have that feature :). Everyone has different knowledge and different English mastery. I also watch in fast forward on other sites too sometimes ;)

1 Reply

Once again you have created a wonderful tutorial that I enjoyed very much! Thank you and I love the humor.

Reply
Default user avatar
Default user avatar Andriy Frankevych | posted 4 years ago

Yes! Just in time, I was waiting for this <3

Reply
Default user avatar

Hi, This is really what I need. let me be the first to ask the usual question :)
any ETA yet?

Reply

Haha "the usual question" :). Yes indeed! I hope over the next few months we'll start to be able to give concrete estimates very early on - our process is actually quite solid and predictable these days (woo!).

Cheers!

1 Reply

Hey Mehdi,

Sorry, we don't have any ETA because this course is on early planning stage yet, but you can track it here: https://knpuniversity.com/c... or press "Notify me when course is available" and we'll email you ;)

Cheers!

Reply
Default user avatar

I would give a rough guess that it should be published 1-3 months before the year ends (it's right now in coding stages), but there always might be some unplanned issues delaying it.

1 Reply
Default user avatar

Is this course for absolute beginner ? I never tested my code before. Are you guys using any PHP framework ?

Reply

Hey Irfan
If you mean beginner to testing, then yes :)
This course is not that complex, but at least you need to be familiar with PHP and OO concepts
To your question "Are you guys using any PHP framework?", yes, we show you how to test with PHPUnit, it's a very good open source framework, and actually we use it here in KnpU.

Cheers!

Reply
Default user avatar
Default user avatar Irfan | MolloKhan | posted 4 years ago | edited

Hey MolloKhan
Thank you very much for your reply. I am familiar with OOPHP but I never wrote automated test and secondly, I am not familiar with Symfony. I used Laravel few times for small projects. Having said, Do you think its a good idea to take this course ? Thanks in advance :)

Reply

Hi again Irfan!

Yep, this course is for you: the PHP dev who hasn't tested before. We *do* use Symfony in this tutorial. But, for many parts of it, it's not relevant. Unit testing is done the exact same way regardless of your framework. This is true because unit tests don't even touch your framework or know that it exists :). Later in the tutorial, when we talk about integration tests and functional tests, these *do* interact with your framework, and are Symfony-specific (though, the concepts apply to any framework).

So, based on what you've told me so far, if you're excited to learn about testing, I think (hope) that you'll learn a ton with this tutorial :).

Cheers!

Reply
Default user avatar
Default user avatar toporovvv | posted 4 years ago

Thank you for a wonderful course. One of the best on KnpU.

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!