How to bundle PHPUnit with my code? - php

I would like to:
Run tests with PHPUnit regardless of my environment (and if PHPUnit or PEAR is installed or not)
Show test results on screen if possible
How can I do this? I tried downloading the code here and including Autoload.php but it still have some dependencies. Maybe there's some better approach for this than trying to bundle it with my code...?

To include PHPUnit in your projects source files I'd suggest following the guide:
Using PHPUnit From a Git Checkout from the PHPUnit Contributung section.
It tells you about all the packages you need to install and shows you show to build a runner/wrapper script for the phpunit executable.
#!/bin/bash
php -d include_path='.:../phpunit/:../dbunit/:../php-code-coverage/:../php-file-iterator/:../php-invoker/:../php-text-template/:../php-timer:../php-token-stream:../phpunit-mock-objects/:../phpunit-selenium/:../phpunit-story/:/usr/local/lib/php' ../phpunit/phpunit.php $*
You can adapt the path to your need or if you want to wrap it in another script you can also use phpunit somewhat programmatically by
require '/path/to/phpunit/PHPUnit/Autoload.php';
PHPUnit_TextUI_Command::main();
This assumes that you ether have a phpunit.xml.dist file or that you use the proper cli parameters when calling your wrapper script.
You can also use the pear packages and unpack all the stable versions instead of working from the git checkout to save some disk and repo space. The wrapper script and all the include path work is the same :)
Related SO questions:
PHP - Is there a portable version of PHPUnit?
PHPUNIT without installation

