PHPUnit TestSuite Exclude - php

so I would like to exclude a directoy from my Testsuite just like this:
<testsuite name="PHPUnitWillKillMe">
<directory>src/*/Bundle/*/*Bundle/Tests</directory>
<exclude>src/*/Bundle/*/*Bundle/Tests/Controller/</exclude>
</testsuite>
Everything except for the Controllers should be tested.
The thing is, it does not work. PHPUnit still runs all the tests in src//Bundle//*Bundle/Tests/Controller/ when I run
phpunit --testsuite PHPUnitWillKillMe
Any idea?
Best Regards!
PHPUnit Version I tested this were 3.7.21 and 3.7.28.

I tested it on my Symfony demo project (the Bundles suggests that this is what you are using) and I have the same issue. It seems to be a combination of two problems. First, there is a known bug with running PHPUnit (PHPUnit 3.7.19) with the -c or --config option:
https://github.com/sebastianbergmann/phpunit/issues/928
When running it elsewhere and specifying the config file using --config, the exclude would however stop working.
Second, the exclude directive seems to ignore / fail when there is any globbing (*) in the path, so by removing the globbing, it worked for me:
<testsuites>
<testsuite name="Project Test Suite">
<directory>../src/*/*Bundle/Tests</directory>
<directory>../src/*/Bundle/*Bundle/Tests</directory>
<exclude>../src/Blah/MyBundle/Tests/Controller/</exclude>
</testsuite>
</testsuites>
It's the only way I found to exclude the Tests in MyBundle as required. The globbing did not work for the exclude. But then, it means you have to add as many exclude directives as there are folders you want to ignore.
Probable related gihub issue:
https://github.com/sebastianbergmann/phpunit/pull/573
[...] this fix lands in the 4.0 release as it breaks backwards compatibility.
Solution #1: remove any globbing in your paths
Solution #2: Upgrade to PHPUnit v4.* (not tested by myself, see comments, doesn't solve the problem of exclude paths with globbing)

Just had similar issue, phpunit has quite nice support for groups:
...
--filter <pattern> Filter which tests to run.
--group ... Only runs tests from the specified group(s).
--exclude-group ... Exclude tests from the specified group(s).
--list-groups List available test groups.
...
What you do is
/**
* #group nonRunnableGroupName
*/
public function testSomething()
{ /* test here */ }
And run test like
$ phpunit -c /src --exclude-group nonRunnableGroupName

Related

How to configure PHPUnit to test the whole vendor folder in a ZF2 application?

I'm developing a Zend Framework 2 application with a common folder structure, so that the folder /vendor contains all (project external) libraries. Setting up the unit testing environment I would like to be able to run all vendor tests. The folders structures are different depending on the library. Some packages have no tests at all.
A possible solution would be to create a test suite "vendor" and manually define there the paths to every single test folder, e.g.:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor/lib-foo/path/to/tests</directory>
<directory>../vendor/package-bar/path/to/tests</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
I don't like this solution. First of all because then I'd have to handle every package manually.
Another solution would be to define /vendor as test folder:
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit ...>
<testsuites>
<testsuite name="vendor">
<directory>../vendor</directory>
...
</testsuite>
...
</testsuites>
...
</phpunit>
Well, but then PHPUnit has to scan a lot of folders, that it doesn't need, and the tests will need much more time.
Is there a better solution, that would make possible to automate the process and avoid much manual configuration?
It would probably be difficult to run all PHPUnit vendor test suites with a single test run. One issue is that each of the different test suites might ship its own configuration file or even require a custom bootstrap configuration file. You cannot cover that when running all test suites with a single command.
I'd probably use some shell magic for this. Note that this example relies on the presence of a phpunit.xml(.dist) file in each of your 3rd party packages (for most libraries that's a reasonable assumption). You could even integrate this into your continuous integration process to test this continuously:
for FILE in $(find . -name 'phpunit.xml*') ; do
sh -c 'cd '$(dirname $FILE)' && composer install'
vendor/bin/phpunit -c $FILE
done

How to run single test method with phpunit?

