Code snippets for symfony 1.x


Refine Tags

Snippets tagged "test"

Unit Test to check the configuration of sending emails in symfony 1.4 (c / SwiftMailer)

 * test/unit/maillerTest.php
 * @author     Gilmar Pupo <>
 *  Unit Test to check the configuration of sending emails in symfony 1.4 (c / SwiftMailer)
require_once dirname(__FILE__).'/../bootstrap/unit.php';
$t = new lime_test(1);
require_once sfConfig::get('sf_symfony_lib_dir').'/vendor/swiftmailer/classes/Swift.php';
$dispatcher = new sfEventDispatcher();
$factories = sfYaml::load(sfConfig::get('sf_root_dir') . '/apps/backend/config/factories.yml');
$mailer = new sfMailer($dispatcher, $factories['all']['mailer']['param']);
$message = Swift_Message::newInstance('Subject test')
  ->setFrom(sfConfig::get('app_contact_emailfrom', ''))
  ->setTo(array('' => 'Gilmar Pupo'))
  ->setBody('Email content');
$numSent = $mailer->send($message);
$t->ok( $numSent > 0 );
by Gilmar Pupo on 2010-09-08, tagged mail  test 

Dump fixtures using Criteria

In case you have a populated database and you need to generate a fixtures for it, you can use symfony propel:data-dump tasks or manually call methods of sfPropelData.

But If your database contains too much data to be fetched, this methods will not work for you.

For such cases I have extended sfPropelData to use Propel Criteria objects to filter dumped data. For example, you can set limit 30 records for every model to prevent dumping all records from database.


You can create special tasks to generate fixtures and use there class listed below

