Writing tests with unknown variables - php

I am trying to use PHPunit to do testing.
One of the tests I am writing requires scanning a directories sub directories for a certain folder.
I want to write a test that checks to make sure it does not fail if the folder does not exist.
The issue is that the directory it scans may or may not have the folder in it. so I am confused as to how I am meant to do this.
One option I could see is to move everything out of the directory, run the assertion, and then move everything back in, but that seems messy to me. What is the best way to do this?

phpunit actually provides a means to mock the filesystem using vfsStream. This is described in the PHPUnit documentation (specifically look at example 10.19 to see how this is used). vfsStream acts as a wrapper for the filesystem.

Related

Preserve unit test generated content?

I am doing some fairly complex unit tests using PHPUnit. In these tests some files are being generated in temp dirs. After test is finished all this get's wiped. Is there a way to say to framework to leave generated content untouched?
There are 2 ways you could achieve this. Without knowing what exactly clears those files, my best bet is to subclass PHPUnit\Framework\TestCase and implement tearDown or tearDownAfterClass there (and have the relevant test cases subclass that instead), or alternatively by using register_shutdown_function in your bootstrap script.
The tearDown/shutdown method could simply rename the temp dir and mkdir a new one so there'll be nothing to clear, but it's still best to not have those files cleared in the first place. If that code sits inside your vendor/ directory, it's still possible to modify those files.

How to generate Tests in tests/ directory in PhpStorm?

PhpStorm has some sort of weird behaviour that is driving me crazy. I've got my project setup to have a source and a test directory. The source directory should be for productive code, while the test directory should contain all the phpunit tests.
In those directories, the folder structure is mirrored - if I have a class \foo\Bar,
then there is
src/foo/Bar.php and test/foo/BarTest.php.
I've marked src/ and test/ as source and test directory in PhpStorm, however, every time I want to create a new test suite for a class, PhpStorm defaults to put the test class into the src/ directory next to the class under test.
It's possible to change that, however it get's more annoying when that same directory in test/ does not exist yet. Instead of creating it, PhpStorm will just reject to create that test suite for me.
Maybe I am misunderstanding the concept behind test management in PhpStorm quite a bit - because it just can't be that bad user experience.
Is there something I am doing wrong, or something that I can configure to make the situation less painful?
You are doing nothing wrong. It just does not work this way -- devs coded it to behave in a way it is right now.
Originally IDE used PHPUnit's ability to generate test classes (back then such functionality was part of actual PHPUnit). Then PHPUnit creator(s) have moved this functionality into separate package (phpunit-skelgen) .. and you had to install it manually/separately. Then devs decided to drop phpunit-skelgen support completely and implemented current implementation (which is also more in line with similar routines in other IDEs built on IDEA platform/technologies supported by those IDEs).
There are quite few tickets about changing such behaviour to the same as you described/desired .. but so far it does not look like it's in their priority list...
https://youtrack.jetbrains.com/issue/WI-2850
https://youtrack.jetbrains.com/issue/WI-24358
https://youtrack.jetbrains.com/issue/WI-21890
Subscribe to those tickets (star/vote/comment) to get notified on progress.
As of release 2016.3 PHPStorm now takes places tests in the specified tests directory, providing exactly what you ask for in your question.

How do you manage the unit test files in projects? do you add them in git?

How do you manage your PHPUnit files in your projects?
Do you add it to your git repository or do you ignore them?
Do you use #assert tag in your PHPdocs codes?
Setup
I'm not using php currently, but I'm working with python unit testing and sphinx documentation in git. We add our tests to git and even have certain requirements on test passing for pushing to the remote devel and master branches (master harder than devel). This assures a bit of code quality (test coverage should also be evaluated, but thats not implemented yet :)).
We have the test files in a separate directory next to the top-level source directory in the directories where they belong to, prefixed with test_, so that the unit testing framework finds them automagically.
For documentation its similar, we just put the sphinx docs files into their own subdirectory (docs), which is in our case an independent git submodule, which might be changed in the future.
Rationale
We want to be able to track changes in the tests, as they should be rare. Frequent changes indicate immature code.
Other team members need access to the tests, otherwise they're useless. If they change code in some places, they must be able to verify it doesn't break anything.
Documentation belongs to the code. In case of python, the code directly contains the documentation. So we have to keep it both together, as the docs are generated from the code.
Having the tests and the docs in the repository allows for automated testing and doc building on the remote server, which gives us instantaneous updated documentation and testing feedback. Also the implementation of “code quality” restrictions based on test results works that way (its actually more a reminder for people to run tests, as code quality cannot be checked with tests without looking at test coverage too). Refs are rejected by the git server if tests do not pass.
We for example require that on master, all tests have to pass or be skipped (sadly, we need skipped, as some tests require OpenGL, which is not available on headless), while on devel its okay if tests just “behave like expected” (i.e. pass, skip or expected failure, no unexpected success, error or failure).
Yes, to keeping them in git. Other conventions I picked up by looking at projects, including phpunit itself. (A look at the doctrine2 example shows it seems to follow the same convention.)
I keep tests in a top-level tests directory. Under that I have meaningfully named subdirectories, usually following the main project directory structure. I have a functional subdirectory for tests that test multiple components together (where applicable).
I create phpunit.xml.dist telling it where to find the tests (and also immediately telling anyone looking at the source code that we use phpunit, and by looking at the xml file they can understand the convention too).
I don't use #assert or the skeleton generator. It feels like a toy feature; you do some typing in one place (your source file) to save some typing in another place (your unit test file). But then you'll expand on the tests in the unit test files (see my next paragraph), maybe even deleting some of the original asserts, and now the #assert entries in the original source file are out of date and misleading to anyone looking at just that code.
You have also lost a lot of power that you end up needing for real-world testing of real-world classes (simplistic BankAccount example, I'm looking at you). No setUp()/tearDown(). No instance variables. No support for all the other built-in assert functions, let alone custom ones. No #depends and #dataProvider.
One more reason against #assert, and for maintaining a separate tests directory tree: I like different people to write the tests and the actual code, where possible. When tests fail it sometimes points to a misunderstanding in the original project specs, by either your coder or your tester. When code and tests live close together it is tempting to change them at the same time. Especially late on a Friday afternoon when you have a date.
We store our tests right with the code files, so developers see the tests to execute, and ensure they change the tests as required. We simply add an extension of .test to the file. This way, we can simply include the original file automatically in each test file, which may then be created with a template. When we release the code, the build process deletes the .test files from all directories.
/application/src/
Foo.php
Foo.php.test
/application/src/CLASS/
FOO_BAR.class
FOO_BAR.class.test
require_once(substr(__FILE__, 0, -5)); // strip '.test' extension

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.

Codeigniter Shared Resources - Opinions Wanted

I run multiple websites all running off of a single installation of CodeIgniter on my server (separate application directories and a single system directory). This has been working fabulously and I don't see any reason to change it at this point.
I find myself writing library classes to extend/override CI all of the time and many times if I find a bug or improve effeciency I have to go back to several websites to make the same adjustments at risk of a typo that breaks one of the websites. Because of this it requires that I change each file and then test that site for bugs.
I have been pondering a solution of using a single libraries directory in a central location and symlinking all of my websites to that central directory. Then when I make a file change it will immediately propagate to all of the downstream websites. It will still require that I test each one for errors, but I won't have to make the changes multiple times. Anything that is specific to a single website will either be a non-shared file (still in the linked directory just not used elsewhere) or can be put in a local helper.
Also, I keep separate 'system' directories by CI version so I can migrate my websites independently if necessary--this central libraries file would be attached to a specific version to reduce possible breaks.
Does anyone see potential issues or pitfalls from taking this approach? Has anyone accomplished this in another direction that I should consider?
Thanks in advance!
I think this actually makes sense :] Go for it. Even on official CodeIgniter page, they mention it's possible.
Also, I don't see one reason why there should be any problem.
Edit: they touch the problem of multiple sites here: http://codeigniter.com/user_guide/general/managing_apps.html
also:
http://codeigniter.com/wiki/Multiple_Applications/
http://www.exclusivetutorials.com/setting-multiple-websites-in-codeigniter-installation/
How to Handle Multiple Projects in CodeIgniter?
http://codeigniter.com/forums/viewthread/56436/
I have a single system directory and separate application directories for my CI apps. In order to share libraries and some view templates between my apps, I have created a "Common" directory, in the same folder as the CI system and with the same structure as a regular app folder and used symlinks, but you can modify the Loader class so that it looks in the Common folder too. My setup looks something like this:
/var/CodeIgniter/
/var/Common/
/var/Common/config/
/var/Common/controllers/
...
/var/Common/libraries/
...
/var/www/someapp/
/var/www/someotherapp/
...
I'm not sure how you handle publishing your sites (assuming you actually do any of that), but I'd look into version control. For example, in SVN you can make external to another svn directory (or file) and then just update the current svn directory which grabs the external file. This approach gains one benefit from the others, which is when you modify the common library, the others aren't immediately affected. This prevents unwanted breaks before you have time to go test all the sites using the common library. You can then just update each site's folder whenever you are ready to test the changes. This is "more work", but it prevents code duplication AND unwanted breaks.
I wrote a MY_Loader to do exactly that.
http://ellislab.com/forums/viewthread/136321/

Categories