16

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?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
mck89
  • 18,918
  • 16
  • 89
  • 106

2 Answers2

27

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.

Gordon
  • 312,688
  • 75
  • 539
  • 559
  • Note that this can cause a `PHP Fatal error` in recent PHPUnit versions (I don't know exactly since what exact version). You cannot declare `protected function setup()` in that way but you need `protected function setup(): void`. Also, `setup()` is called before every test. So probably the user may need `public static function setUpBeforeClass(): void` that is called only once and at the beginning, and it's not called all the times before every test. https://docs.phpunit.de/en/7.5/fixtures.html?highlight=setup()#variations Also, the link needs an update since it's just the homepage of PHPUnit – Valerio Bozz Mar 16 '23 at 13:47
4

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.

Adrian Günter
  • 903
  • 2
  • 11
  • 23
Sjoerd
  • 74,049
  • 16
  • 131
  • 175