using version 8.1.6, and Given the following phpunit.xml :
<phpunit bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="SlimSkeleton">
<directory>tests</directory>
<exclude>./tests/Functional/BaseTestCase.php</exclude>
</testsuite>
</testsuites>
</phpunit>
And the following directory structure :
./tests/Functional/serviceA/...
./tests/Functional/BaseTestCase.php
I keep getting the following output :
...
1) Warning
No tests found in class "Tests\Functional\BaseTestCase".
...
I run the suitr via a scripts command in composer.json :
{
...
"scripts": {
"test": "phpunit"
}
}
Is it expected ? Is there a way to silence this warning ?
phpunit by default finds *Test.php, so even without <exclude> in phpunit.xml it would ignore BaseTestCase.php by running composer test.
Using tests instead of tests/EmailTest would instruct the PHPUnit command-line test runner to execute all tests found declared in *Test.php sourcecode files in the tests directory.
https://phpunit.de/getting-started/phpunit-8.html
I see "No tests found" warning if I specify command-line argument like the below. But this is not the intended usage of BaseTestCase.php from Slim-Skelton.
$ composer test tests/Functional/BaseTestCase.php
> phpunit 'tests/Functional/BaseTestCase.php'
PHPUnit 8.1.6 by Sebastian Bergmann and contributors.
W 1 / 1 (100%)
Time: 21 ms, Memory: 4.00 MB
There was 1 warning:
1) Warning
No tests found in class "Tests\Functional\BaseTestCase".
WARNINGS!
Tests: 1, Assertions: 0, Warnings: 1.
Related
I have a lot of problems trying to intall phpunit, maybe my knowledge isn't enought or the guide is very incomplete.
First, the install, I tried all the ways, globally, with "downloaded PHAR file directly" or with "sudo apt-get install phpunit" but when I tried to do:
$phpunit -v
bash: /usr/bin/phpunit: No chuch file or directory
if I do:
$ ll /usr/local/bin (I know, the path is different, other unexplicable event)
-rwxr-xr-x 1 user user 2784899 abr 29 17:09 phpunit*
but
$ sudo phpunit --version
PHPUnit 7.1.5 by Sebastian Bergmann adn contributors.
ok, looks better, so I tried to make the first example
<?php
use PHPUnit\Framework\TestCase;
class StackTest extends TestCase
{
public function testPushAndPop()
{
$stack = [];
$this->assertSame(0, count($stack));
array_push($stack, 'foo');
$this->assertSame('foo', $stack[count($stack)-1]);
$this->assertSame(1, count($stack));
$this->assertSame('foo', array_pop($stack));
$this->assertSame(0, count($stack));
}
}
but it give me the next error:
PHP Fatal error: Class 'PHPUnit\Framework\Testcase' not found in /var/www/html/phpunit/index.php on line 4
I'm using Ubuntu 18 and php 7.2
Any idea?
When you are running PHPUnit from the command line, you also need to include a 'bootstrap' file - it can be as simple as the composer autoload.php file:
phpunit --bootstrap vendor/autoload.php
Longer term, that configuration would be put into the phpunit.xml file so it is read, and run automatically by PHPunit.
<!-- file: phpunit.xml
src/autoload.php would also include the ./vendor/autoload.php file
and do any other locally required setup -->
<phpunit bootstrap="src/autoload.php">
<testsuites>
<testsuite name="money">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>
Ok, I start to understand some things.
First #Sebastian Bergmann give me the clue, with this example, it works.
But if you start with the documentation you never found it. I think it's an error and can confuse a begginer like me.
Yet I can't install phpunit with PHAR or globally, maybe it could be a future new post.
Thanks for all
I am trying to generate code test coverage for my PHP project with PHPUnit and phpdbg using the following command:
phpdbg -dmemory_limit=512M -qrr ./bin/phpunit -c .phpunit.cover.xml
This works perfectly fine:
PHPUnit 6.2.4 by Sebastian Bergmann and contributors.
........ 8 / 8 (100%)
Time: 114 ms, Memory: 14.00MB
OK (8 tests, 13 assertions)
Generating code coverage report in HTML format ... done
However, when I use the exact same command in a docker container:
docker run -it --name YM4UPltmiPMjObaVULwsIPIkPL2bGL0T -e USER=sasan -v "/home/sasan/Project/phpredmin:/phpredmin" -w "/phpredmin" --user "1000:www-data" php:7.0-apache phpdbg -dmemory_limit=512M -qrr ./bin/phpunit -c .phpunit.cover.xml
I get the following error:
PHPUnit 6.2.4 by Sebastian Bergmann and contributors.
[PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 561514763337856 bytes) in /phpredmin/vendor/phpunit/phpunit/src/Util/GlobalState.php on line 166]
I don't understand why PHPUnit needs to allocate 561514763337856 bytes of memory. I suspect it gets stuck in a loop, but why this does not happen outside of the container? Here is my PHP version on my machine:
PHP 7.0.22-0ubuntu0.17.04.1 (cli) (built: Aug 8 2017 22:03:30) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
with Zend OPcache v7.0.22-0ubuntu0.17.04.1, Copyright (c) 1999-2017, by Zend Technologies
And here is the .phpunit.cover.xml file:
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
cacheTokens="false"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnError="true"
stopOnFailure="true"
stopOnIncomplete="false"
stopOnSkipped="false"
stopOnRisky="false"
timeoutForSmallTests="1"
timeoutForMediumTests="10"
timeoutForLargeTests="60"
verbose="false">
<testsuites>
<testsuite name="PhpRedmin PHP source">
<directory>src-test/</directory>
</testsuite>
</testsuites>
<logging>
<log type="coverage-html" target="cover/" lowUpperBound="35"
highLowerBound="70"/>
</logging>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src-test/</directory>
<directory suffix=".php">src/</directory>
</whitelist>
</filter>
</phpunit>
-- Edit1 --
I found that it has something to do with #runInSeparateProcess. When I remove the test that has #runInSeparateProcess then it starts to work. But still I don't know what is the problem
-- Edit2 --
Also I found out that If I don't mount my code directory in the Docker container everything works fine
Add '-d memory_limit=-1' before your test
if use composer use the below code
./vendor/bin/simple-phpunit -d memory_limit=-1 tests/
if you use phpdbg use the below code
phpdbg -d memory_limit=-1 -qrr vendor/bin/phpunit --coverage-text
When we use #runInSeparateProcess, PHPUnit will attempt to serialize included files, ini settings, global variables, and constants to pass them to the new process. In this case, it looks like PHPUnit encountered a recursive scenario when serializing one of these items, which exhausted the memory available to the PHP process. We need to determine what changed between your local environment and the Docker container.
First, we can try disabling this serialization behavior to verify that we should proceed along this path. Add the following #preserveGlobalState annotation to the test method that fails:
/**
* #runInSeparateProcess
* #preserveGlobalState disabled
*/
public function testInSeparateProcess()
{
// ...
}
If this resolves the problem, or if we get a new error, we can begin looking for differences in the Docker container that may cause the issue. Without more visibility into the code and environment, it's hard to suggest where to start, but here are some ideas:
Compare the output of php -i from each environment. Look out for PHP extensions that exist in one, but not the other.
Use phpdbg to set a breakpoint and step through the code. We're already using it to generate coverage, but it's also a useful debugging tool. We're looking for the item that causes the infinite recursion. Note that we'll need to set the breakpoint before PHPUnit executes the test case such as in the bootstrap file or PHPUnit source code (line 810 of TestCase may work).
When bind-mounting a volume, make sure the www-data user in the container has the same UID as the user that owns the files on the host.
Try running the test without the memory limitation. Obviously we can't allocate as much as the error suggests we may need, but the memory limit may mask another underlying problem. We can kill the container if needed.
I couldn't reproduce this issue using a dummy test in a similar environment (as close as I could get—same container with volume), so the code under test may contribute to the problem.
Your mounted folder probably has all vendors and cache files. Try mounting only the source folder.
This is phpdbg bug. Note how much memory it tries to allocate? It is insane. I tried hard to figure out where the bug exactly: if test script full name (directory + script file name) exceeds certain size then it overflows the stack (yeah, stackoverflow ;) and overwrites integer which specifies how much memory must be allocated. Then normal error handling kicks in: not enough memory to allocate such insane amount. So this is for Krakjoe to fix. Or may be I will make a patch for it in my spare time. If you need to have resolution right now: make sure that directory path your script is in is short.
I have a fairly simple problem that I cannot seem to figure out.
I am developing an OOP-based PHP application using the Composer Dependency Manager, PHPUnit for testing. I am hosting the repository on GitLab and am using GitLab-CI to run the PHPUnit tests.
My file directory is fairly simple:
├──_data
├──_2016
├──_federal
├──fit.json
├──_libs
├──_paycheckCalculator
├──paycheck.php
├──taxCalc.php
├──_public_html
├──index.php
├──_vendor
├──[composer dependencies]
├──autoload.php
├──_tests
├──paycheckTest.php
├──taxCalcTest.php
├──_templates
├──[Twig templates]
taxCalc.php contains:
public static function calcFIT($taxableWages, array $taxStatus, int $frequency = 52):float {
$fitFile = "../data/2016/federal/fit.json";
...
That works just fine on my production server and I can run the PHPunit tests just fine via PHPUnit integration with PhpStorm, but when I try to get GitLab-CI to work I consistently get an error:
...
$ vendor/bin/phpunit --configuration phpunit.xml PHPUnit 5.5.4 by
Sebastian Bergmann and contributors.
EE..EII 7
/ 7 (100%)
Time: 32 ms, Memory: 4.00MB
There were 3 errors:
1) paycheckTest::calcNetTest
file_get_contents(../data/2016/federal/fit.json): failed to open
stream: No such file or directory
/builds/calebrw/paycheckCalculator/libs/paycheckCalculator/taxCalc.php:100
/builds/calebrw/paycheckCalculator/libs/paycheckCalculator/paycheck.php:49
/builds/calebrw/paycheckCalculator/libs/paycheckCalculator/paycheck.php:28
/builds/calebrw/paycheckCalculator/tests/paycheckTest.php:34
2) paycheckTest::calcTaxesTest
file_get_contents(../data/2016/federal/fit.json): failed to open
stream: No such file or directory
/builds/calebrw/paycheckCalculator/libs/paycheckCalculator/taxCalc.php:100
/builds/calebrw/paycheckCalculator/tests/paycheckTest.php:58
3) taxCalcTest::calcFITTest
file_get_contents(../data/2016/federal/fit.json): failed to open
stream: No such file or directory
/builds/calebrw/paycheckCalculator/libs/paycheckCalculator/taxCalc.php:100
/builds/calebrw/paycheckCalculator/tests/taxCalcTest.php:53
ERRORS! Tests: 7, Assertions: 11, Errors: 3, Incomplete: 2. ERROR:
Build failed: exit code 1
My .gitlab_ci.yml is as follows:
# Select image from https://hub.docker.com/_/php/
image: php:7.0
# Select what we should cache
cache:
paths:
- vendor/
before_script:
# Install git, the php image doesn't have installed
- apt-get update -yqq
- apt-get install git -yqq
# Install composer
- curl -sS https://getcomposer.org/installer | php
# Install all project dependencies
- php composer.phar install
PHPUnit:testsuite:
script:
- vendor/bin/phpunit --configuration phpunit.xml
My phpunit.xml file contains:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.5/phpunit.xsd"
colors="false"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnFailure="false">
<testsuites>
<testsuite name="Paycheck Tests">
<directory>tests/</directory>
</testsuite>
</testsuites>
<php>
<includePath>/builds/calebrw/paycheckCalculator</includePath>
</php>
</phpunit>
Please note that I've used this with or without the <includePath> tag and there is no difference if I use <includePath>/../</includePath> or anything else for that matter.
I appreciate any help you can give.
EDIT:
I finally got this to work. I added a function (in the global space for now) to my config.php file:
/**
* Required Functions
*/
function getDirectory(bool $html = false):string
{
$htmlBaseDirectory = '/webprojects/paycheckCalculator';
if ($html == true) {
return $htmlBaseDirectory;
} else {
return dirname(__DIR__);
}
}
That meant I could update my index.php:
require_once('config.php'); // Configuration Variables
require_once( getDirectory() . '/vendor/autoload.php'); // Composer Autoload
$dir = getDirectory(true) . $htmlPublicDirectory; // Combined variable needed for Twig compatibility
but I was still having problems with the GitLab-Ci runner having yet a completely different environment that doesn't call my config.php at all, so I added a fix (or hack really) to get the test to pass to taxCalc.php:
if (getenv('CI_BUILD_ID') !== false) {
define('MAIN_PATH', '/builds/calebrw/paycheckCalculator/');
} else {
define('MAIN_PATH', dirname(__DIR__));
}
...
class taxCalc
{
...
public static function calcFIT($taxableWages, array $taxStatus, int $frequency = 52):float {
$fitFile = MAIN_PATH . "/data/2016/federal/fit.json";
And now the build passes.
Thanks for all the help to both people who responded.
Make sure that the file is commited (usually you don't commit data you may place it under resources). I think you did already.
The second thing is also just a suggestion:
define a PATH constant and use this. Because in your case you never know where is your current working directory.
Define a bootstrap file in phpunit and define the MAIN_PATH. Example:
<?php
define('MAIN_PATH', dirname(__DIR__));
require MAIN_PATH . '/vendor/autoload.php';
In the index you have to provide this MAIN_PATH too and in calcFit you write:
<?php
function calcFit() {
$fitFile = MAIN_PATH . '/data/2016/federal/fit.json';
}
The issue is very probably that you are using a relative path in your require. See here for explanations and solutions : PHP - Failed to open stream : No such file or directory
I have a 'No tests executed' with phpunit..
This line works
$ phpunit install/InstallDbTest.php
...
<result expected>
...
$ cat suites/installtests.xml
<phpunit>
<testsuites>
<testsuite name="database">
<file>install/InstallDbTest.php</file>
</testsuite>
</testsuites>
</phpunit>
$ phpunit -c suites/installtests.xml
PHPUnit 4.7.4 by Sebastian Bergmann and contributors.
Time: 130 ms, Memory: 11.25Mb
No tests executed!
Does anyone can tell me what I am doing wrong ?
Thanks in advance!
You need to correct the path in your phpunit.xml.
It is trying to find the filesuites/install/InstallDbTest.php. Since the file doesn't exist, no tests are run and you get the message.
Change the configuration to the following:
<phpunit>
<testsuites>
<testsuite name="database">
<file>../install/InstallDbTest.php</file>
</testsuite>
</testsuites>
</phpunit>
File paths in phpunit.xml are all relative to the location of the xml file.
Maybe in the InstallDbTest.php file you are missing:
<?php
...
For those of you who you use a different bootstrap file than the Composer's autoload file, make sure you don't use one of your test case classes.
Indeed, PHPUnit (version 6.2 in my case) add to the running TestSuite all PHP files for which no class is loaded yet (see how it's done in the code). From the TestSuite::addTestFile($filename) method:
$classes = get_declared_classes();
$filename = Fileloader::checkAndLoad($filename);
$newClasses = \array_diff(\get_declared_classes(), $classes);
So if your class already belong to the get_declared_classes it will be ignored.
To summarize: don't use your test class before ;)
For many good reasons I put some tests into parent test class und some tests in inhereted class. I have got this structure then:
/bar/foo/foo.php
/bar.php
This command I use to start phpunit: phpunit --configuration unit.xml I tried this one too, but with same result: phpunit --configuration unit.xml --testsuite foo
So now I want to run all tests in a folder foo. Problem is, that tests in bar.php will be running twice and I have no idea why. Do someone has the answer to that? Is it maybe a feature of phpunit? How can I told phpunit not to run them twice?
If I run phpunit bar/foo/foo.php everything works fine and test function in bar.php is running only once.
foo.php
require_once '/bar.php';
class foo_test extends bar_test {
public function test_1_pass() {
$this->assertEquals('a', 'a');
}
}
bar.php
class bar_test extends PHPUnit_Framework_TestCase {
public function test_2_fail() {
$this->assertEquals('a', 'b');
}
}
Unittest responce
PHPUnit 3.7.29 by Sebastian Bergmann.
Configuration read from /unit.xml
F.F
Time: 104 ms, Memory: 3.25Mb
There were 2 failures:
1) bar_test::test_2_fail
Failed asserting that two strings are equal.
/bar.php:6
2) foo_test::test_2_fail
Failed asserting that two strings are equal.
/bar.php:6
FAILURES!
Tests: 3, Assertions: 3, Failures: 2.
unit.xml
<phpunit
backupGlobals="false"
backupStaticAttributes="false"
syntaxCheck="false">
<testsuites>
<testsuite name="foo">
<directory suffix=".php">bar/foo</directory>
</testsuite>
</testsuites>
</phpunit>
If you don't intend to execute the parent test class on its own, make it abstract, this prevents PHPUnit from trying to instantiate it and running its tests.