单元测试(Unit testing)

Writing proper tests can assist in writing better software. If you set up proper test cases you can eliminate most functional bugs and better maintain your software.

整合 PHPunit 到 phalcon(Integrating PHPunit with phalcon)

If you don’t already have phpunit installed, you can do it by using the following composer command:

  1. composer require phpunit/phpunit

or by manually adding it to composer.json:

  1. {
  2. "require-dev": {
  3. "phpunit/phpunit": "~4.5"
  4. }
  5. }

Once phpunit is installed create a directory called ‘tests’ in your root directory:

  1. app/
  2. public/
  3. tests/

Next, we need a ‘helper’ file to bootstrap the application for unit testing.

PHPunit 辅助文件(The PHPunit helper file)

A helper file is required to bootstrap the application for running the tests. We have prepared a sample file. Put the file in your tests/ directory as TestHelper.php.

  1. <?php
  2.  
  3. use Phalcon\Di;
  4. use Phalcon\Di\FactoryDefault;
  5.  
  6. ini_set('display_errors',1);
  7. error_reporting(E_ALL);
  8.  
  9. define('ROOT_PATH', __DIR__);
  10. define('PATH_LIBRARY', __DIR__ . '/../app/library/');
  11. define('PATH_SERVICES', __DIR__ . '/../app/services/');
  12. define('PATH_RESOURCES', __DIR__ . '/../app/resources/');
  13.  
  14. set_include_path(
  15. ROOT_PATH . PATH_SEPARATOR . get_include_path()
  16. );
  17.  
  18. // Required for phalcon/incubator
  19. include __DIR__ . "/../vendor/autoload.php";
  20.  
  21. // Use the application autoloader to autoload the classes
  22. // Autoload the dependencies found in composer
  23. $loader = new \Phalcon\Loader();
  24.  
  25. $loader->registerDirs(
  26. array(
  27. ROOT_PATH
  28. )
  29. );
  30.  
  31. $loader->register();
  32.  
  33. $di = new FactoryDefault();
  34. Di::reset();
  35.  
  36. // Add any needed services to the DI here
  37.  
  38. Di::setDefault($di);

Should you need to test any components from your own library, add them to the autoloader or use the autoloader from your main application.

To help you build the unit tests, we made a few abstract classes you can use to bootstrap the unit tests themselves.These files exist in the Phalcon incubator @ https://github.com/phalcon/incubator.

You can use the incubator library by adding it as a dependency:

  1. composer require phalcon/incubator

or by manually adding it to composer.json:

  1. {
  2. "require": {
  3. "phalcon/incubator": "dev-master"
  4. }
  5. }

You can also clone the repository using the repo link above.

PHPunit.xml 文件(PHPunit.xml file)

Now, create a phpunit file:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <phpunit bootstrap="./TestHelper.php"
  3. backupGlobals="false"
  4. backupStaticAttributes="false"
  5. verbose="true"
  6. colors="false"
  7. convertErrorsToExceptions="true"
  8. convertNoticesToExceptions="true"
  9. convertWarningsToExceptions="true"
  10. processIsolation="false"
  11. stopOnFailure="false"
  12. syntaxCheck="true">
  13. <testsuite name="Phalcon - Testsuite">
  14. <directory>./</directory>
  15. </testsuite>
  16. </phpunit>

Modify the phpunit.xml to fit your needs and save it in tests/.

This will run any tests under the tests/ directory.

简单的单元测试(Sample unit test)

To run any unit tests you need to define them. The autoloader will make sure the proper files are loaded so all you need to do is create the files and phpunit will run the tests for you.

This example does not contain a config file, most test cases however, do need one. You can add it to the DI to get the UnitTestCase file.

First create a base unit test called UnitTestCase.php in your /tests directory:

  1. <?php
  2.  
  3. use Phalcon\Di;
  4. use Phalcon\Test\UnitTestCase as PhalconTestCase;
  5.  
  6. abstract class UnitTestCase extends PhalconTestCase
  7. {
  8. /**
  9. * @var \Voice\Cache
  10. */
  11. protected $_cache;
  12.  
  13. /**
  14. * @var \Phalcon\Config
  15. */
  16. protected $_config;
  17.  
  18. /**
  19. * @var bool
  20. */
  21. private $_loaded = false;
  22.  
  23. public function setUp()
  24. {
  25. parent::setUp();
  26.  
  27. // Load any additional services that might be required during testing
  28. $di = Di::getDefault();
  29.  
  30. // Get any DI components here. If you have a config, be sure to pass it to the parent
  31.  
  32. $this->setDi($di);
  33.  
  34. $this->_loaded = true;
  35. }
  36.  
  37. /**
  38. * Check if the test case is setup properly
  39. *
  40. * @throws \PHPUnit_Framework_IncompleteTestError;
  41. */
  42. public function __destruct()
  43. {
  44. if (!$this->_loaded) {
  45. throw new \PHPUnit_Framework_IncompleteTestError('Please run parent::setUp().');
  46. }
  47. }
  48. }

It’s always a good idea to separate your Unit tests in namespaces. For this test we will create the namespace ‘Test’. So create a file called testsTestUnitTest.php:

  1. <?php
  2.  
  3. namespace Test;
  4.  
  5. /**
  6. * Class UnitTest
  7. */
  8. class UnitTest extends \UnitTestCase
  9. {
  10. public function testTestCase()
  11. {
  12. $this->assertEquals('works',
  13. 'works',
  14. 'This is OK'
  15. );
  16.  
  17. $this->assertEquals('works',
  18. 'works1',
  19. 'This will fail'
  20. );
  21. }
  22. }

Now when you execute ‘phpunit’ in your command-line from the tests directory you will get the following output:

  1. $ phpunit
  2. PHPUnit 3.7.23 by Sebastian Bergmann.
  3.  
  4. Configuration read from /private/var/www/tests/phpunit.xml
  5.  
  6. Time: 3 ms, Memory: 3.25Mb
  7.  
  8. There was 1 failure:
  9.  
  10. 1) Test\UnitTest::testTestCase
  11. This will fail
  12. Failed asserting that two strings are equal.
  13. --- Expected
  14. +++ Actual
  15. @@ @@
  16. -'works'
  17. +'works1'
  18.  
  19. /private/var/www/tests/Test/UnitTest.php:25
  20.  
  21. FAILURES!
  22. Tests: 1, Assertions: 2, Failures: 1.

Now you can start building your unit tests. You can view a good guide here (we also recommend reading the PHPunit documentation if you’re not familiar with PHPunit):

http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/

原文: http://www.myleftstudio.com/reference/unit-testing.html