$data = new fxPropelData();
// Defining criterias
$c1 = new Criteria();
$c2 = clone($c1);
// array with models and criterias for them
    $models = array(
      'Fruit'=> $c1,
      'Vegetable' => $c2,
$data->dumpDataWithCriteria(sfConfig::get('sf_data_dir').'/fixtures/food.yml',$models, $options['connection']);

class fxPropelData

class fxPropelData extends sfPropelData {
  public function dumpDataWithCriteria($directoryOrFile, $models = array(), $connectionName = null) {
    $dumpData = $this->getDataWithCriteria($models, $connectionName);
    // save to file(s)
    if (!is_dir($directoryOrFile)) {
      file_put_contents($directoryOrFile, sfYaml::dump($dumpData, 3));
    else {
      $i = 0;
      foreach ($models as $tableName => $criteria) {
        if (!isset($dumpData[$tableName])) {
        file_put_contents(sprintf("%s/%03d-%s.yml", $directoryOrFile, ++$i, $tableName), sfYaml::dump(array($tableName => $dumpData[$tableName]), 3));
  protected function getDataWithCriteria($models, $connectionName = 'propel') {
    $this->con = Propel::getConnection($connectionName);
    $this->dbMap = Propel::getDatabaseMap($connectionName);
    $dumpData = array();
    foreach ($models as $model => $criteria) {
      $tableName = $model;
      $tableMap = $this->dbMap->getTable(constant(constant($tableName.'::PEER').'::TABLE_NAME'));
      $hasParent = false;
      $haveParents = false;
      $fixColumn = null;
      foreach ($tableMap->getColumns() as $column) {
        $col = strtolower($column->getName());
        if ($column->isForeignKey()) {
          $relatedTable = $this->dbMap->getTable($column->getRelatedTableName());
          if ($tableName === $relatedTable->getPhpName()) {
            if ($hasParent) {
              $haveParents = true;
            else {
              $fixColumn = $column;
              $hasParent = true;
      if ($haveParents) {
        // unable to dump tables having multi-recursive references
      // get db info
      $resultsSets = array();
      if ($hasParent) {
        $resultsSets[] = $this->fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $criteria, $tableName, $fixColumn);
      else {
        $stmt = call_user_func(array($tableName.'Peer', 'doSelectStmt'),$criteria,$this->con);
        $resultsSets[] = array_merge($stmt->fetchAll(PDO::FETCH_ASSOC),$resultsSets);
      foreach ($resultsSets as $rows) {
        if(count($rows) > 0) {
          if (!isset($dumpData[$tableName])) $dumpData[$tableName] = array();
          foreach ($rows as $row) {
            $pk = $tableName;
            $values = array();
            $primaryKeys = array();
            $foreignKeys = array();
            foreach ($tableMap->getColumns() as $column) {
              $col = $column->getName();
              $isPrimaryKey = $column->isPrimaryKey();
              if (is_null($row[$col])) {
              if ($isPrimaryKey) {
                $value = $row[$col];
                $pk .= '_'.$value;
                $primaryKeys[$col] = $value;
              if ($column->isForeignKey()) {
                $relatedTable = $this->dbMap->getTable($column->getRelatedTableName());
                if ($isPrimaryKey) {
                  $foreignKeys[$col] = $row[$col];
                  $primaryKeys[$col] = $relatedTable->getPhpName().'_'.$row[$col];
                else {
                  $values[$col] = $relatedTable->getPhpName().'_'.$row[$col];
                  $values[$col] = strlen($row[$col]) ? $relatedTable->getPhpName().'_'.$row[$col] : '';
              elseif (!$isPrimaryKey || ($isPrimaryKey && !$tableMap->isUseIdGenerator())) {
                // We did not want auto incremented primary keys
                $values[$col] = $row[$col];
            if (count($primaryKeys) > 1 || (count($primaryKeys) > 0 && count($foreignKeys) > 0)) {
              $values = array_merge($primaryKeys, $values);
            $dumpData[$tableName][$pk] = $values;
    return $dumpData;
  protected function fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $criteria, $tableName, $column, $in = null)
    is_null($in) ? $criteria->add($column->getName(),NULL) : $criteria->add($column->getName(),$in,Criteria::IN);
    $stmt = call_user_func(array($tableName.'Peer', 'doSelectStmt'),$criteria,$this->con);
    $in = array();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
      $in[] = "'".$row[strtolower($column->getRelatedColumnName())]."'";
      $resultsSets[] = $row;
    if ($in = implode(', ', $in))
      $resultsSets = $this->fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $tableName, $column, $in);
    return $resultsSets;
by Davert on 2009-12-11, tagged creiteria  fixtures  functional  propel  test  unit 

Run all test in plugins and applications

I've been using the following code to run all tests in all plugins and applications.

Create an file with this code like 'run-all-test.php' and execute it in command line 'php run-all-test.php'.

Take a look at SF_ROOT_DIR, set the correct path of your ROOT project.

define( 'SF_ROOT_DIR', dirname(__FILE__).'/../../../..' );
include( SF_ROOT_DIR.'/config/config.php' );
$h = new lime_harness(new lime_output_color());
$h->base_dir = SF_ROOT_DIR;
// unit tests app
$h->register_glob( SF_ROOT_DIR.'/test/unit/*Test.php' );
$h->register_glob( SF_ROOT_DIR.'/test/unit/*/*Test.php' );
// functional tests app
$h->register_glob( SF_ROOT_DIR.'/test/functional/*Test.php');
$h->register_glob( SF_ROOT_DIR.'/test/functional/*/*Test.php');
// unit tests plugin
$h->register_glob( SF_ROOT_DIR.'/plugins/*Plugin/test/unit/*Test.php' );
$h->register_glob( SF_ROOT_DIR.'/plugins/*Plugin/test/unit/*/*Test.php' );
// functional tests plugin
$h->register_glob( SF_ROOT_DIR.'/plugins/*Plugin/test/functional/*Test.php' );
$h->register_glob( SF_ROOT_DIR.'/plugins/*Plugin/test/functional/*/*Test.php' );
by Marco Catunda on 2007-10-24, tagged test 

Unit testing file uploads

A good amount of people have expressed interest in unit testing file uploads. sfTestBrowser does not currently support this but we can use sfWebBrowser instead, as follows (uploadTest.php, to be placed in your unit tests directory):

sfConfig::set('sf_data_dir', dirname(__FILE__).'/../../data');
$file = dirname(__FILE__).'/../fixtures/photos/maine01.jpg';
$invalid_file = dirname(__FILE__).'/../fixtures/photos/';
$t = new lime_test(2, new lime_output_color());
$b = new sfWebBrowser();
$b->post('http://mysite/upload', array(
  'file' => $file
$t->like($b->getResponseText(), '/has been uploaded/', 'file uploads successfully');
$b->post('/upload', array(
  'file' => $invalid_file
$t->like($b->getResponseText(), '/we only allow images/', 'unsupported mime types are not uploaded');

N.B. You must have curl installed for this to work.

by Benjamin Meynell on 2007-09-15, tagged test  upload 

Unit testing with Propel

Even though the book is quite good, the part in which unit testing is explained could use some better information. Especially the testing with a database connection (Propel in this case) needs some fixing.

Below you find an example unit test in which the database is accessed.

It tests a fictional class 'testClass' with the method 'load()'. That method accesses the database ... for which Propel needs to be running. The Symfony application that is loaded is called 'myapp';

if (!@constant('SF_APP')) { // Only load constants in not done before (group tests)
    define('SF_APP', 'myapp');
    define('SF_ENVIRONMENT', 'dev');
    define('SF_DEBUG', TRUE);
if (!@constant('SF_ROOT_DIR')) { // Only load constants in not done before (group tests)
sfCore::initSimpleAutoload(array(SF_ROOT_DIR.'/lib/model' // DB model classes
                                ,$sf_symfony_lib_dir // Symfony itself
                                ,dirname(__FILE__).'/../../lib' // Location class to be tested
                                ,dirname(__FILE__).'/../../apps/stageselect/lib' // Location myapp application
                                ,SF_ROOT_DIR.'/plugins')); // Location plugins
set_include_path($sf_symfony_lib_dir . '/vendor' . PATH_SEPARATOR . SF_ROOT_DIR . PATH_SEPARATOR . get_include_path());
 * Start database connection and Symfony core
sfCore::bootstrap($sf_symfony_lib_dir, $sf_symfony_data_dir);
 * Test
// Init
$oTest = new lime_test(1, new lime_output_color());
// Print head
// Does the method load() exist in class 'testClass'
$oTest->can_ok('testClass', 'load', 'testClass has method load()');
by Jordi Backx on 2007-08-07, tagged database  propel  test  unit 
(1 comment)

Test a validator class

If you create a custom validator, you might want to test it by creating a unit test script.

This is a sample unit test script for testing validators.


$app='frontend'; // Necessary for fonctional boostrap
$context = sfContext::getInstance();
$request = $context->getRequest();
$manager = new sfValidatorManager();
$validator = new myFooBarValidator();
// The values to validate.
// You can make a second array with values
// that are supposed to fail and do another
// loop below.
$values = Array('foo', 'bar');
$t = new lime_test(count($values) * 2, new lime_output_color());
foreach ( $values as $value ) {
  // Re-initialize the validation entry
  // Without this, the first failure would
  // cause any additional validation to
  // be skipped
  $manager->registerName('myname', false);
  $manager->registerValidator('myname', $validator);
  $request->setParameter('myname', $value);
  $retval = $manager->execute();
  $t->is($retval, true);
  $t->is($request->getErrors(), Array());
  // We remove the error so that the next loop
  // does not carry the error.
by Christian Roy on 2007-06-04, tagged test  validator 

Making a specific Pake task quieter

We wanted to use a 'propel-insert-sql' in our acceptance tests suite to clear DB before every test reducing interferences. We all learned here how to call a Pake task from our PHP code. To get a quiet 'propel-insert-sql' task letting 'test' task be verbose and reporting test results we must add a method to the pakeTask class in pakeTask.class.php file:

public function setVerbose() 
  $this-&gt;verbose = false;

and edit sfPakePropel.php file to make 'propel-insert-sql' task quiet:

function run_propel_insert_sql($task, $args)
  _call_phing($task, &#039;insert-sql&#039;);

This way we have a lot quiter acceptance test suite and a clean DB whenever we want.

by Jacopo Romei on 2006-07-31, tagged cli  pake  propel  test 

Selecting test groups from cli

I find boring to wait to run all the tests while I'm focusing on a single one or few ones. Thus I decided to hack pake simpletest task to accept test group selection.

1st step:

In your Pake tasks folder (eg.: /usr/share/pear/pake/tasks) edit the pakeSimpletestTask.class.php file

public static function call_simpletest($task, $type = &#039;text&#039;, $dirs = array(), $test_file = null)

and add this few lines replacing the single line 48

if (!$test_file) {
    $files = pakeFinder::type(&#039;file&#039;)-&gt;name(&#039;*Test.php&#039;)-&gt;in($test_dirs);
else {
    $files = pakeFinder::type(&#039;file&#039;)-&gt;name($test_file)-&gt;in($test_dirs);

This way you are making your pake test task able to accept "hints" about which file to load in the test folder.

2nd step:

Open the sfPakeTest.php file in your symfony/tasks folder and do the following: Add

$test_file = null;
if (count($args) &gt; 1)
    $test_file = $args[1];

at line 14, then change last line into

pakeSimpletestTask::call_simpletest($task, &#039;text&#039;, $dirs_to_test, $test_file);

That's all.

Now you can launch symfony test <app_name> <test_filename> and have this only executed with no loss of time. You can even use wildcards!!! For example: symfont test myportal *ValidatorTest.php It will execute all the tests named with that pattern in your test/myportal folder.

Super confortable testing at last! Test driven programming requires very flexible test groups approach and this could be a small contribution. Hope it helps. Bye!

by Jacopo Romei on 2006-07-10, tagged cli  pake  test  tests 

Use the model in a batch or a test

To use database connections defined in the databases.yml configuration file, you can use the following snippet:

// initialize database manager
$databaseManager = new sfDatabaseManager();
by Fabien Potencier on 2006-05-21, tagged batch  configuration  propel  test