logo
Ask your Symfony questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$40
Symfony 1.4, Doctrine, Wamp - How to speed up PHPUnit?

Hi,

Running Wampserver 2.0 on local machine, Symfony 1.4, Doctrine and PHPUnit 3.5.5 / sfPHPUnit2Plugin.

Very simple test is taking 1 minute to run on my machine. A slightly longer test, 33 minutes (this runs in 4 seconds on a colleague's machine).

Happy to pay $40 to the person who can point out what's wrong and why it's taking so long.

If you need my phpinfo / ini files etc, no problem, just let me know what you need.

Many Thanks in advance.

darren13 | 12/07/10 at 2:25am Edit
Tutorial: How to assign prize money


The experts have suggested, on average, a prize of $40 for this question.

(5) Possible Answers Submitted...

See a chronological view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    12/07/10
    2:37am
    Jimish Gamit says:

    Well, PHPUnit CodeCoverage is pretty nice and exports some nice HTML files to take a look into. However, a project most often contains more than just PHP files and for a symfony project this could be the phpunit.xml.dist. It removes all folders from your coverage report, that most likely are not your stuff. This one is based on the shipped file of sfPHPUnit2Plugin. The relevant part is the <filter> section.


    <phpunit
    colors="true"
    convertErrorsToExceptions="true"
    convertNoticesToExceptions="true"
    convertWarningsToExceptions="true"
    stopOnFailure="true">

    <filter>
    <blacklist>
    <directory>cache</directory>
    <directory>data</directory>
    <directory>log</directory>
    <directory>lib/vendor</directory>
    <directory>plugins</directory>
    <directory>web</directory>
    </blacklist>
    </filter>

    <testsuites>
    <testsuite name="Unit Tests">
    <directory>test/phpunit/unit/</directory>
    </testsuite>
    <testsuite name="Functional Tests">
    <directory>test/phpunit/functional/</directory>
    </testsuite>
    </testsuites>
    </phpunit>


    Source:http://toni.uebernickel.info/development/speed-up-phpunit-codecoverage-in-symfony-projects/

    Previous versions of this answer: 12/07/10 at 2:36am | 12/07/10 at 2:37am

    • 12/07/10 2:56am

      darren13 says:

      Hi Jimish,

      Thanks for reply.

      I've got plugins/sfPHPUnit2Plugin/data/phpunit.xml.dist.tpl

      <phpunit
      colors="true"
      convertErrorsToExceptions="true"
      convertNoticesToExceptions="true"
      convertWarningsToExceptions="true"
      stopOnFailure="true">

      <testsuites>
      <testsuite name="Unit Tests">
      <directory>test/phpunit/unit/</directory>
      </testsuite>
      <testsuite name="Functional Tests">
      <directory>test/phpunit/functional/</directory>
      </testsuite>
      </testsuites>
      </phpunit>


      but no phpunit.xml.dist anywhere in project.

      I inserted the blacklist code you gave to this file, but still tests taking long time.

      Maybe there is a problem with sfPHPUnit2Plugin?

      Can I copy/rename the above file to the 'correct' directory if this is not the right one?

      Thanks,
      Darren.

  • avatar
    Last edited:
    12/07/10
    2:51am
    Wojciech Sznapka says:

    Try to load model and fixtures to sqlite memory. In bootstrap file you can do (remember to define ROOT_DIR and TEST_DIR vars):

    Doctrine::createTablesFromModels(sprintf("%s/lib/model", $ROOT_DIR));
    Doctrine::loadData(sprintf("%s/fixtures", $TEST_DIR));

    and put this to the databases.yml:

    test:
    doctrine:
    class: sfDoctrineDatabase
    param:
    dsn: 'sqlite::memory:'

    It should be way faster.

  • avatar
    Last edited:
    12/07/10
    4:35am
    Christian Schaefer says:

    Hi Darren,

    you told me that on linux your tests run just nicely and the performance drop only occurs on windows. If that is still the case you need to show us one of your tests to get an idea of what you're trying to do.

    Other than that the above mentioned things apply.

    Cheers
    /Christian

    • 12/07/10 4:45am

      darren13 says:

      Hi Christian,

      I'm not sure actually if it's a Linux box that it's running fine on - I'll ask my colleague, who's on the other side of the world and not available atm.

      But on our Dev web server, this test below takes 14 minutes. On my Windows/Wamp setup, 1 minute. On my colleague's machine, 4 seconds for a much longer test.

      (this test comes back OK when it eventually comes back)

      <?php

      require_once dirname(__FILE__) . '/../../bootstrap/functional.php';

      class LoginTest extends sfPHPUnitBaseFunctionalTestCase {

      protected function getApplication() {
      return 'backend';
      }

      public function testLoginSimple() {
      $browser = $this->getBrowser();

      // DR Rewriting to test Backend Homepage Login.
      $browser->info('1 = The Client Homepage')->
      info(' 1.1 - Get index')->
      get('/')->
      with('request')->begin()->
      end()->

      //###############################################
      // DR Test Login Fails with Invalid Login

      with('form')->begin()->
      info(' 1.2 Submit Incorrect Login')->
      click('Login', array(
      'signin' => array(
      'username' => 'norbert123456789',
      'password' => 'merrigoround')))->
      end()->

      with('response')->begin()->
      info(' 1.3 Check login failed with incorrect details')->
      checkElement('ul.error_list:contains("The username and/or password is invalid")', true)->
      end()->

      //###############################################
      // DR Test Login Fails with No Login Details, but a valid Password
      with('form')->begin()->
      info(' 1.4 Submit No Login, correct Password')->
      click('Login', array(
      'signin' => array(
      'username' => '',
      'password' => '******')))->
      end()->

      with('response')->begin()->
      info(' 1.5 Check login failed with no user, correct password')->
      checkElement('body:contains("Username")', true)->
      checkElement('body:contains("Password")', true)->
      end()->

      //###############################################
      // DR Test Login Fails with No Login or Password Details

      with('form')->begin()->
      //checkElement('body:contains("Login")', true)->
      info(' 1.6 Submit No Login or Password')->
      click('Login', array(
      'signin' => array(
      'username' => '',
      'password' => '')))->
      end()->

      with('response')->begin()->
      info(' 1.7 Check login failed with no user or pass')->
      checkElement('body:contains("Username")', true)->
      checkElement('body:contains("Password")', true)->
      end()->

      //#####################################################
      //DR Check Login fields are present

      get('/')->
      with('response')->begin()->
      info(' 1.8 Check Login fields are present')->
      checkElement('body:contains("Username")', true)->
      checkElement('body:contains("Dashboard")', false)->
      checkElement('input #signin_username', true)->
      checkElement('input #signin_password', true)->
      end()->

      //#####################################################
      // DR Test Login Works with Valid Login

      get('/')->

      with('form')->begin()->
      info(' 1.9 Submit Correct Login')->
      click('Login', array(
      'signin' => array(
      'username' => '********',
      'password' => '********')))->
      end()->

      // Form should have no errors with correct login details:
      with('form')->begin()->
      hasErrors(false)->
      end()->

      //Go to
      get('/')->
      //DR Check Homepage Title and Nav Links is present
      with('response')->begin()->
      info(' 2.0 Check Dashboard fields are present')->
      checkElement('body:contains("Homepage")', true)->
      checkElement('#accordion ul:contains("Dashboard")', true)->
      checkElement('#accordion ul:contains("View Candidates")', true)->
      checkElement('#accordion ul:contains("View Clients")', true)->
      checkElement('#accordion ul:contains("Contacts")', true)->
      checkElement('#accordion ul:contains("Manage Jobs")', true)->
      checkElement('#accordion ul:contains("Migration")', true)->
      checkElement('#accordion ul:contains("Marketing")', true)->
      checkElement('#accordion ul:contains("Web Tools")', true)->
      checkElement('#accordion ul:contains("Check your mail")', true)->
      checkElement('#accordion ul:contains("Settings")', true)->
      checkElement('#accordion ul:contains("Logout")', true)->
      end()->

      //DR check Logout works
      get('/user/logout')->
      with('response')->begin()->
      info(' 2.1 Logout ')->
      end()->

      get('/')->
      with('response')->begin()->
      info(' 2.3 Check homepage is back to Login screen')->
      checkElement('body:contains("Username")', true)->
      checkElement('body:contains("Password")', true)->
      end()


      ;
      }

      }

    • 12/07/10 5:02am

      Christian Schaefer says:

      ah ok so you are wrapping a lime functional test inside a phpunit test. thats fine.
      but it also explains why this takes longer than a few seconds. functional tests will always take longer than unit tests as they test from the outside and all the framework needs to boot up.

      the test itself looks good enough for me but it implies the question: do you test against a live database or a test one?

  • avatar
    Last edited:
    12/07/10
    11:22am
    Nate Flink says:

    This sounds like a problem with the environment. Here are some things I would look at. Have you checked the basic stuff like php.ini for memory limit. Depending on your set up you might need to check the php cli ini file.

    Can you isolate where the choke point is occurring? Do you have logs to look at this, maybe comparing time stamps?

    It sort of sounds like maybe the query is taking a long time. Are the databases on both machines the same?

    Are the PEAR implementations on both machines the same version?

    Are the environment PATH variables set up correctly on the windows machine?




  • avatar
    Last edited:
    12/16/10
    2:30am
    Florian Klein says:

    To check where your script is taking too much time, you can use Xdebug and KCacheGrind.

    Just configure xdebug to enable the profiler option.
    It will save in a file the call chains and others infos like time spent on each method.

    This file will be readable by KCacheGrind.

    Here is a sample config for xdebug.ini ( on my distrib: /etc/php5/conf.d/xdebug.ini )


    xdebug.remote_enable=1
    xdebug.remote_handler=dbgp
    xdebug.remote_mode=req
    xdebug.remote_host=127.0.0.1
    xdebug.remote_port=9000
    ; profiler settings
    xdebug.profiler_append=1
    ;xdebug.profiler_append=0
    xdebug.profiler_enable=1
    xdebug.profiler_enable_trigger=1
    xdebug.profiler_output_name = cachegrind.out.%s
    xdebug.profiler_output_dir=/xdebug/



    Wou then just have to (eventually) reboot your apache (if any), and reload your test suite.

    You will see appear a file in /xdebug/cachegrind.out.*, just open it with KCacheGrind or winCacheGrind to see a graphical representation of your memory footprint, call graph or callee graph.





This question has expired.



darren13, darren13 had additional discourse to offer.



Current status of this question: Community pot



Please log in to add additional discourse to this page.





Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.