Skip to content

Test

Structure

  • Tests should mirror the directory structure of the code they're testing
  • Use descriptive test method names that explain the scenario being tested
  • Use the CoversClass PHPUnit attribute to indicate which classes are being tested
  • Extend Tests\ApplicationTestCase for feature tests (when the Laravel container needed)
  • Extend PHPUnit\Framework\TestCase class for simple unit tests
  • Do not add comments like // Arrange, please separate all AAA blocks by empty lines

Test Data

  • Create minimal data required for the test

  • Minimize usages of setUp() method, prefer private methods instead

  • To test datasets, prefer Data Providers and PHPUnit\Framework\Attributes\TestWith attribute

  • Use Generators for Data Providers. Use string keys for better DX

  • Use PHPUnit attributes like #[PHPUnit\Framework\Attributes\Test], #[Group] instead of PHPDoc annotations (import them)

  • Directly use Factory classes (located at the tests/Factories directory):

    diff
    - User::factory()->make();
    + UserFactory::make();
  • Use createOne() Factory method to create a single Model

  • Start test names from it_

Assertions

  • One assertion per line

    diff
    - $response->assertOk()->assertJsonCount(2);
    + $response->assertOk();
    + $response->assertJsonCount(2);

HTTP Tests

  • Use named routes (if available) or action() helper with controller's FQCN instead of hardcoded URL:

    diff
    - $this->postJson("/api/v1/users/resend-email-verification", [...]);
    + $this->postJson(action(ResendEmeilVerificationController::class), [...]);

    or:

    diff
    - $this->postJson("/api/v1/users/resend-email-verification", [...]);
    + $this->postJson(route("users.resend-email-verification"), [...]);

Literature

  1. Testing tips by Kamil Ruczyński