I am struggling to run a single test method named testSaveAndDrop in the file escalation/EscalationGroupTest.php with phpunit. I tried the following combinations:
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=escalation/EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest.php::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=EscalationGroupTest::testSaveAndDrop
phpunit EscalationGroupTest escalation/EscalationGroupTest.php --filter=testSaveAndDrop
In each case all test methode in the file escalation/EscalationGroupTest.php are executed. How to select just ONE method instead?
The name of the class is EscalationGroupTest and the version of phpunit is 3.2.8.
The following command runs the test on a single method:
phpunit --filter testSaveAndDrop EscalationGroupTest escalation/EscalationGroupTest.php
phpunit --filter methodName ClassName path/to/file.php
For newer versions of phpunit, it is just:
phpunit --filter methodName path/to/file.php
I prefer marking the test in annotation as
/**
* #group failing
* Tests the api edit form
*/
public function testEditAction()
Then running it with
phpunit --group failing
No need to specify the full path in the command line, but you have to remember removing this before commit, not to clutter the code.
You may also specify several groups for a single test
/**
* #group failing
* #group bug2204
*/
public function testSomethingElse()
{
}
Here's the more generic answer:
If you are sure the method name is unique you can only filter by method name (this works for me)
phpunit --filter {TestMethodName}
However it is safer to specify the file path/reference as well
phpunit --filter {TestMethodName} {FilePath}
Example:
phpunit --filter testSaveAndDrop reference/to/escalation/EscalationGroupTest.php
Quick note: I've noticed that if I have a function named testSave and another function named testSaveAndDrop using command phpunit --filter testSave will also run testSaveAndDrop and any other function that starts with testSave*, it's weird!!
Following command will execute exactly testSaveAndDrop test.
phpunit --filter '/::testSaveAndDrop$/' escalation/EscalationGroupTest.php
Run this inside your project root directory i am using in laravel root directory.
vendor/bin/phpunit --filter 'Your method name'
Example with custom method name.
/** #test //Initilize this for custom method name, without test keyword
*
* Test case For Dashboard When User Not logged In it will redirect To login page
*/
public function only_logged_in_user_see_dashboard()
{
$response = $this->get('/dashboard')
->assertRedirect('/login');
}
Example with test keyword
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$this->assertTrue(true);
}
for run phpunit test in laravel by many way ..
vendor/bin/phpunit --filter methodName className pathTofile.php
vendor/bin/phpunit --filter 'namespace\\directoryName\\className::methodName'
for test single class :
vendor/bin/phpunit --filter tests/Feature/UserTest.php
vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest'
vendor/bin/phpunit --filter 'UserTest'
for test single method :
vendor/bin/phpunit --filter testExample
vendor/bin/phpunit --filter 'Tests\\Feature\\UserTest::testExample'
vendor/bin/phpunit --filter testExample UserTest tests/Feature/UserTest.php
for run tests from all class within namespace :
vendor/bin/phpunit --filter 'Tests\\Feature'
for more way run test see more
So, something like this
phpunit --filter 'EscalationGroupTest::testSaveAndDrop' EscalationGroupTest escalation/EscalationGroupTest.php
Without = and with '
https://phpunit.de/manual/3.7/en/textui.html
If you're in netbeans you can right click in the test method and click "Run Focused Test Method".
You Can try this i am able to run single Test cases
phpunit tests/{testfilename}
Eg:
phpunit tests/StackoverflowTest.php
If you want to run single Test cases in Laravel 5.5 Try
vendor/bin/phpunit tests/Feature/{testfilename}
vendor/bin/phpunit tests/Unit/{testfilename}
Eg:
vendor/bin/phpunit tests/Feature/ContactpageTest.php
vendor/bin/phpunit tests/Unit/ContactpageTest.php
The reason your tests are all being run is that you have the --filter flag after the file name. PHPUnit is not reading the options at all and so is running all the test cases.
From the help screen:
Usage: phpunit [options] UnitTest [UnitTest.php]
phpunit [options] <directory>
So move the --filter argument before the test file that you want as mentioned in #Alex and
#Ferid Mövsümov answers. And you should only have the test that you want run.
Given that you
vendor/bin/phpunit --filter=EscalationGroupTest::testSaveAndDrop
If you're using an XML configuration file, you can add the following inside the phpunit tag:
<groups>
<include>
<group>nameToInclude</group>
</include>
<exclude>
<group>nameToExclude</group>
</exclude>
</groups>
See https://phpunit.de/manual/current/en/appendixes.configuration.html
I am late to the party though. But as personal I hate to write the whole line.
Instead, I use the following shortcuts in the .bash_profile file make sure to source .bash_profile the file after adding any new alias else it won't work.
alias pa="php artisan"
alias pu="vendor/bin/phpunit"
alias puf="vendor/bin/phpunit --filter"
Usage:
puf function_name
puf filename
If you use Visual Studio Code you can use the following package to make your tests breeze.
Package Name: Better PHPUnit
Link: https://marketplace.visualstudio.com/items?itemName=calebporzio.better-phpunit
You can then set the keybinding in the settings. I use Command + T binding in my MAC.
Now once you place your cursor on any function and then use the key binding then it will automatically run that single test.
If you need to run the whole class then place the cursor on top of the class and then use the key binding.
If you have any other things then always tweek with the Terminal
Happy Coding!
You must use --filter to run a single test method
php phpunit --filter "/::testMethod( .*)?$/" ClassTest ClassTest.php
The above filter will run testMethod alone.

