PHPUnit not doing anything, no output - php

I have written some test cases and want to try them out with PHPUnit. However, it does not work.
If I run phpunit CategoryTest it outputs:
PHPUnit 3.7.14 by Sebastian Bergmann.
If I do phpunit --log-json error.log CategoryTest, error.log file displays:
{"event":"suiteStart","suite":"CategoryTest","tests":5}
{"event":"testStart","suite":"CategoryTest","test":"CategoryTest::test__construct"}
So, it finds that there are 5 tests in the file, starts doing the first one and for no reason stops. Is there any log where I could find a reason why it would not continue execution?
Also, if I run test on some other file, say phpunit --log-json error.log UserTest, the shell does not display any output and neither does error.log file.
I tried reinstalling it, as it was suggested in one of the other similar questions, but it didn't do anything.
Any ideas how I could fix it?
require_once '../Category.class.php';
require_once '../../db_connect.php';
require_once 'PHPUnit/Framework/TestCase.php';
class CategoryTest extends PHPUnit_Framework_TestCase {
private $Category;
protected function setUp() {
parent::setUp ();
$this->Category = new Category(0, $mdb2);
}
protected function tearDown() {
$this->Category = null;
parent::tearDown ();
}
public function __construct() {
}
public function test__construct() {
$this->markTestIncomplete ( "__construct test not implemented" );
$cat = $this->Category->__construct(0, $mdb2);
$this->assertInstanceOf('Category', $cat);
}
public function testReturnID() {
$this->markTestIncomplete ( "returnID test not implemented" );
$id = $this->Category->returnID();
$this->assertEquals(0, $id);
}
...
}
Variable $mdb2 comes from the db_connect.php file.
I figured it out. The problem was that I included a variable from outside of a class.

You shouldn't overwrite the __construct() method in your TestCase. The constructor sets up the mock generator and some other mandatory thing for the test, so you get a lot of strange behaviour and unwanted side effects if you overwrite the constructor. The setUp() method is the special method you should use to initialize your test.

Related

PHPUnit does not run its tests

