Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHPUnit store properties on test class

I'm a beginner with PHPUnit.

This is a sample test class that I've created:

class NewTest extends PHPUnit_Framework_TestCase
{
    protected $foo;

    function testFirst ()
    {
        $this->foo = true;
        $this->assertTrue($this->foo);
    }

    /**
     * @depends testFirst
     */
    function testSecond ()
    {
        $this->assertTrue($this->foo);
    }
}

When testSecond is executed, it throws an error saying "Undefined property NewTest::$foo".

Why does this happen? Does PHPUnit clear new properties after each test execution? Is there a way to set a property in a test so that it will be accessible in other tests of the same test class?

like image 864
mck89 Avatar asked Mar 15 '11 10:03

mck89


2 Answers

You are setting the foo property inside the testFirst() method. PHPUnit will reset the environment between tests/create a new instance of "NewTest" for every test method if they don't have a @depends annotation), so if you want to have foo set to true you have to recreate that state in the dependent test or use the setup() method.

With setup() (docs):

class NewTest extends PHPUnit_Framework_TestCase
{
    protected $foo;
    protected function setup()
    {
        $this->foo = TRUE;
    }
    function testFirst ()
    {
        $this->assertTrue($this->foo);
    }
    /**
     * @depends testFirst
     */
    function testSecond ()
    {
        $this->assertTrue($this->foo);
    }
}

With @depends (docs):

class NewTest extends PHPUnit_Framework_TestCase
{
    protected $foo;
    function testFirst ()
    {
        $this->foo = TRUE;
        $this->assertTrue($this->foo);
        return $this->foo;
    }
    /**
     * @depends testFirst
     */
    function testSecond($foo)
    {
        $this->foo = $foo;
        $this->assertTrue($this->foo);
    }
}

All of the above should pass.

EDIT had to remove the @backupGlobals solution. It was plain wrong.

like image 132
Gordon Avatar answered Oct 05 '22 22:10

Gordon


  • You can use the @depends annotation
  • You can initialize something in the setUp() method

Generally, you want to avoid that one test influences another test. This makes sure the test is clean and always works, instead of in some edge-case which test1 creates.

like image 25
Sjoerd Avatar answered Oct 05 '22 22:10

Sjoerd