Composer scripts see vendor/bin on the path

Scripts in composer.json run with vendor/bin prepended to PATH, so the tools do not need a path prefix — which is why "test": "phpunit" works and the same command in a Makefile does not.

{
    "scripts": {
        "test": "phpunit --colors=always",
        "cs": "phpcs --standard=phpcs.xml src",
        "ci": ["@cs", "@test"]
    }
}

The knock-on effect is that anything spawned by those scripts inherits the path too, so a test that shells out to a project tool finds it. It only applies for the duration of the script; a developer typing phpunit in a terminal still gets whatever is installed globally, which is a common source of “it passes for me” when the global version differs from the locked one.