I want to use a local installation of PHPUnit (via composer) to run my tests and display it on screen (acessing /admin/tests for instance). But the only way to run tests I found in the documentation was the command line tool.
Bellow is an hypothetical example of what I'm looking for:
$session = new PHPUnit_TestSession('path/to/folder');
$results = $session->runAll();
echo $results->failuresCount();
// other hipotetical $result->methods...
// maybe $results->dump()
This may be an overkill but you are in for a treat: https://github.com/NSinopoli/VisualPHPUnit :)
EDIT Here is a rudimentary use of PHPUnit using the TextUI_TestRunner
// make sure you have PHPUnit on your path
require_once "PHPUnit/Framework/TestSuite.php";
require_once "PHPUnit/TextUI/TestRunner.php";
$suite = new PHPUnit_Framework_TestSuite();
$suite->addTestSuite('YourTestCase');
// run the test suite with TextUI_TestRunner
PHPUnit_TextUI_TestRunner::run($suite);
The YourTestCase class is a subclass of PHPUnit_Framework_TestCase, which you can read more on how to write at the official website: http://www.phpunit.de/manual/3.2/en/writing-tests-for-phpunit.html
However, I'd also recommend getting a copy of this book: http://www.amazon.com/Advanced-PHP-Programming-George-Schlossnagle/dp/0672325616 The author teaches you quite a few cool tricks, including autoloading tests, etc.
Related
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.
I am new on Symfony2 and I got blocked when trying to run an asynchronous command like this:
class MyCommand extends ContainerAwareCommand{
protected function configure()
{
$this
->setName('my:command')
->setDescription('My command')
->addArgument(
'country',
InputArgument::REQUIRED,
'Which country?'
)
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$country = $input->getArgument('country');
// Obtain the doctrine manager
$dm = $this->getContainer()->get('doctrine_mongodb.odm.document_manager');
$users = $dm->getRepository('MyBundle:User')
->findBy( array('country'=>$country));
}}
That works perfectly when I call it from my command line:
php app/console my:command uk
But it doesn't work when I call it trowh a Symfony2 Process:
$process = new Process("php ../app/console my:command $country");
$process->start();
I get a database error: "[MongoWriteConcernException] 127.0.0.1:27017: not master"
I think that means that the process is not getting my database configuration...
I just want to run an asynchronous process, is there other way to do it?
Maybe a way to call the Application Command that do not require the answer to keep going ?
Maybe I need to use injection?
PS: My current command is just a test, at the end it should be an 'expensive' operation...
Well, I found out what happened...
I use multiple environments: DEV, TEST and PROD.
And I also use differents servers.
So the DEV environment is my own machine with a simple mongodb configuration.
But the TEST environment is on other server with a replica set configuration...
Now the error get full sense: "[MongoWriteConcernException] 127.0.0.1:27017: not master"
To solve it, I've just added the environment parameter (--env=) to the process and everything worked like a charm:
$process = new Process("php ../app/console my:command $country --env=test");
Actually, to get the correct environment I use this:
$this->get('kernel')->getEnvironment();
Which let's my code as follows:
$process = new Process("php ../app/console my:command $country --env=".$this->get('kernel')->getEnvironment());
Maybe is not a beautifull way to do it, but it works for me :)
Disclamer: This might be a bit overkill for what you're trying to do :)
I would choose an opposite way to do it: pthreads
First, quick examination of StackOverflow showed me a really nice example of using pthreads: Multi-threading is possible in php
Then, knowing that you could invoke your command from another command:
http://www.craftitonline.com/2011/06/calling-commands-within-commands-in-symfony2/
... lets you piece all the parts. It's a bit complicated but it does the job.
In case you want to execute your code completely async in Symfony2/3 there is AsyncServiceCallBundle for that.
You should just call it like this:
$this->get('krlove.async')->call('your_service_id', 'method_name', [$arg1, $arg2]);
Internally it uses this approach to run your code in background.
I'm attempting to implement https://github.com/PHP-FFMpeg/PHP-FFMpeg
I copied the src/FFMpeg folder to my includes folder and made sure my autoloader knows where to find everything.
as a test I made a script that simply does:
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
I get:
Fatal error: Class 'Doctrine\Common\Cache\ArrayCache' not found in /var/www/php/include/FFMpeg/FFProbe.php on line 203
My question is: does PHP-FFMPeg require Doctrine, because that is not stated in the documentation. What version do I need? Are there other prerequisites?
I could create a new question for this, but I'm not sure if I should. I now have PHP-ffmpeg implemented. I'm using Laravel, however that should be irrelevant for this question. I'm trying to enable progress monitoring. It works, however I need to pass in an ID so I can update the correct key in memcache.
$id = 12345;
$format->on('progress', function ($audio, $format, $percentage) {
//this works perfect, but doesn't tell me which item is being updated
Cache::put("progress", $percentage, .25);
//this does not work as I am unable to pass in $id, if I add it as the 4th argument above it will display the number of threads or something
//Cache::put("{$id}_progress", $percentage, .25);
});
I need clarification on the "on" method. I looked through https://ffmpeg-php.readthedocs.org/en/latest/_static/API/ and was not able to figure out how this method works. Any help would be appreciated.
You should follow the recommended instructions in the README.
Composer is the easiest way to install PHP-FFMpeg dependencies
The "on" method called on the format is an implementation of EventEmitter.
As you can see here : https://ffmpeg-php.readthedocs.org/en/latest/_static/API/FFMpeg/Format/ProgressableInterface.html it extends the EventEmitterInterface of https://github.com/igorw/evenement.
If you're really interested about how it works under the hood, have a look at here :
The progress listener is created here : https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Format/Audio/DefaultAudio.php#L96 and added at execution here https://github.com/PHP-FFMpeg/PHP-FFMpeg/blob/master/src/FFMpeg/Media/Video.php#L151
This is actually possible because FFMpegDriver extends the Driver provided by https://github.com/alchemy-fr/BinaryDriver
Hope this helps :)
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.
I've got a PHP script that runs at the command line, executing classes that are already unit tested with PHPUnit.
However, I'd like to verify that the script itself has no logical errors and runs properly.
// require classes
require_once 'injectedClass.php';
require_once 'DBClass.php';
require_once 'taskEngine.php';
$injectedObj = new injectedClass;
$dbObj = new DBClass;
$taskRunner = new taskEngine($injectedObj, $dbObj);
$taskRunner->task1()->task2();
$taskRunner->finish();
//etc
Updated Solution
It is as simple as djechelon's answer suggested, I was overthinking it. The solution is to create a PHPUnit test and pre-assign the variables passed into the taskRunner to mock objects. In the live script, a simple check before creating real objects allows the same script to be used for testing and production:
test:
$injectedObj = $this->getMock('injectedClass');
$dbObj = $this->getMock('DBClass');
require_once '/path/to/live/script.php';
$this->assertTrue($taskRunner->finished);
script:
// require classes
if(!isset($injectedObj)) {
$injectedObj = new injectedClass;
}
if(!isset($dbObj)) {
$dbObj = new DBClass;
}
$taskRunner = new taskEngine($injectedObj, $dbObj);
// run tasks
Can't you create a PHPUnit test for your script?
You could perform an integration test by hand, creating a script that runs your script with a set of given input parameters and compare its output to what you could expect.
Beware of the chicken-and-egg problem: your testing script cannot be tested itself by a test bench...
Anyway I'm not sure you need testing your script if it's so simple. A few manual runs might suffice...