Silex - Code coverage from functional test - php

I would like to generate code coverage from functional testing in Silex App via PHPUnit. I created sandbox where you could reproduce.
The question is: Why Controller::indexAction() method is marked as Not Executed code in code coverage report?
Thank you!

No time for testing.
What i have seen:
You are setting your test array for the first test in app.php
return new \Symfony\Component\HttpFoundation\JsonResponse(['foo' => 'bar']);
Why? And did the test fail if you remove that? Maybe here the Controller isn't tested.
Then you are testing the 2 methods not in the same way.
Maybe that leads to the solution of the problem.

Related

Code Coverage with PHPUnit during Runtime

I am using Laravel to build my own website, and I want to know the coverage for my source code during a user interaction event instead of writing testing cases using PHPUnit.
From my perspective, PHPUnit only generate reports that the unit tests touch, but if I want to get the code coverage during the execution, meaning generate the code coverage report after php artisan serve
What should I do to achieve this feature? For instance:
$filter = new Filter;
$filter->includeDirectory('/path/to/directory');
$coverage = new CodeCoverage(
(new Selector)->forLineCoverage($filter),
$filter
);
$coverage->start();
// Some User Interactions to the Web Service
$coverage->stop();
// Generating reports during the interactions
(new HtmlReport)->process($coverage, '/tmp/code-coverage-report');
All comments, answers, and bits of advice are welcome.
Thank you.

PHPUnit: creating custom code coverage reporter / logger

