CodeBlanks Logo Icon CodeBlanks

setUp and tearDown

PHP course · Advanced · Lesson 79/92

Learn the setup and teardown code that runs before and after each test with setUp() and tearDown().

What are setUp and tearDown for?

Many tests share the same setup: a new ShoppingCart, a new User. Instead of copying this code into every test, you write a setUp method. PHPUnit calls setUp automatically before each test; tearDown runs after. setUp builds shared objects (the fixture); tearDown cleans up files or database rows. This keeps tests independent and repeatable.

Test fixture

A fixture is the shared state a test needs: objects, files, database rows. setUp builds them; the test method adds its own changes on top. A good fixture is small and fast. For example, in ShoppingCartTest, setUp creates an empty cart every time; tests then check adding, removing and clearing. If tearDown is not needed, you can skip it; PHPUnit cleans up objects automatically.

Exercise Build a fixture with setUp

Make ShoppingCartTest extend TestCase. Add a setUp method that builds a new ShoppingCart before each test and stores it in the $cart property. In testStartsEmpty check the count is 0 with assertEquals. In testAddIncreasesCount add "Bread" and check the count is 1 with assertEquals.

Show example solution
void { $this->cart = new ShoppingCart(); }. In testStartsEmpty add $this->assertEquals(0, $this->cart->count()). In testAddIncreasesCount add $this->cart->add("Bread"); $this->assertEquals(1, $this->cart->count()).
Example solution:
<?php
// Here we define TestCase ourselves
class TestCase {
    protected function assertEquals($expected, $actual): void {
        if ($expected !== $actual) {
            throw new Exception("Expected $expected, got $actual");
        }
    }
}

class ShoppingCart {
    private array $items = [];
    public function add(string $item): void { $this->items[] = $item; }
    public function count(): int { return count($this->items); }
}

class ShoppingCartTest extends TestCase {
    private ShoppingCart $cart;

    protected function setUp(): void {
        $this->cart = new ShoppingCart();
    }

    public function testStartsEmpty(): void {
        $this->assertEquals(0, $this->cart->count());
    }

    public function testAddIncreasesCount(): void {
        $this->cart->add("Bread");
        $this->assertEquals(1, $this->cart->count());
    }
}

// Run the tests
$test = new ShoppingCartTest();
$test->setUp();
$test->testStartsEmpty();
echo "testStartsEmpty: PASSED\n";
$test->setUp();
$test->testAddIncreasesCount();
echo "testAddIncreasesCount: PASSED\n";

Test yourself

  1. Match the lifecycle

    setUp
    Before each test
    tearDown
    After each test
    testAdd
    Test method
    fixture
    Shared setup
  2. How many times does setUp run in a test class?

    • Once before all tests
    • Once after each test
    • Once before each test
    • Only before the first test
    Show answer

    Once before each test — Correct. setUp runs once before each test; tests do not affect each other.

  3. Complete the setUp method

    <?php
    class CartTest extends TestCase {
        private ShoppingCart $cart;
    
        protected function ____(): void {
            $this->cart = new ShoppingCart();
        }
    }
    
    Show answer
    <?php
    class CartTest extends TestCase {
        private ShoppingCart $cart;
    
        protected function setUp(): void {
            $this->cart = new ShoppingCart();
        }
    }
    

All lessons in Advanced