Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Integration testing PHPUnit and Phinx

I'm creating a PHP REST api, using PHPUnit for unit tests and integration tests. I'm looking to integrate phinx for DB migration (instead of building migration code myself).

I have actually two questions:

  • How would I go about using Phinx for my Database setup? Phinx is normally used as a command line tool, but I would need some way to invoke from the setup method in my unit test class.

  • How would I go about integration testing the Migration classes that I write? I would like some kind of verification that after each migration step my database is in some expected state (perhaps including some sample data that should consistent during each migration)

like image 519
dwergkees Avatar asked Aug 16 '14 19:08

dwergkees


2 Answers

Here is a solution.

<?php
use Phinx\Console\PhinxApplication;
use Symfony\Component\Console\Input\StringInput;
use Symfony\Component\Console\Output\NullOutput;
use Phinx\Wrapper\TextWrapper;

class ExampleTest extends TestCase
{

private static $T;

public function setUp(){
    $app = new PhinxApplication();
    $app->setAutoExit(false);
    $app->run(new StringInput(' '), new NullOutput());

    self::$T = new TextWrapper($app);
    self::$T->getMigrate("testing");
}

public function tearDown(){
    self::$T->getRollback("testing");
}

?>

Short and sweet.

like image 96
Jed Lynch Avatar answered Sep 18 '22 17:09

Jed Lynch


Phinx won't automate everything but here's what you can do.

How would I go about using Phinx for my Database setup? Phinx is normally used as a command line tool, but I would need some way to invoke from the setup method in my unit test class.

You can use exec PHP function to run external commands, see the documentation.

How would I go about integration testing the Migration classes that I write? I would like some kind of verification that after each migration step my database is in some expected state (perhaps including some sample data that should consistent during each migration).

This is the harder part. Probably the best approach would be to migrate the database using Phinx prior running the test suites. Passing all tests would automatically verify the migration was a success, given you have the good code coverage. After all the first thing you want to ensure is that the application works from the end user perspective – your functional / integration tests cover exactly that.

The problem with testing something like this is that each migration is different, hence different part of the database would get changed. Tests normally target a very specific area of the code / functionality, so you won't be able to have a simple single test that verifies that migration went well, all that needed to update got updated, and nothing went wrong. If you want to verify that exact changes were applied you'll need to add the new test for each migration and remove redundant tests. The overall approach might be like this:

  1. Save original state sql dumps using a common index (number / data) so that you can find the latest one, like Migration-2014-09-11-22-00.sql.
  2. In the bootstrap import find the latest dump, setup the database with it and apply the migration.
  3. Use a separate migration test case to assert that it went well. You can actually create a separate Migration-2014-09-11-22-00.php, which would contain migration-specific assertions and include it in the testMigration() of the MigrationTest class. There are definitely more that one way of doing this.
  4. The rest of unit and integration tests verify that your app works as expected overall.
like image 43
Ian Bytchek Avatar answered Sep 20 '22 17:09

Ian Bytchek