In addition to unit testing with PHPUnit, I would like to do integration testing where my php test is loaded just like a php page would be with all Apache context available to the test (and the methods being tested).
In JUnit and Spring I would do this by using the AbstractJUnit4SpringContextTests class which would load the application context and make it available to the tests. I don't see a similar concept in the PHPUnit documentation.
If you aren't able to (or don't want to) mock everything necessary to test PHP code, is there a way to run PHPUnit tests through Apache?
As a concrete example, I want to test a method that calls X existing methods, many of which use the _SERVER array or other request-specific variables that I can't mock without a lot of work.
I never try this, but it should work:
public function testSomeMethod()
{
$_SERVER['some-var'] = 'some value';
$x = $this->obj->getSomething();
$this->assertEquals('expected', $x);
}
You can also backup $_SERVER variable and restore it later.
Related
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.
Beginner question here but is it possible to run a PHPSpec test suite that contains tests that make REST calls without actually running a server.
Yes, you can by mocking the service that makes the calls BUT TDD/BDD (and so PHPSpec) are not meant to be used for those kind of test that are integration tests
For those kind of test I would recommend to use something like Behat
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).
Does PHPUnit have functionality (or an external manner) to reflect on the target object, and either fail or markTestIncomplete()'ish on methods which it does not have a test for?
To be clear; this would be in a situation where a test suite exists. A developer adds a new method, but neglects to write a test for it. Currently, it does not affect the unit testing process what-so-ever. I am looking for a way to change this.
Thanks in advance.
PHPUnit can log code coverage data into a file with serialized data, which you can analyze later. This way you can find about untested methods:
$ phpunit --coverage-php coveragedata.ser .
PHPUnit 3.7 itself has no way to fail when classes/methods are untested or when code coverage is below a treshold.
Is there a way to run in-memory database such as hsqldb?
I need it for unit testing. In Java there's no problem with it. But, unfortunately, there is a problem with it in PHP. So, is there a way?
You should be able to use this Perl module to access HSQLDB via PHP
https://metacpan.org/pod/DBD::JDBC
Ideally for unit testing you should be mocking your data access in order to test your components in isolation - so you would use mocks and stubs to remove the dependency on the database in your tests.