NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
PHPUnit integration - automated tests


Joined: 27 Apr 2007
Posts: 72
Reply with quote
Usefull script of my daily use. I suggest to attach it to hotkey, mine is CTRL-F5.

In integration:
type: SHELL
command: c:\php\phped\php5\php.exe c:\php\integrationScripts\RunTestsInFile.php
shortcut: Ctrl-F5
Check: Work with editor, take input from editor, whole text, redirect output strem to log window.

Any ideas welcome!

Code:

/**
* This script searches current sources, finds all phpdocs tags @test and
* runs ALL phpunit tests at once. The output of phpunit is reduced
* and for successfull test only 1 line is shown. (Unsuccessfull test output is shown).
* As last line of output you can see overall result of all tests run.
*
* You should set paths to phpunit.bat (in pear directory) and default path
* to your test.
*
* You can use phpdoc tag @testdir to specify location of your test directory
* (without trailing /).
*
* Searches php source for PhpDoc tags @test and @testdir.
* Runs PhpUnit on selected files. Shortens output.
*/

/* Example comment */
/**
*  Please note that this comment can be anywhere in the file.
*  There can be more then one comment.
*
*  @test /relative/path/to/MyPhpUnitTest.php  - default test path will be used
*  @test c:\absolute\path\to\MyPhpUnitTest.php - absolute path
*  @testdir c:\mytests - from now, all relative @test tags are relative to c:\mytests
*  @test /othertest/anotherTest.php   - will run c:\mytests\othertest\anotherTest.php
*/
class TestRunner {

   public $pearCmd  = "c:\\work\\libs\\pear\\phpunit.bat";
   public $testBase = 'c:\\work\\projects\\adastra-nette\\tests';

   //---------------------------------------------------------------------------

   public function run($content)
   {
      $testfiles = $this->getTestFiles($content);

      if (count($testfiles) === 0) {
         echo "No test files found in source!";
         exit(0);
      }

      $overallBadCnt = 0;

      foreach ($testfiles as $testfile) {

         if (!file_exists($testfile)) {
            echo "Test file not found: '$testfile'\n";
            $overallBadCnt++;
            continue;
         }

         //execute test
         $cmdline  = $this->pearCmd . " " . $testfile;
         $lastLine = exec($cmdline, $output, $returnVar);

         if (substr($lastLine, 0, 2) !== 'OK') {
            echo $this->bar($testfile) ."\n";
            $overallBadCnt ++;
            foreach ($output as $ln) {
               if(trim($ln)) {
                  echo $ln . "\n";
               }
            }
            echo $this->bar() ."\n";
         } else {
            echo $lastLine .", Test file: '" . $testfile . "'". "\n";
         }
      }

      if($overallBadCnt>0)
      {
         echo "REPORTED TEST ERRORS!";

      } else {
         if (count($testfiles)>1) {
            echo "ALL " . count($testfiles) . " TESTS PASSED, CONGRATULATIONS!";
         } else {
            echo "TEST PASSED, CONGRATULATIONS!";
         }

      }
   }

   //---------------------------------------------------------------------------

   /**
   * Returns bar with message (optional).
   * @param string $message
   * @param int $len
   * @param string $char
   * @return string
   */
   public function bar($message=NULL, $len=80,$char='=')
   {
      $message = trim($message);
      if (strlen($message) === 0)
         return str_repeat($char,$len);

      echo $llen;
      $llen = ($len - strlen($message)) / 2;
      $message = str_pad(str_repeat($char,$llen) . " " . $message ." ", $len, $char);
      return $message;
   }

   //---------------------------------------------------------------------------
   /**
   * Search for @test and @testdir directives in PhpDoc comments.
   * @param string $contents Php source
   * @return array found test files to run
   */
   public function getTestFiles($contents)
   {
      $tokens = token_get_all($contents);

      $testfiles = array();

      foreach ($tokens as $token)
      {
         if ($token[0] === T_DOC_COMMENT)
         {
            $content = explode("\n",$token[1]);

            foreach ($content as $line) {
               if (preg_match('/\A[\s]*\\*[\s]*@test[\\s]+([\\-\\/\\.\\w\\:\\\]+\\.php)/', $line, $regs)) {
                  $phpfile = $regs[1];
                  $phpfile = str_replace('/','\\',$phpfile);

                  //absolute or relative?
                  if(substr($phpfile,0,1) === '\\') {
                     $testfiles[] = $this->testBase . $phpfile;
                  } else {
                     $testfiles[] = $phpfile;
                  }
               }
               if (preg_match('/\A[\s]*\\*[\s]*@testdir[\\s]+(\\-[\\/:\\\\.\\w]+)/', $line, $regs)) {
                  $this->testBase = $regs[1];
                  $this->testBase = str_replace('/', '\\', $this->testBase);
               }

            }

         }
      }
      $testfiles = array_unique($testfiles);
      return $testfiles;
   }
}

$runner = new TestRunner();
$runner->run(file_get_contents('php://stdin'));



Example of output:
Code:

OK (4 tests, 15 assertions), Test file: 'c:\work\projects\adastra-nette\tests\mybase\model\SimpleObjectStoreTest.php'
OK (3 tests, 38 assertions), Test file: 'c:\work\projects\adastra-nette\tests\mybase\NumericTextInputTest.php'
ALL 2 TESTS PASSED, CONGRATULATIONS!
View user's profileFind all posts by sirjardaSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8344
Reply with quote
What's about Code Coverage analysis?

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
PHPUnit integration - automated tests
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic