POSTED IN TESTING, BLOG

How to add PSR-2 code check as unit test

Who is this article for?

This article is for developers who are looking to add PSR-2 code check to their project.

Before You Begin

I am going to assume you know what PSR-2 coding style entails. If you are not fully aware of what PSR-2 is, please take time and read about it.

Below are some good reads -

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Refactoring: Improving the Design of Existing Code, 1999. Martin Fowler.

Now that you have a basic understanding of what PSR-2 is, let's jump into implementing it. We are going to implement it as a Unit test called CodeStyleLinterTest.

Step 1 - Install Required Packages

PHP-CS-Fixer

This tool will verify your coding standards as defined in the PSR-1, PSR-2, etc., or other community-driven ones like the Symfony one. You can also define your (team's) style through configuration. You can read all about the package here - https://github.com/FriendsOfPHP/PHP-CS-Fixer. It even allows you to create custom rule-based on your requirements. Ok, so let's install it now to our PHP project

composer require friendsofphp/php-cs-fixer --dev

The Process Component

The Process component executes commands in sub-processes. You can also use exec() but for security reason, I would recommend using the process component package.

composer require symfony/process  --dev

As I am going to use these two packages only for my development purposes only, I have added them as dev dependencies of my composer.json.

Step 2 - The Unit Test Case

Script

<?php

namespace Tests\Unit;

use Symfony\Component\Process\Process;
use function base_path;
use Tests\TestCase;

class CodeStyleLinterTest extends TestCase
{
    // Add more path to test
    const PATH_TO_TEST = [
        'app',
        'config',
        'public/index.php',
        'tests',
        'database'
    ];
    
    /** @test */
    public function psr2()
    {
        $phpCsFixerPath = base_path('vendor/bin/php-cs-fixer');
        // Let's check PSR-2 compliance for our code
        foreach (self::PATH_TO_TEST as $path) {
            $fullPath = base_path($path);
            // Run linter in dry-run mode so it changes nothing.
            $process = new Process([$phpCsFixerPath, 'fix', $fullPath, '--dry-run', '--allow-risky=no']);
            $process->run();
            // Exit code should be 0, else there is a problem with the PSR-2 compliance
            $this->assertEquals(
                0,
                $process->getExitCode(),
                $process->getOutput()
            );
        }
    }
}

I created this unit test for my laravel app, but you can use it for any PHP project. You can update the PATH_TO_TEST constant to include your directories or files you want to run the PSR-2 code check.

Conclusion

Having a simple PSR-2 does not ensure code quality; it only makes the code look pretty i.e., formatting. You should conduct regular code review session to go over your code.

Sources