setting phpunit command from the console symfony

I have already posted this question on php unit first test symfony
I installed phpunit via the composer as a per project installation.
When trying vendor/bin>phpunit -c ../../app every thing is ok and I get a positive answer.
Whereas this command give the answer to all the tests in the tests directory.
But I want the result to every test alone.
When trying /vendor/bin>phpunit -c ../../src/xxx/Bundle/tests/entity/yyy.php and I get the following message : could not load c:\wamp\www\symfony\src/xxx/Bundle/tests/entity/yyy.php Parse PI : PI php never end ... Start ttag expected, '<' not found
and when trying /vendor/bin>phpunit -c ../../src/xxx/Bundle/tests/entity/yyy and I get the following message : could not read "..\..\src/xxx/Bundle/tests/entity/yyy"
Could anybody help me to know how should I write the command and from where execute it???
Any ideas???
Don't use the -c option here. The -c option is a shortcut for --configuration and it points to the directory of a PHPunit configuration file (like app/phpunit.xml.dist). That configuration tells PHPunit where to look for the test classes and some other configuration, like the bootstrap file.
If you want to run tests for a specific test, you can do it like phpunit path/to/tests/MyTest.php. But you'll loose the autoloading then. To get that back, you can use the --bootstrap option to point to the bootstrap file. So it'll be phpunit --bootstrap vendor/autoload.php path/to/tests/MyTest.php.
If you want to run this command more often, you can better edit the app/phpunit.xml.dist file and create a new suite:
<?xml version="1.0" encoding="utf-8" ?>
<phpunit ...>
<!-- ... -->
<testsuites>
<testsuite name="MyBundle">
<file>path/to/tests/MyTest.php</file>
</testsuite>
</testsuites>
<!-- ... -->
</phpunit>
And then run: phpunit -c app --testsuite MyBundle
Happened with me too, but in fact we are misreading the documentation you are forgetting 'app' in the command line look:
phpunit -c app src/AppBundle/Tests/Util/CalculatorTest.php
Note the app parameter in command sentence.

How to run full directories in phpunit?

