In PHPUnit, you can annotate a test-case class (#runTestsInSeparateProcesses) or a test function (#runInSeparateProcess) to run tests in process isolation. There is also a setting in the phpunit.xml config file (processIsolation = "true") to run all tests in separate processes.
I have a group of test-case classes which all inherit from a database-related abstract test class that I need to run in process isolation. But annotations aren't inherited from parent classes. Is there a way for me to mark these test-case classes to run in separate processes by #group, or directory, or some other specifier, without having to mark each test-case class with #runTestsInSeparateProcesses?
No, this is currently not possible. Feel free to open a feature request.
Related
I have more than 1000s of unit tests for my application and it takes hour to run the test and get the results. how do we configure to run phpunit to run all only those testcases that has dependency / impact of the current change.
E.g if I change a method in the class A and this method is called in one of the method of Class B. I have Unit tests written for class A, B & C. I want to execute only testcases for class A's method that has been changed and class's B method that has called it.
Edit: I'm using Jenkins to automatically test the code ,how will my phpunit know what has been changed so it will trigger the phpunit for impacted code change.
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.
I'm trying to set up a testing suite for my Symfony 3 app, and I'm wondering what the correct method for setting up the test database is. I've found this article, but it doesn't actually explain how to add fixtures programmatically.
Also, it appears their example sets up the test database for every test.
Is there a way to setup a test database which is automatically loaded with fixtures when phpunit is run? The official documentation is kind of sparse
Symfony has different environments you can operate in. By default those are prod(production), dev(developement) and test. Although it may not be exactly what you want, you can configure different config, paramaters, routes and so on for each environment. Read the official documentation for more info but yeah, you can setup your parameters.yml file for test mode which could have a different database configured there.
https://symfony.com/doc/current/configuration/environments.html
If you extend your TestCases from KernelTestCase or WebTestCase, basically extend from \PHPUnit_Framework_TestCase you have methods like setUpBeforeClass() or setUp() which are run by PhpUnit before your test/test cases is/are executed.
Use this to e.g. create your fixtures, load your SQL file or whatever and however you might require your prerequisites for your tests.
I have a situation, that all app code comes from one source already compiled and in read only access. I need to run tests, but code that comes to me do not have phpunit installed.
Would it be possible to pass 2 autoloaders to phpunit using phing? One with app dependencies and other with phpunit?
phpunit is a command line program that already comes with it's own autoloading, and it only needs the directory with test classes (applying it's own autodetection/autoloading to them), and a bootstrap script which allows to instantiate all the classes that at some point need to be tested.
So the answer is "yes, expect to be able to use two autoloaders", but there most certainly is no need to fiddle with the autoloader coming with PHPUnit.
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).