To contextualise, in similar tools, PHPMD and PHPCS, one can specify a custom formatter for result output, eg:
PHPMD:
vendor/bin/phpmd test \\my\\namespace\\renderers\\phpmd\\AdamFormat phpmd.xml
PHPCS:
vendor/bin/phpcs --standard=phpcs.xml --report=./src/renderers/phpcs/AdamFormat.php
I'm looking to do the same thing for PHPUnit, but have thusfar drawn a blank (investigation, googling, searching here). Looking at the code of PHPUnit, it all seems a bit hard-codey to me:
Code coverage handler:
if (isset($arguments['coverageClover'])) {
$this->printer->write(
"\nGenerating code coverage report in Clover XML format ..."
);
try {
$writer = new CloverReport;
Logging:
if (isset($arguments['testdoxHTMLFile'])) {
$result->addListener(
new HtmlResultPrinter(
I have not spotted anywhere in the docs that suggest otherwise. Seems like an odd shortfall to me.
So two questions:
Am I reading things right? PHPUnit doesn't support this?
Presuming that's "yes: not supported", has anyone had any success with a tactic to circumventing this in a non Heath Robinson manner?
I realise that one can use the --coverage-php option to output the results as PHP variables for another process to then utilise to do [whatever], but that seems like an inside out approach to me, and falls into the Heath Robinson category.

Error using Mockery/phpUnit in Laravel

I'm a novice developer trying to get a test suite started for an existing laravel app but I have not experience in testing. Right now I'm just trying to get some tests built out to get some confidence and experience to write more substantial tests. I'm trying to test a relationship on a model(I realize it's not a very sensible tests) and trying to create a mocked model object to do so(I also understand it's better to do this in memory in a sqlite db but the major goal here is to test the controllers but I don't know how to deal with the authentication issue there). I have the following simple, stupid test:
public function testFoo()
{
$lead = m::mock('Lead');
$this->mock->shouldReceive('program')->once();
$this->assertEquals($lead->program_id, $lead->program->id);
}
But I get the following error:
LeadTest::testFoo
BadMethodCallException: Received Mockery_0_Lead::getAttribute(), but no expectations were specified
I don't understand what this error is trying to tell me and I'm finding no help googling the issue or reading through the docs I can find.
I assume I'm not setting the expected return values but this is a pretty general test and it doesn't seem right to hard code expected return values. What am I missing here?
I'm just testing a Laravel relationship to make sure I have things set up/implemented correctly:
public function program()
{
return $this->belongsTo('Program');
}
The problem was that I was missing the expected return value. It should've been something like this:
$this->mock->shouldReceive('program')->once()->andReturn(someObjectOrValue);
And the assertion should've been something like:
$this->assertEquals(someObjectOrValue, $lead->program->id);
The Mockery docs are a lot more verbose than I originally thought. http://docs.mockery.io/en/latest/reference/expectations.html

Laravel Unit testing controllers error when using multiple methods

I am trying to test some of my controllers through Unit Testing. But there is something strange happening. With the following code in my testcase:
public function test_username_registration_too_short()
{
$result = $this->action('POST', 'App\\Controllers\\API\\UserController#store', null, [
'username' => 'foo'
]);
$this->assertEquals('not_saved', $result->getContent());
// $result = $this->action('POST', 'App\\Controllers\\API\\UserController#store', null, [
// 'username' => 'foo'
// ]);
// $this->assertEquals('not_saved', $result->getContent());
}
public function test_username_registration_too_short_run_2()
{
$result = $this->action('POST', 'App\\Controllers\\API\\UserController#store', null, [
'username' => 'foo'
]);
$this->assertEquals('not_saved', $result->getContent());
}
When I run this, the initial too_short test passes, but the exact same code on run 2 does not pass (it even manages to save the user). But if I put that same code twice in the same method (what is commented out now) it works perfectly? I have nothing in my setUp or tearDown methods. And I am a bit lost here.
The code in the controller is the following:
$user = new User(Input::all());
if($user->save())
{
return 'saved';
}
return 'not_saved';
I'm not going to stop repeating myself over this question. There's a similar answer to a (somewhat) similar question. TL;DR: don't use unit testing framework for functional / integration testing.
This is area of functional testing and there is a fabulous framework
called Behat. You should do your own research, but essentially, while
PHPUnit is great at testing more or less independent blocks of
functionality it sucks at testing bigger things like full request
execution. Later you will start experiencing issues with session
errors, misconfigured environment, etc., all because each request is
supposed to be executed in it's own separate space and you force it
into doing the opposite. Behat on the other hand works in a very
different way, where for each scenario (post robot, view non-existing
page), it sends a fresh request to the server and checks the result.
It is mostly used for final testing of everything working together by
making assertions on the final result (response object / html / json).
If you want to test your code the proper way consider using the right tools for that. Once you know your way around with Behat you'll fall in love with it + you can use PHPUnit from within the Behat, to make individual assertions.

Yii - CHttpRequesterror while functional unittesting in module

When I'm trying to execute a functional unittest of a module within my Yii code, I keep receiving the following error:
CException: CHttpRequest is unable to determine the request URI.
At first, I though it was because it couldn't find the module. However, If I change the url to a wrong one, I get a correct error,s tating it couldn't find the view.
This is how my testing code looks like
public function testViewControllerModule()
{
ob_start();
Yii::app()->runController('module/controller/view');
}
Any ideas on what I might be missing?
bool.devs answer works so far.
This blog post explains the origin of the exception pretty well:
http://mattmccormick.ca/2012/09/14/unit-testing-url-routes-in-yii-framework/
In my case, I generalized the solution and have set the following variables in /www/protected/tests/bootstrap.php:
...
$_SERVER['SCRIPT_FILENAME'] = 'index-test.php';
$_SERVER['SCRIPT_NAME'] = '/index-test.php';
$_SERVER['REQUEST_URI'] = 'index-test.php';
Yii::createWebApplication($config);
Consider using 'index-test.php' instead of 'index.php' because it contains the config 'test.php' which is responsible for fixtures and maybe other test relevated configurations.
If someone has better suggestions feel free to comment :)
Kind regards
I think it's because you haven't set any server variables, i.e $_SERVER and you might be doing something like this in your controller:
Yii::app()->request ....
So before you run your test, make sure you use a fixture for the server variables also. I think this should suffice for now:
$_SERVER=array(
'REQUEST_URI'=>'index.php', // the other fields should follow
);
However to run functional tests i would recommend using SeleniumRC, you won't have to do these workarounds then, and can simulate user clicks also, i think.
Read the initial guide to Functional Testing , read the selenium rc phpunit guide, and also the CWebTestCase documentation.
Notes: You might still have to use fixtures for some variables, and i don't have much experience in testing(which is bad), so i'm not very sure if i am completely correct about selenium.

Categories