set unit test symfony - php

Actually I exposed my question here : test a repository in symfony
But When setting a test for my repository, I get the following result:
Time: 4 seconds, Memory: 18.25Mb
OK, but incomplete or skipped tests!
Tests: 76, Assertions: 183, Skipped: 9.
Is the test ok or not ok and what does assertion mean?
Why does he skip some tests??

Is the test ok?
Yes, the tests are OK ("OK, but incomplete or skipped tests").
what does assertion mean?
Assertions are expectations that are done in a test. For instance:
class CalculatorTest extends \PHPUnit_Framework_TestCase
{
public function testSum()
{
$calculator = new Calculator();
$this->assertEquals(5, $calculator->sum(2, 3));
$this->assertEquals(19, $calculator->sum(14, 2, 3));
}
}
In this code, we have 1 test (testSum) and 2 assertions (2 times assertEquals).
Why does he skip some tests?
Symfony relies on some third party libraries or PHP extensions which may not be installed. When it isn't installed, you can't test it. Thus markes Symfony the test as skipped. For instance:
class LocaleTypeTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
if (!extension_loaded('php_intl')) {
$this->markTestSkipped('Failed to run LocaleType tests, as intl is missing.');
}
}
}

Related

Autoloading class files for PHPUnit

So, I am just playing around with PHPUnit, I don't really need it but I want to learn how it works so I am trying it out on a random class in a plugin of mine.
The issue I have rn is that whenever I run phpunit I says the Plot class in my test was not found. In my composer.json file I have
{
"require": {
"phpunit/phpunit": "^8.5"
},
"autoload":{
"psr-4" : { "\\mohagames\\PlotArea\\utils\\" : "src/mohagames/PlotArea/utils/"}
}
}
And my Plot.php file is in the C:\Users\moham\Documents\GitHub\PlotArea\src\mohagames\PlotArea\utils\ directory and has the mohagames\PlotArea\utils namespace
But for some reason it still says
C:\Users\moham\Documents\GitHub\PlotArea>C:\Users\moham\Documents\Github\PlotArea\vendor\bin\phpunit --debug
PHPUnit 8.5.0 by Sebastian Bergmann and contributors.
Runtime: PHP 7.3.4
Configuration: C:\Users\moham\Documents\GitHub\PlotArea\phpunit.xml
Test 'SampleTest::testPlot' started
Test 'SampleTest::testPlot' ended
Time: 95 ms, Memory: 4.00 MB
There was 1 error:
1) SampleTest::testPlot
Error: Class 'Plot' not found
C:\Users\moham\Documents\GitHub\PlotArea\tests\unit\SampleTest.php:8
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.
And the SampleTest test class:
<?php
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase{
public function testPlot(){
$plot = new Plot();
}
}
I've tried all sort of solutions on the internet but none of them worked
Like Alister pointed out importing the class first works otherwise, PHP doesn't know what class the code is referring to.
<?php
use PHPUnit\Framework\TestCase;
use mohagames\PlotArea\utils\Plot;
class SampleTest extends TestCase{
public function testPlot(){
$plot = new Plot();
}
}

What did I miss in my Mock Aspect configuration?

I am developping a phpcas bundle using guard component of Symfony framework. My bundle is working but I want to do some unit tests. I want to test my CasAuthenticator. PhpCAS library is using static method. So I decided to use Mock Aspect to mock it.
I configured Aspect, but I still have a bug.
Here is a simplified test which is running but failing.
Expected PhpCAS::setDebug to be invoked but it never occurred. Got:
C:\wamp64\www\casguard\casguard\vendor\codeception\aspect-mock\src\AspectMock\Proxy\Verifier.php:64
C:\wamp64\www\casguard\casguard\Tests\SimpleTest.php:32
//root_dir/Tests/SimpleTest.php
namespace AlexandreT\Bundle\CasGuardBundle\Tests;
use PHPUnit\Framework\TestCase;
use AspectMock\Test as test;
use PhpCAS;
class SimpleTest extends TestCase
{
public function testAspectMock()
{
$phpCas = test::double('PhpCAS', ['setDebug' => function () {
echo 'YES I CALL THE MOCKED Debug function';
}]);
PhpCAS::setDebug();
$phpCas->verifyInvoked('setDebug', false);
}
protected function tearDown()
{
parent::tearDown();
test::clean();
}
}
Output does not contain YES I CALL THE MOCKED Debug function, so I think that the PhpCAS is not mocked by Aspect.
I carefully read this documentation and I configured my bootstrap file like this:
//root_dir/Tests/bootstrap.php
include __DIR__.'/../vendor/autoload.php'; // composer autoload
$kernel = \AspectMock\Kernel::getInstance();
$kernel->init([
'debug' => true,
'includePaths' => [
__DIR__.'/../vendor/jasig/phpcas',
],
]);
As you can read, I added the vendor directory where the Cas.php declares the PhpCAS class. But it doesn't change anything. I made some tests: the bootstrap.php file is loaded by phpunit.
What did I miss in my Mock Aspect configuration?
I added a line to configure cache directory in my bootstrap.php file
and I can see that the Cas.php was well included.
But I still had the bug. When I was exploring the cached file, I discovered that the phpcas library doesn't respect the PSR0 convention. First letter of phpCAS Class isn't capitalized.
So I edited my test:
public function testAspectMock()
{
//$phpCas = test::double('PhpCAS', ['setDebug' => function () {
// ^
// |
// v
$phpCas = test::double('phpCAS', ['setDebug' => function () {
echo 'YES I CALL THE MOCKED Debug function';
}]);
phpCAS::setDebug(); //phpCAS instead of PhpCAS
$phpCas->verifyInvoked('setDebug', false);
//And I had an assertion else test is marked as risky.
self::expectOutputString('YES I CALL THE MOCKED Debug function');
}
2 letters... 2 hours of debugging... #Grrrr

