Skip to content
Advertisement

Setting up PHPunit – PHP CLI is not executing the shell script

I’m in a multi developer program. The other developer installed PHPUnit via composer and successfully is running tests. I took the composer files, ran composer update, but when I try to run the tests, I am receiving this error:

C:ReposProjectTDD>php vendor/bin/phpunit

Output:

dir=$(cd "${0%[/\]*}" > /dev/null; cd "../phpunit/phpunit" && pwd)

if [ -d /proc/cygdrive ]; then
    case $(which php) in
        $(readlink -n /proc/cygdrive)/*)
            # We are in Cygwin using Windows php, so the path must be translated
            dir=$(cygpath -m "$dir");
            ;;
    esac
fi

"${dir}/phpunit" "$@"

This is the content of the phpunit shell script. The shebang first line #!/usr/bin/env sh is not being output, but this is the rest of the file. The problem appears to be that the PHP CLI is not executing the script, just reading it. I can’t figure out how to fix that.

I am on a windows environment, and I am not running apache locally.

Things I have tried:

  • I have tried using full paths (eg, C:/php/php.exe) for both the php and the shell script, and that didn’t matter.
  • I have tried reversing the slashes vendorbinphpunit
  • I can run php -v successfully, but php -f vendor/bin/phpunit still just outputs the file contents.
  • I have confirmed the PATH for php is accurate and restarted.
  • All expected vendor files do appear to be present.
  • Composer update is not throwing errors of any kind.
  • I’ve changed my terminal / CLI processor to use powershell instead of the default cmd.exe (same result as above)
  • I’ve confirmed encoding of the phpunit file is UTF-8 without BOM
  • I’ve tried making the php command execute the phpunit script in powershell and git bash directly with no luck — it outputs the shell file. It seems to be that php is just not executing it, which makes me think there is a problem with my php.ini or something.
  • I CAN run the phpunit shell directly, such as phpunit --version, but I can’t get it to run my tests.
  • I set the composer platform to match my cli php -v
  "config": {
    "platform": {
      "php": "7.4.20"
    }
  }

Edit: Interestingly, I uploaded it all to my LAMP webserver and ran the same script there, and it is not executing there either. It’s outputting the files…

Advertisement

Answer

There is a lot of stuff you’re fiddling with while trouble-shooting your issue, so there can be only giving extended comments on it. Take it with a grain of salt and pick the pieces that make sense to you, it looks to me you’re clever and should be close to the point where you connect the dots more soon than later (don’t give up):


C:ReposProjectTDD>php vendor/bin/phpunit

This on your windows shell prompt command the php binary to execute the (php) script vendor/bin/phpunit.

And PHP does exactly this (everything else would be a surprise, right?), it executes that script.

The output you see confirms it. As php is the PHP CLI SAPI (PHP Command Line Binary), the first line starting with # is not output (you can find this behaviour described in the PHP documentation as well: https://www.php.net/manual/en/features.commandline.usage.php and on antoher place that I can’t find right now that exactly describes this difference to the common mode https://www.php.net/manual/en/language.basic-syntax.phpmode.php).

You then correctly analyze:

This is the content of the phpunit shell script.

and make the note on the shebang line:

#!/usr/bin/env sh

So this looks to me that this shell script vendor/bin/phpunit is not to be executed with the given commandline:

php vendor/bin/phpunit

but instead just by:

C:ReposProjectTDD>vendor/bin/phpunit

Which won’t (or might not) work on your windows system.

Some more background information (this applies to phpunit bin-stubs as well as other when installed as composer(1) dependencies):

  • composer manages these scripts (for you)
  • composer handles them for POSIX compatible systems as well as for others (compare the /usr/bin/env sh which is stupid, it’s /bin/sh, always, may need a report on the composer project) incl. windows or windows with cygwin or WSL running on Windows, Vagrant box setups etc. pp. (yes they really care since years).
  • composer handles this at the time of install/update.
  • for windows (which I can’t compare are not using it but from what I remember) composer is adding .bat or .cmd files next to the commands (as that is how Windows handles executables).

So mabye using:

C:ReposProjectTDD>composer exec phpunit

already solves your invocation problem.

Or

C:ReposProjectTDD>vendorbinphpunit.bat

Or

C:ReposProjectTDD>vendorbinphpunit.cmd

Or

C:ReposProjectTDD>vendorbinphpunit

does. Point in case is this: https://getcomposer.org/doc/articles/vendor-binaries.md


All in all this looks to me you got instructions from one developer working on a unixoide sytem (Mac, Linux) and you’re running on Windows. This should not pose a problem on that level, however the onboarding in your team might be low or it’s just the knowledge management (unfortunately after a decade or more of Stackoverflow this got worse) and you’ve been left alone with the trouble shooting.

It’s not a programming problem, but merely getting the tooling to run.

Perhaps there is some regime about composer and running it which prevents you from looking there first. But this is hard to say on Stackoverflow.

I’d start fresh with the project, remove it from disk and install it anew. This must work, always. To not sink the current project you can do this a-new in a second directory (the project might support composer create-project to give it a quick start – that is cloning new and doing the composer install).

Similar it is that you could do a composer update in the existing project (which is intended to modify it and depending on how well the project you work with is integrated with composer and your development platform will enable or break things).

At the end of the day the common workflow is:

> rmdir vendor

(remove the vendor directory, that is the blank slate)

> composer install

(install the vendor directory, that is all PHP dependencies of the project)

> composer exec phpunit

(execute the phpunit test-runner)


Edit: Interestingly, I uploaded it all to my LAMP webserver and ran the same script there, and it is not executing there either. It’s outputting the files…

Never install phpunit on a webserver system. Run it in development or CI, but not on the webserver. Period. (this has security implications, and it won’t help you to execute it there, you need to run it where you develop when you’re doing TDD – keep this focus for troubleshooting)


The true path to the PHP script that is represented by vendor/bin/phpunit is:

vendor/sebastianbergmann/phpunit/phpunit

(you can find it in the composer.json of phpunit https://github.com/sebastianbergmann/phpunit/blob/master/composer.json#L66)

Given your original command-line and from the various other information you give, this should work:

php vendor/sebastianbergmann/phpunit/phpunit
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement