searbe

    • Edit
    • Delete
    • Tags
    • Autopost

    PHPUnit and Virtualbox / Uncaught exception 'PHPUnit_Framework_Exception'

    Note

    As per the comments for this post (I haven’t had the time to verify):

    Paul Mitchell submitted a patch which solves the issue in the latest versions of Virtualbox Guest Additions – so please try upgrading.

    If that doesn’t work, Theodore Smith suggests that adding this attribute and value to the phpunit tag in your xml configuration will solve the issue:

    testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader"

    Original post

    I’ve been fighting for two evenings trying to get PHPUnit working.

    I have a setup where my LAMP stack runs in VirtualBox, in which I’ve mounted a folder shared with the virtual machine via Virtualboxes “shared folders” feature.

    It seems that there’s a bug with DirectoryIterator; end result is it will point-blank refuse to iterate over files in your shared folder, and when you run your unit tests in the folder “Foo” with the command “phpunit Foo”:

    PHP Fatal error:  Uncaught exception 'PHPUnit_Framework_Exception' with message 'Neither "FooTests.php" nor "FooTests.php" could be opened.' in /usr/share/php/PHPUnit/Util/Skeleton/Test.php:102

    So. You’re going to have to do things the old fashioned way to fix this. Find PHPUnit_Runner_IncludePathTestCollecto (which uses File_Iterator and ultimately reliest on a RecursiveDirectoryIterator) and comment out the following:

    /**
     * @return File_Iterator
     */
    public function collectTests()
    {
        $iterator = File_Iterator_Factory::getFileIterator(
          $this->paths, $this->suffixes, $this->prefixes
        );
    
        if ($this->filterIterator !== NULL) {
            $class    = new ReflectionClass($this->filterIterator);
            $iterator = $class->newInstance($iterator);
        }
    
        return $iterator;
    }

    In its place, insert this code – which does stuff the skanky old fashioned way:

    public function collectTests()
    {
        $tests = array();
    
        foreach ($this->paths as $path) {
            $tests = array_merge($tests, $this->_iterate($path));
        }
    
        return $tests;
    }
    
    protected function _iterate($path)
    {
        $a = array();
        if ($h = opendir($path)) {
            while (false !== ($fname = readdir($h))) {
                $fullPath = $path . '/' . $fname;
    
                if ($fname == '.' || $fname == '..') {
                    continue;
                }
    
                if (is_dir($fullPath)) {
                    $a = array_merge($a, $this->_iterate($fullPath));
                    continue;
                }
    
                foreach ((array) $this->suffixes as $sfx) {
                    if (substr($fname, -strlen($sfx)) == $sfx) {
                        $a[] = $fullPath;
                        continue;
                    }
                }
    
                foreach ((array) $this->prefixes as $pfx) {
                    if (substr($fname, 0, strlen($pfx)) == $pfx) {
                        $a[] = $fullPath;
                        continue;
                    }
                }
            }
            closedir($h);
        }
        return $a;
    }

    Now “phpunit Foo” will correctly iterate through your Foo directory and test your stuff.

    This does need revisiting but for now this quick fix seems to get least get things running.

    • 3 June 2011
    • Views
    • Permalink
    • Favorited 0 Times

    Comments 8 Comments

    Jul 07, 2011
    Vlad Balmos said...
    Having the same problem, unfortunately your solution doesn't work for whole directories because it includes unrelated files, like svn files and others
    Aug 16, 2011
    Paul Mitchell said...
    Upgrading to VirtualBox 4.1.2 + Guest Additions should fix this issue.
    Aug 19, 2011
    mrmre said...
    Paul M. is right. I must admit I was skeptical... but upgrading from VirtualBox 4.1.0 to 4.1.2 (and updating to Guest Additions 4.1.2 in my VM) fixed this problem for me. Thanks, Paul!
    Dec 02, 2011
    Boris said...
    Thank you! You just saved me so much time. I had no idea VirtualBox was causing this problem.
    Jan 25, 2012
    hopeseekr said...
    The real solution, for those who are wondering, is to add this attribute and value to your <phpunit> tag: testSuiteLoaderClass="PHPUnit_Runner_StandardTestSuiteLoader".
    Jan 26, 2012
    Paul Mitchell said...
    @hopeseekr There was a real bug in VirtualBox 4.1.0 Guest Additions. I know because I submitted the patch to fix it. http://article.gmane.org/gmane.comp.emulators.virtualbox.devel/4426
    Jan 26, 2012
    Craig Bendell said...
    To be honest I now use Ubuntu as my primary O/S, prior to that I stopped using vbox guest additions for file sharing & used samba instead... so I haven't been able to verify the fixes and workarounds after the initial "fix" I posted here.

    If setting the loaderclass to PHPUnit_Runner_StandardTestSuiteLoader does cause PHPUnit to use a different strategy (ie, it doesn't use the file iterators), that sounds like the best fix if people are still having the problem. But even better is if guest additions behave properly, which apparently they do, so this whole post is a bit redundant..!

    I'll put a note on the top of the post regarding this though - thanks both for taking the time to comment :)

    Jan 26, 2012
    Paul Mitchell said...
    Happy to help :)

    Leave a Comment

  • Craig Bendell's Posterous

    PHP developer living in Worthing, UK working for D3R. Starting Android / Java development for fun.

  • About Craig Bendell

    PHP developer living in Worthing, UK working for D3R. Starting Android / Java development for fun.

  • Subscribe

    Subscribe to this posterous
    Unsubscribe
    Subscribe via RSS
    You're a contributor here (Edit)
    This is your Space (Edit)
    Follow by email »
    Get the latest updates in your email box automatically.
    Follow on Twitter
  • Follow Me