Phpunit tests gives warning no tests found in class

I am trying to learn how to test with phpunit and laravel. When start the test using phpunit command, I am getting a warning :
There was 1 failure:
1) Warning
No tests found in class "PostsTest".
FAILURES!
Tests: 2, Assertions: 1, Failures:
My test classname and filename matches. I have read other problems about unmatching names. my filename is PostsTest.php and my test file :
class PostsTest extends ApiTester {
public function it_fetches_posts()
{
$this->times(5)->makePost();
$this->getJson('api/v1/posts');
$this->assertResponseOk();
}
private function makePost($postFields=[])
{
$post = array_merge([
'title' => $this->fake->sentence,
'content' => $this->fake->paragragraph
], $postFields);
while($this->times --)Post::create($post);
}
}
if necessary my ApiTester :
use Faker\Factory as Faker;
class ApiTester extends TestCase {
protected $fake;
protected $times = 1;
function __construct($faker)
{
$this->fake = Faker::create();
}
}
I dont have any clue where the error is. Laravel or my local phpunit settings or anything else. Any helps is appreciated.
Thanks.
Annotations are the answer.
/** #test */
public function it_tests_something()
{
...
}
Adding that #test tells phpunit to treat the function as a test, regardless of the name.
The only methods that PHPUnit will recognize as tests are those with names starting with test.
So you should rename the it_fetches_posts() method to test_it_fetches_posts or testItFetchesPosts. The camel case naming is optional but useful if you use the --testdox option later.
Also, as stated in other answer you can also add the #test annotation to any method and it will be considered a test by PHPUnit.
Either begin its name with word 'test' like test_something_should_work or update the test docs with this annotation /** #test */
Additionally, consider a case where you are testing a class A that requires a class B (that you will mock). When $a->someMethod($mocked_B_class) is called, make sure you don't have any warnings in it such as trying to access a property of an array like you would access the property of a class ($array = ['one','two']; $array->one).
In this case it wont give you any information about the test or the error

constructor breaks phpunit tests with providers

Here's a test PHPUnit test I wrote:
<?php
class MyTest extends PHPUnit_Framework_TestCase
{
public function __construct()
{
echo "starting tests\r\n";
parent::__construct();
}
public function provider()
{
return array(array('test'));
}
/**
* #dataProvider provider
*/
public function testProvider($var)
{
$this->assertEquals($var, $var);
//exit($var);
}
}
When I run it I get the following:
There was 1 error:
1) MyTest::testProvider
Missing argument 1 for MyTest::testProvider()
/home/myname/test.php:19
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
My question is... why? And what can I do about it?
In the actual unit tests I'm writing (the above is just a test demonstrating the problem) I'm testing a class with several different backend engines. I have an abstract class with a bunch of test cases and a protected class variable named $engine. I then have a bunch of classes that extend this abstract class and set $engine in the constructor. In each of the test methods in the abstract method $obj->setEngine($this->engine) is then called to test the specific engine in question. But this approach seems to break unit tests with providers and in lieu of that I'm not sure what I should be doing.
Any ideas?
Instead of implementing a constructor, you should use the static method setUpBeforeClass to create the $engine. The engine must be stored in a static property.
https://phpunit.de/manual/current/en/fixtures.html#fixtures.sharing-fixture

Running PHPUnit tests from directory with custom framework

For our project I have created a framework on top of the PHPUnit framework which helps us in some of the common tasks in writing unit tests.
This custom framework inherits from PHPUnit_Framework_TestCase and then modifies the mySetup() and adds bunch of useful functions for our code.
<?php
class OurUnitTestFramework extends PHPUnit_Framework_TestCase {
public $dbMock;
protected function mySetup (..) { ... }
protected function testHelper () { ... }
}
?>
Now in our test code we just extend OurUnitTestFramework and then write the tests.
<?php
require_once ("OurUnitTestFramework");
class DatabaseConnectionTest extends OurUnitTestFramework {
parent::setUp (..) { ... }
public function testSomeThing () { ... }
public function testSomeOtherThing () { ... }
}
?>
Till now we were running all the unit tests through Jenkins and it still is running fine but now when we try to run the tests in a folder it fails. All the tests inside the folder/sub-folder runs successfully but there is one failure:
[sumit#dev model]$ phpunit database
PHPUnit 3.5.14 by Sebastian Bergmann.
F........
Time: 0 seconds, Memory: 10.50Mb
There was 1 failure:
1) Warning
No tests found in class "OurUnitTestFramework".
FAILURES!
Tests: 9, Assertions: 30, Failures: 1.
I have a directory database which has sub directories and all the tests passes from that folder and its subfolder but I get failure from OurUnitTestFramework saying there is no tests found in this custom framework. So I am not able to understand why phpunit is running unit tests on the file which is included/extended in the test file?
We can simply choose to ignore this one error but I wanted to know if okay to leave like this or is there something that I need to configure to make it pass.
Thanks
Make 'OurUnitTestFramework' an abstract class.

Categories