I am following the examples in the PHPUnit manual. See the two Test files below. I am running the tests in Eclipse PDT with PTI installed. I see the following problems:
When running DependencyFailureTest, it does not recognize it as being a test. Is does not run anything.
When running MultipleDependenciesTest, it is running and mentions that all three test cases pass, as it should. However, if I then change the expected outcome in the function testConsumer into array('first', 'third'), it still mentions that all test cases pass, although one of them should clearly fail. Also, when I change one of the assertions into $this->assertTrue(FALSE);, I expect a failed and a skipped test case, but again all test cases pass.
Has anyone experienced something similar, and solved this?
DependencyFailureTest
<?php
class DependencyFailureTest extends PHPUnit_Framework_TestCase
{
public function testOne()
{
$this->assertTrue(FALSE);
}
/**
* #depends testOne
*/
public function testTwo()
{
}
}
?>
MultipleDependenciesTest
<?php
class MultipleDependenciesTest extends PHPUnit_Framework_TestCase
{
public function testProducerFirst()
{
$this->assertTrue(true);
return 'first';
}
public function testProducerSecond()
{
$this->assertTrue(true);
return 'second';
}
/**
* #depends testProducerFirst
* #depends testProducerSecond
*/
public function testConsumer()
{
$this->assertEquals(
array('first', 'second'),
func_get_args()
);
}
}
?>
I don't have a good answer yet, only some black magic voodoo. I noticed that for running it in the command line, I need to include the class under test.
<?php
require_once ('path/to/Car.php')
class CarTest extends PHPUnit_Framework_TestCase {
...
For running it in PTI, I mention the file in the Bootstrap file in the PHPUnit preferences. Therefore, this reuire_once statement is not necessary. But worse however, this require_once statement causes the test not to run!
Something strange that I noticed is that at one time, my tests were not running, even without the require_once statement. In the PHPUnit preferences, I had the option Do not check for equal namespaces while searching for php/test case classes enabled. I disabled it, and it worked. I enabled it again, and it still worked.
Phpunit doesnot show any thing (run 0/0)
Console Error:
Fatal error: Declaration of PHPUnitLogger::addFailure(Test $test, AssertionFailedError $e, $time): void must be compatible with PHPUnit\Framework\TestListener::addFailure(PHPUnit\Framework\Test
$test, PHPUnit\Framework\AssertionFailedError $e, float $time): void in
C:\Users\xxx\AppData\Local\Temp\phpunit_printer\PHPUnitLogger.php(415): eval()'d code on line 1
TestCase
<?php
namespace PHPUnit\Framework;
use Facebook\WebDriver\WebDriverBy;
use Facebook\WebDriver\Remote\DesiredCapabilities;
use Facebook\WebDriver\Remote\RemoteWebDriver;
class SeleniumTest extends \PHPUnit_Framework_TestCase
{
protected $webDriver;
public function setUp()
{
// system . property_exists("Facebook\WebDriver\Firefox\FirefoxDriver", "C:\rc\geckodriver\geckodriver");
// System . set("Webdriver.gecko.driver", "C:\rc\geckodriver\geckodriver");
$this->webDriver = RemoteWebDriver::create('http://localhost:4444/wd/hub', DesiredCapabilities::firefox());
$this->webDriver->manage()
->window()
->maximize();
$this->webDriver->get('http://localhost/farmer/login');
// $this->webDriver->get("www.gmail.com");
}
public function testLoginPass()
{
$this->webDriver->get('http://localhost/farmer/login');
$this->webDriver->findElement(WebDriverBy::name('username'))->sendKeys(' correct');
$this->webDriver->findElement(WebDriverBy::id('password'))->sendKeys('password');
$this->webDriver->findElement(WebDriverBy::name('btn-login'))->click();
$content = $this->webDriver->findElement(WebDriverBy::tagName('body'))->getText();
$this->assertContains('Dashboard', $content);
}
public function testLoginFail()
{
$this->webDriver->get('http://localhost/farmer/login');
$this->webDriver->findElement(WebDriverBy::name('mobile'))->sendKeys("800000000000");
$this->webDriver->findElement(WebDriverBy::id('password'))->sendKeys("8000000000");
$this->webDriver->findElement(WebDriverBy::name('btn-login'))->click();
$content = $this->webDriver->findElement(WebDriverBy::className('help-block'))->getText();
$this->assertContains('Your Credential Doesnot Match.Please Try Again !!', $content);
}
public function tearDown()
{
$this->webDriver->quit();
}
}
?>
While MakeGood is working Properly in Eclipse (Everything is OK)
MAKEGOOD result

Run function before all tests in PHPUniit

I am looking at PHPunit for running Selenium tests and can run tests fine. What's missing though is the ability to run a function before the tests are run (let's say to set up some config).
<?php
require_once 'SeleniumTest.php';
class MyTest extends SeleniumTest
{
public function testTest1()
{
$this->runSelenese(__DIR__ . '/test1.html');
}
public function testTest2()
{
$this->runSelenese(__DIR__ . '/test2.html');
}
}
The config file is just a regular html file, but needs to be run once before anything else is run
Edit
Another read of the setUp() function has led me to believe that my tests should be setup as follows.
What I want to simulate is a user logging in, setting up some config, running the test and then logging out of the application at the end of the test.
This is what I have come up with; please advise on what I have done wrong, as the tests don't run at the moment. All tests timeout: is this how I should be approaching this?
<?php
require_once 'SeleniumTest.php';
class MyTest extends SeleniumTest
{
public function setUp()
{
$login_path = '/login_path/Login.html';
$logout_path = '/logout_path/Logout.html';
$config_path = '/config_path/config.html';
$this->runSelenese($login_path);
$this->runSelenese($config_path);
$this->runSelenese($logout_path);
}
public function testTest1()
{
$this->runSelenese(__DIR__ . '/test1.html');
}
public function testTest2()
{
$this->runSelenese(__DIR__ . '/test2.html');
}
}

PHPUnit and Mock Objects not working