The dependencies will be dependent on what add-ons you're using, PHPUnit by itself should be self contained. Since there's no particularly consistent package management solution for PHP (and you've eliminated the most viable options aside from wheel reinvention), your best bet would be to include the files in the source tree separate from the application code. Creating a sibling directory from whatever your APPLICATION_ROOT or similar would be that is named "test" and that has a "lib" or similar directory full of PHPUnit and any dependencies you need for it would likely be a good plan. There should be no overlapping and a one way dependency from the test dir to the main application source.
I'm assuming you're looking for a healthcheck automated test page, so you could create the single page that includes what is needed from that test directory. Ideally if you have the web directory which exposes your static resources you could have the PHP file that is in charge of loading the Front Controller for your application by including the application folder from outside of the document root, and then a second file that loads the test suite. That would allow your application directory to remain focused on the application code itself, the test directory to house your testing code, and then the 2 small include files which are in charge of loading the codebases (with any kind of shared constant definitions, etc. also extracted and kept DRY).

There is a consistent package management solution for PHP - http://getComposer.org. It also now has a means to install PHPunit in the usual composer style, http://packagist.org/packages/phpunit/phpunit
With the software installed, it will put the phpunit command line script into the local 'bin/' directory, so you can call it, though you will likely want to have a shell script that also sets the configuration file it will use.
The usual setup is a tests/ subdirectory with the hierarchy of PHPunit-extending classes that run the actual tests.

Related

Read composer extra config in regular code

Using composer config extra.foo bar I can set custom data in composer.json and according to the documentation composer scripts can read it using $event->getComposer()->getPackage()->getExtra()
I would like to read it in a regular script (installed as a vendor binary) so the binary can be configured by the user, e.g. the binary requires a configuration file which I would like to put in extra.config.
Does composer support this or do I need to manually locate and parse composer.json? Is there a better solution for letting the user add configuration?
The documentation part you are refering to is about PHP-Scripts that get triggered as event-handler during a composer-invocation. So composer runs and provides the configuration-information while invoking the script.
When I understand your approach right, you want to be able to read the information while running your own script without composer. Then - as composer is not involved - composer can not provide any information.
So what you could do is read the composer.json file, parse it as JSON and get the for you relevant information from it.
But then it's nothing else than reading any other configuration file. So I would use a separate file for configuration. That would allow you to use a config also for projects that don't use composer (whyever one would want to do that...). And separation of concerns is also a good idea!
You perhaps might want to have a look at f.e. phpunit, phpcs or travis on how they handle their specific configuration issues within their scripts.

Clean application deployment when using Composer

I have started to use Composer for a new PHP application (it uses a few frameworks and APIs such as Laravel, Smarty etc.) and all is good with it in development.
However, I am not too sure about how do I go about deploying this on a live production server. The sub-directories of the respective modules under the /vendor directory seem to include a lot of stuff which I would not normally include with an app, (such as Demo files, installation readmes, documentation etc.). Is this normal, or is it that the creators of those packages got the wrong idea of how to create a Composer package?
Is there a standard approach to create a clean app deployment that only includes the necessary distribution files and not the rest of the stuff which is not related and should not even be there (even for security reasons)?
I am asking about the most common workflow used, or maybe a specific command or configuration in composer.json I should be looking at to achieve this.
There are two recommendations I'd make which cover most of your worries.
1)
Use composer update --no-dev to prune out any dependencies for development only from your lock file. Or tweak your requirements in composer.json to achieve the same.
In theory the package developers should keep the production version cleaner, (e.g. not including all the phpunit tests). However yes it's pretty normal to have a lot of 'cruft' in the vendor library, mostly because the concept of build is relatively uncommon in PHP, therefore "sources" and "targets" are intermingled.
Demos and readme's are still a necessary part of the 'distribution' version of a component so will still be there if you specify no-dev, which is just to say "I'm not developing this package, I'm just consuming it".
It does feel like there's a missing composer feature: one level above this which is indeed a super-clean deployment minified package.
2)
Keep your vendor library above the web root.
This prevents any unwanted browsing into the vendor library, and removes any security issues of site visitors exploring your libraries (if that's what you were rightfully worried about).
e.g. I typically use
domain
/api
/etc
/vendor
/www
/js
/css
/images
/index.php
/foo
/bar.php
Where www is the virtual-host web root.
All entry-level scripts are in your web root as normal and path to the autoload at ../vendor/autoload.php
Or of course www/ could be the laravel root folder if you're using Laravel for your website as well as api.
api can host a separate vhost for your laravel APIs if they're done separately from a 'flat' website.
(I keep other folders above the web root build, docs, src for SASS, JS, Grunt etc, etc can securely store any config, passwords, keys etc.).
3)
If you're still not happy with the baggage, then as the other commenter suggests, you'd want to look at a build process which cleans things up. This can get complex though and difficult to maintain!
e.g. you could build to a local www deployment folder (i.e. composer update, plus any grunt tasks, bower installs, laravel/artisan publishing etc), then prune it back (custom scripts you'd have to engineer), and commit that into a separate repository representing a published, flattened deployment target. This is what you would deploy to your website.
This would have to be automated or you'd stop doing if after about the third time :)
But... you have to ask why else you'd want to prune back the vendor libs. Disk space? They're not that big. General tidiness? Consider the folders as black boxes and just read the API docs. i.e. don't look :)

Can we use Composer with sparse SVN checkout to share dependencies?

Our current development setup uses a single Subversion repository containing multiple projects, each with branches, tags, and trunk. We then use a "sparse checkout" to select the projects, and branches of those projects, to work with.
The result is that the directory structure of a working copy matches that of the repository, including branch information, and we never use svn switch. (This style of working will probably be familiar to anyone who uses SVN, but may be surprising to those who don't.)
We are thinking of using Composer to manage both external and internal dependencies, but I'm not sure how this can work with the sparse checkout style of working.
I would like some way of using a directory within the existing checkout to satisfy a dependency, rather than each "root project" needing a separate copy.
For example:
sites/Foo/trunk
depends on lib Aaa, so references lib/Aaa/trunk
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
sites/Bar/trunk
depends on lib Aaa 1.0.*, so references lib/Aaa/branches/release-1.0
depends on lib Bbb 1.5.*, so references lib/Bbb/branches/release-1.5
At present, if I edit the code in lib/Bbb/branches/release-1.5, I can test those changes on both sites, without needing to commit one and update the other.
Is there any way of using Composer to manage these dependencies?
(PS: Please don't answer with "give up on SVN, use Git, it is teh awesomez"; that is an answer to a different question.)
No - I do not believe that you can do this with Composer as standard: it expects to copy the files from whichever source (Packagist/VCS/Zips) to the local vendor folder, which is not what you want.
That said, I believe there are two potential ways you could get this working (at least in part):
Autoloader
You could try using the autoload field in the composer.json file to include the correct files into the project. You would still need to manage the checkouts of the relevant branches/versions manually (like I assume you do now), but you would be able to manage the inclusion of the internal libraries through Composer. This will probably require that your libraries are properly namespaced. The paths to the files for each namespace are relative to the root of the project, but can go below the root (via the /../ path) if required.
To be honest though, if you already have an autoloader for these files, there may not be much advantage to this solution. Relevant Docs
Composer Plugin
You could also write a composer plugin/"custom installer" that could probably manage this. This would have the advantage that you could have it manage checking out the correct parts of the sparse repository to have the correct version available, as well as doing correct wildstar version checking, but would be a much more difficult and riskier venture.
The basic process would be that you would define a new package type (e.g. 'internal-svn-package'). You would create the plugin as an external library that gets installed normally via Composer, which declares (via it's composer.json) that it handles this new type of package. Your custom logic would then be used for any packages that are listed with this custom type. I'm not sure how much of the internal composer logic for SVN checkouts you would be able to reuse however. Relevant Docs

Can I package PHPUnit as a phar?

I would like to package PHPUnit and various other test dependencies into a phar and put that into svn. This way I can run phpunit on any client machine without needing pear. Can this be done?
Current status:
Work on a phpunit.phar has started in the phpunit repo but the generated phar is not stable and not feature complete.
If it gets there there will be official releases
Original answer:
If you can I'll give you 500 rep, a 100 Bucks and my first born.. well no.. just the first two.
To be serious:
I've nagged the creator of PHPUnit about this topic on at least 3 conferences now and well.. it doesn't seem like it's possible.
There are a couple of issues with that. First off PHPUnit spawns new php processes for test isolation. The problem with this is that a phar can't tell which php executable called it. So if you start phpunit with a custom compiled version it would use the "default" php installed to spawn the isolated tests.
Secondly as far as i know and have been told it's not possible to put static files like images and css in a phar. Which makes generating code coverage a lot harder. That would require some work on that part.
There are other issues i can't recall exactly recall right having to do with xDebug being able to provide code coverage for phars (and phpunit relying on not generating overage for it's own code and so) and others things.
There once was a phar but from my understanding that just doesn't work out with the current state of phpunit and never really worked completly.
I'm not saying it can't be done just that various people already have given up on creating a phpunit.phar including the guy how develops it. (That is just my impression, i of course can't speak for Sebastian here and might be completely wrong, take this as a little disclaimer)
Putting PHPUnit into SVN
You don't have to build a .phar to do so!
For my company I maintain a svnd version of PHPUnit. It's not the recommended way of using it but it works without much issues!
Follow the "using from a git checkout" instructions on the phpunit github site. You then need to put those files into your php include path and it works.
My suggestion would be to create a custom phpunit.sh that modifies the include path and then calls the original phpunit.sh passing along all arguments. It's a little bit of work but it works quite well and it is a hell of a lot easier than creating a phar archive :)
From the new PHPUnit page:
We distribute a PHP Archive (PHAR) that contains everything you need in order to use PHPUnit. Simply download it from here, make it executable, and put it into your $PATH, for instance......

Why to have "build/" folder with PHP project and phing

What is a benefit of having "build/" folder where all the sources will be placed and "built"?
Maybe it's a silly question, but I'm trying to understand Continuous Integration with PHP. Any example of build.xml for phing uses such build/ folder, but what's a sense in that for PHP where a checked out project doesn't require a compilation, only a basic configuration. Copying it all into build/ will just complicate the things, because you'll have doubled files and +1 folder to the web root path (if you'd like to have web UI to run selenium tests on)
Particularly I need phing for two cases:
1) let new user setup his first installation (or update old), right on a working copy
2) run unit/func-tests, phpcc, phpcs, phpdoc etc (all that usually on CI server)
Should I have "build/" for the second task? What is the best practice for PHP?
There are several good reasons to have a build directory (i.e., deployment to multiple environments, performing some text replacement, minimizing and combining CSS and JS, optimizing images, handling of config files etc.)
However, these may not apply in your use cases. There is no rule saying you need this directory. Depending on your thinking on testing in production, a build directory may be a good reason to keep this directory.

Categories