Use \PHPUnit_Framework_TestCase or ..\TestCase - php

Stupid question... In the Symfony docs, unit test classes extend \PHPUnit_Framework_TestCase but in PHPUnit docs, test classes extend PHPUnit\Framework\TestCase. Is there a difference, are they the same, or am I missing a subtle PHP feature where _ is equivalent to \?
Short of actually testing it out myself, can I use either, or just one in Symfony?
Update: It's been helpfully explained to me that these two classes are just a difference between PHPUnit versions. After my own research and for the record, Symfony 3.1 still extends \PHPUnit_Framework_TestCase in its own KernelTestCase class that powers Symfony's functional testing. To avoid breaking code, I'm going to play safe & extend WebTestCase that inherits from \PHPUnit_Framework_TestCase when unit testing with Symfony specifically. Such unit tests still work with PHPUnit 5.6 anyway

These are the same but since PHPUnit 5.4 it's recommended to use TestCase. However, it's not a problem if you stay with PHPUnit_Framework_TestCase.
See a very similar question: PHPUnit can't found the "TestCase" class

Related

Run phpunit tests by testcase class that they extend

I want to separate my tests in unit and integration tests and have an abstract TestCase class for each, e.g. UnitTestCase and IntegrationTestCase.
Is there a nice way to run only those tests that extend UnitTestCase without giving a #group unit annotation to each of these test classes?
The phpunit documentation is very sparse when describing subclassing. Also a google search didn't turn up any useful results.
No. Either use the #group annotation for this or, better IMO, have a tests/unit directory for unit tests as well as a tests/integration directory for integration tests and then define two test suites in phpunit.xml. By default, both will be run. Using --testsuite you can then filter based on the test suite name.

Is there a way to test Symfony application other than PHPUnit?

During an interview, project manager asked me the following question:
I see in your resume that you are using PHPUnit 4 for tests? Why don't
you use the built-in testing of Symfony?
I answered:
What I know is that Symfony app testing is done via PHPUnit, which is
recommended from the docs of 2.3 and 2.7. I don't know if Symfony3
comes with a testing component!
Was my answer correct? Thanks for the explanations.
Yes, you are correct. Symfony has a WebTestCase (extending the KernelTestCase where you can find that it extends PhpUnit) for functional testing. Additionally Symfony provides a PhpUnitBridge that provides helpful stuff for writing PHPUnit-Tests for a Symfony app, e.g. to make tests fail that use deprecated components. Both rely on PHPUnit and provide additional capabalities on top of "vanilla" phpunit.
There are alternative testing tools, such as phpspec for writing unit tests and Behat for higher level tests (functional and acceptance testing), but both are not used inside Symfony and therefore don't really seem to be what was being asked about.
Additional information to your answer:
In my experience, WebTestCase also bootstrap kernel as static method in all test. Due to that, is not so good to Unit testing by that tool, as this test should be fast. They design this with functional testing controllers and actions but to not need start HTTP server.
Then for:
unit testing, build-in in is not good option
functional testing, it was original intention, but i think, Behat is better solution
system testing - not so good.
Summary, that is why i don't use this tool.

Trait is not being reported as "covered"

I have a problem testing traits. One of my classes uses a trait and implements an interface. Interface methods by the way are being implemented by a trait.
When I run phpunit with coverage report enabled I see that my class is shown as 100% covered, interface is shown as 100% covered, by trait is shown as 0%:
The class uses trait, methods from trait are being called in test suite, but still trait is considered uncovered.
Should traits be tested separately somehow? I know about getMockForTrait() method, but I would like to avoid it. Is there any way to fix the issue and to cover trait by testing the class itself?

How do you find methods in the Zend Framework 2 API

I'm trying to find utility in the Zend Framework 2 API but can't. Maybe I'm not using it right.
For example, following the online documentation for Unit Testing in Zend Framework:
http://framework.zend.com/manual/2.3/en/tutorials/unittesting.html
... I see that a class that extends AbstractHttpControllerTestCase inherits access to $this->getMockBuilder() from somewhere. However I cannot find it in the API documentation for the AbstractHttpControllerTestCase class:
http://framework.zend.com/apidoc/2.3/classes/Zend.Test.PHPUnit.Controller.AbstractHttpControllerTestCase.html
I also don't see a search utility anywhere in the API. How can one know what methods are available to an extension of this class? Dig into the code? Then why publish a partial formal API?
That class extends phpunit test case to provide additional functionality for controller testing.
For PHPUnit_Framework_TestCase usage refer to phpunit documentation
As for how i find methods - i browse code, parent classes and such. Others use their IDE features.

How to actually run PHPUnit tests in a specific order

This question: Run PHPUnit Tests in Certain Order has an accepted answer which I agree with, but the design problem is with PHP and PHPUnit.
The project I'm testing uses ZF2 and Doctrine. The AbstractHttpControllerTestCase has a method "dispatch" which instantiates a ZF2 Application and goes through all the steps of creating the Response object. These tests are annotated with #covers to ensure other methods aren't covered by running requests during a test. The requests may involve view scripts which invoke view helpers which use all sorts of services, so it becomes infeasible to mock all services used during a given request (and this code would become tedious to copy and maintain for each test).
PHPUnit has the ability to run tests in a separate process, it does this by forking a new PHP instance and feeding it compiled code templates (weird stuff). It will then include all files listed by get_included_files(), which includes everything that ever hit the autoloader. Even with preserveGlobalState disabled, it will still include everything that's been touched by all prior tests in the new process.
Some of the dependencies (installed through composer) use static methods, classes marked final or both. Static methods can be mocked by PHPUnit, final classes have to be overloaded using Mockery as PHPUnit will flat out refuse to create mock objects of final classes. Overloading classes and functions (using the namespace trick) must be done in separate processes as to not influence subsequent tests. So far, so good.
Enter a test which overloads a dependency to set expectations on static methods (on a class which may or may not be marked final), or to set expectations on objects which are not yet instantiated. This will only work if none of the prior tests have ever touched the class to overload and set expectations on, or it'll fail with a "cannot redeclare class" error. PHPUnit has tried to be helpful and included everything to recreate the test environment in the subprocess, but as a result ruins the test case.
Therefore, it would be incredibly useful to mark tests with e.g. "#group isolated" and have those tests run before any other tests without having to invoke PHPUnit twice (besides the inconvenience of it, it would ruin coverage analysis).
Alternatively, if there's a way to override a class that already exists in PHP 5.5, that would allow the stricken test case to fix its precondition. But that's probably not going to happen (runkit is not an acceptable answer in any case).

Categories