I am not sure if I am doing something wrong or it is a bug with PHPUnit and mock objects. Basically I am trying to test if $Model->doSomething() is called when $Model->start() is triggered.
I am using Ubuntu in a VirtualBox, and phpunit 1.1.1 installed via pear.
The full code is below. Any help would be appreciated, it's driving me crazy.
<?php
require_once 'PHPUnit/Autoload.php';
class Model
{
function doSomething( ) {
echo 'Hello World';
}
function doNothing( ) { }
function start( ) {
$this->doNothing();
$this->doSomething();
}
}
class ModelTest extends PHPUnit_Framework_TestCase
{
function testDoSomething( )
{
$Model = $this->getMock('Model');
$Model->expects($this->once())->method('start'); # This works
$Model->expects($this->once())->method('doSomething'); # This does not work
$Model->start();
}
}
?>
The output from PHPUnit:
There was 1 failure:
1) ModelTest::testDoSomething
Expectation failed for method name is equal to <string:doSomething> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
As you found, you need to tell PHPUnit which methods to mock. Also, I would avoid creating expectations for methods that you are calling directly from the test. I would write the above test like this:
function testDoSomething( )
{
$Model = $this->getMock('Model', array('doSomething');
$Model->expects($this->once())->method('doSomething');
$Model->start();
}
Just to expand on why David Harkness's answer works, if you do not specify the $methods parameter to getMock then all functions in the class are mocked. Incidentally, you can confirm this with:
class ModelTest extends PHPUnit_Framework_TestCase
{
function testDoSomething( )
{
$obj = $this->getMock('Model');
echo new ReflectionClass(get_class($obj));
...
}
}
So, why does it fail? Because your start() function has been mocked too! I.e. the function body you have given has been replaced, and so your $this->doSomething(); line never gets run.
Hence, when there are any functions in your class that you need to be preserved, you'll have to explicitly give the list of all other functions.

Does vfsStream allow unlink empty dir?

My unit test tries to remove an empty dir. The class under test uses unlink (result of a previous test). If I write the same code without vfsStream I cannot remove the empty dir.
Unit test:
require 'vfsStream/vfsStream.php';
require '../Classes/Recursive/Delete.php';
class Recursive_Delete_Test extends PHPUnit_Framework_TestCase {
// More tests!
public function testShouldRemoveAnEmptyDirectory()
{
vfsStream::setup();
vfsStreamWrapper::getRoot()->addChild(vfsStream::newDirectory('dir'));
$recursiveDelete = new Recursive_Delete(vfsStream::url('root/dir'));
$recursiveDelete->delete();
$this->assertFileNotExists(vfsStream::url('root/dir'));
}
}
Production code:
class Recursive_Delete
{
private $_file;
public function __construct($file)
{
$this->_file = $file;
}
public function delete()
{
unlink($this->_file);
}
}
Is it a bug or am I missing something?
Thanks.
This is a bug in vfsStream up to 0.10.0 which allows unlink() on directories. The bug is fixed in upcoming release 0.11.0, see https://github.com/mikey179/vfsStream/issues/23. Now a warning will be thrown in case unlink() is applied on a directory.

Mocking The PDO Object using PHPUnit

I'm having difficulty mocking the PDO object with PHPUnit.
There doesn't seem to be much information on the web about my problem but from what I can gather:
PDO has 'final' __wakeup and
__sleep methods that prevent it from being serialised.
PHPunit's mock object implementation serialises the object at some point.
The unit tests then fail with a PHP error generated by PDO when this occurs.
There is a feature meant to prevent this behavior, by adding the following line to your unit test:
class MyTest extends PHPUnit_Framework_TestCase
{
protected $backupGlobals = FALSE;
// ...
}
Source: http://sebastian-bergmann.de/archives/797-Global-Variables-and-PHPUnit.html
This isnt working for me, my test still produces an error.
Full test code:
class MyTest extends PHPUnit_Framework_TestCase
{
/**
* #var MyTest
*/
private $MyTestr;
protected $backupGlobals = FALSE;
/**
* Prepares the environment before running a test.
*/
protected function setUp()
{
parent::setUp();
}
/**
* Cleans up the environment after running a test.
*/
protected function tearDown()
{
parent::tearDown();
}
public function __construct()
{
$this->backupGlobals = false;
parent::__construct();
}
/**
* Tests MyTest->__construct()
*/
public function test__construct()
{
$pdoMock = $this->getMock('PDO', array('prepare'), array(), '', false);
$classToTest = new MyTest($pdoMock);
// Assert stuff here!
}
// More test code.......
Any PHPUnit pro's give me a hand?
Thanks,
Ben
$backupGlobals does not help you, because this error comes from elsewhere. PHPUnit 3.5.2 (possibly earlier versions as well) has the following code in PHPUnit/Framework/MockObject/Generator.php
if ($callOriginalConstructor &&
!interface_exists($originalClassName, $callAutoload)) {
if (count($arguments) == 0) {
$mockObject = new $mock['mockClassName'];
} else {
$mockClass = new ReflectionClass($mock['mockClassName']);
$mockObject = $mockClass->newInstanceArgs($arguments);
}
} else {
// Use a trick to create a new object of a class
// without invoking its constructor.
$mockObject = unserialize(
sprintf(
'O:%d:"%s":0:{}',
strlen($mock['mockClassName']), $mock['mockClassName']
)
);
}
This "trick" with unserialize is used when you ask getMock to not execute the original constructor and it will promptly fail with PDO.
So, how do work around it?
One option is to create a test helper like this
class mockPDO extends PDO
{
public function __construct ()
{}
}
The goal here is to get rid of the original PDO constructor, which you do not need. Then, change your test code to this:
$pdoMock = $this->getMock('mockPDO', array('prepare'));
Creating mock like this will execute original constructor, but since it is now harmless thanks to mockPDO test helper, you can continue testing.
The best I can think of is to use runkit and redefine the two final methods as protected using runkit_function_redefine.
Dont for get to enable the runkit.internal_override setting in php.ini.
And as ever, as with eval, if runkit seems like the answer, the question is probably wrong :)
You are instantiating your test case in your test case?
$classToTest = new MyTest($pdoMock);
Right now, you are essentially testing your test case. It should be more something like:
$classToTest = new My($pdoMock);

Categories