I have somewhat complex dir structure for my tests.
En example:
unitests
unitests/moduleA
unitests/moduleA/t1.php
unitests/moduleA/t2.php
unitests/moduleA/t3.php
unitests/moduleB
unitests/moduleB/t1.php
unitests/moduleB/t2.php
unitests/moduleB/t3.php
I might have deeper directory structure.
How would I run ALL the tests in one command?
(I tried phpunit unitests/*/* which ran only the first file found unitests/moduleA/t1.php)
You should use a configuration file, it will make things easier to run the tests in the future.
If you create a phpunit.xml file containing :
<phpunit>
<testsuites>
<testsuite name="Unit">
<directory>unitests/*</directory>
</testsuite>
</testsuites>
</phpunit>
and run phpunit, all tests should run.
You should also suffix all your classes with Test.
Also it's not a bad idea to create a test suite per sub-folder.

phpunit does not find any tests with director xml tag, but does with (some) file tags

I have this config:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
backupGlobals = "false"
backupStaticAttributes = "false"
colors = "false"
convertErrorsToExceptions = "true"
convertNoticesToExceptions = "true"
convertWarningsToExceptions = "true"
processIsolation = "false"
stopOnFailure = "false"
stopOnError = "false"
stopOnIncomplete = "false"
syntaxCheck = "false"
bootstrap = "test_bootstrap.php"
>
<testsuites>
<testsuite name="UnitTests">
<file>unit/api/2/ApiControllerTest.php</file>
<file>unit/api/2/RoutesTest.php</file>
</testsuite>
it runs the Test files. If I replace the files with
<directory>unit</directory>
// or
<directory>unit/api/2</directory>
// or
<directory>unit/api/2/*</directory>
// or
<directory>unit/api/2/*Test.php</directory>
// or
<directory suffix="Test.php">unit/api/2</directory>
It simply says: No tests executed!
Please, what could be wrong?
Ubuntu 12.04 LTS, php 5.3.10, phpunit 3.7.16
Where in you path relative to the unit directory is the phpunit.xml file?
if your path looks anything like this:
projectroot
|- phpunit.xml
|- unit/
|- api/
You could try setting the directory to the following in phpunit.xml:
<directory>./unit</directory>
And then run phpunit from root like this: phpunit -c phpunit.xml
If that doesn't work, something else is wrong. What happens if you run this:
phpunit ./unit/api/2
If no tests are being run then, please answer the following questions:
maybe your methods in the testcases don't start with 'test'?
Do all testcase files end with Test.php?
Do all testcase classes extend PHPUnit_Framework_TestCase?
Do all testcase classnames end with 'Test'?
PHPUnit defaults to the suffix Test.php, which isn't obvious.
If your tests use another suffix (e.g. TestUser.php or /test/User.php, instead of UserTest.php), the test will be skipped.
This default can be overwritten using the --test-suffix flag on the CLI:
phpunit --test-suffix _test.php
or with the suffix attribute in the XML configuration:
<include>
<directory suffix="_test.php">src</directory>
</include>
Sources:
PHPUnit: The Command-Line Test Runner
PHPUnit: The XML Configuration File
This might depend a little bit on the version of Phpunit.
I could get it to work with two more older ones (3.7.22 and 3.7.38) but had a similar problem earlier. Here is my solution:
I first had the directory configured wrong:
<testsuites>
<testsuite name="Default">
<directory>/tests</directory>
</testsuite>
</testsuites>
As you can see in this wrong example, it's prefixed with a slash ("/"). Removing that slash results in the following XML excerpt that is working fine then:
<testsuites>
<testsuite name="Default">
<directory>tests</directory>
</testsuite>
</testsuites>
Ensure the directory is not prefixed with a slash and that it exists. The existence part is crucial, because the Phpunit testrunner will not display na error message if it does not exists. You will only see that no tests are executed.
No tests executed!
Taking what you have in your question as an example:
<directory>unit</directory>: It fails because the directory does not exists (you think it does, I know, but it fails if the directory does not exists, Phpunit is not lying to you).
<directory>unit/api/2</directory>: If it fails, it fails because the directory does not exists (you think it does, I know, but it fails if the directory does not exists, Phpunit is not lying to you).
<directory>unit/api/2/*</directory>: This will always fail because the directory does not exists. Most file-systems do not allow to use the "*" character in directory- and file-names.
<directory>unit/api/2/*Test.php</directory>: Same here, this is not a valid directory name, it fails because the directory does not exists.
<directory suffix="Test.php">unit/api/2</directory>: If it fails, it fails because the directory does not exists (you think it does, I know, but it fails if the directory does not exists, Phpunit is not lying to you). Additionally the suffix parameter with the value "Test.php" is superfluous because this is the default suffix. As it is superfluous, this is cruft and you should remove it from the XML file.
No software is without bugs and this naturally applies to Phpunit as well, but you should first of all consider that Phpunit is not lying to you in the first place.
I for myself had not problems with the two versions documented after I corrected the directory configuration. Your mileage may vary. This applies to the points 1, 2 and 5 specifically: From your question it looks like those directories do exist, but from the description you give and what is the Phpunit behaviour I can see, those directories do not exist.
Points 3 and 4 should be clear, they simply do not work because you put wildcards into the directory name which was meant to describe a concrete path not to hint that wildcard usage was intended / allowed. You can find this point outlined as well in a previous Q&A question: Attempting to run Phpunit with a configuration XML file results in exception.
The information in this answer is based on
PHPUnit 3.7.22 and 3.7.38 by Sebastian Bergmann.
PHP 5.4.36 by php.net

Categories