I have a PHP project, with the following project structure.
php_test_app
src
Vegetable.php
tests
StackTest.php
VegetableTest.php
The code of these files is shown below. I use PDT and PTI in Eclipse. PHPUnit in Eclipse recognizes that VegetableTest.php belongs to Vegetable.php, because you can toggle between them using the toggle button.
I first try to run the test code by selecting the tests directory in the PHP Explorer and click Run Selected PHPUnit Test. It runs both tests, both the VegetableTest fails with the following trace: Fatal error: Class 'Vegetable' not found in /Users/erwin/Documents/workspace/php_test_app/tests/VegetableTest.php on line 8. A similar issue was posted here: phpunit cannot find Class, PHP Fatal error.
Indeed, I haven't included my source code yet, so now I uncomment the include in VegetableTest.php, shown below. If I now try to run the tests in the same way, PHPUnit does not recognize any test code! Even the StackTest, which is unaltered, is not recognized.
How should I make the include such that the unit tests are
recognized?
Do I need to specify the full path, or just the name of
the file in which the class is defined?
Changing the include statement also doesn't work; I have tried the following.
include 'Vegetable.php';
include 'src/Vegetable.php';
include '../src/Vegetable.php';
Vegetable.php
<?php
// base class with member properties and methods
class Vegetable {
var $edible;
var $color;
function Vegetable($edible, $color="green")
{
$this->edible = $edible;
$this->color = $color;
}
function is_edible()
{
return $this->edible;
}
function what_color()
{
return $this->color;
}
} // end of class Vegetable
// extends the base class
class Spinach extends Vegetable {
var $cooked = false;
function Spinach()
{
$this->Vegetable(true, "green");
}
function cook_it()
{
$this->cooked = true;
}
function is_cooked()
{
return $this->cooked;
}
} // end of class Spinach
StackTest.php
<?php
class StackTest extends PHPUnit_Framework_TestCase
{
public function testPushAndPop()
{
$stack = array();
$this->assertEquals(0, count($stack));
array_push($stack, 'foo');
$this->assertEquals('foo', $stack[count($stack)-1]);
$this->assertEquals(1, count($stack));
$this->assertEquals('foo', array_pop($stack));
$this->assertEquals(0, count($stack));
}
}
?>
VegetableTest.php
<?php
// require_once ('../src/Vegetable.php');
class VegetableTest extends PHPUnit_Framework_TestCase
{
public function test_constructor_two_arguments()
{
$tomato = new Vegetable($edible=True, $color="red");
$r = $tomato.is_edible();
$this->assertTrue($r);
$r = $tomato.what_color();
$e = "red";
$this->assertEqual($r, $e);
}
}
class SpinachTest extends PHPUnit_Framework_TestCase
{
public function test_constructor_two_arguments()
{
$spinach = new Spinach($edible=True);
$r = $spinach.is_edible();
$this->assertTrue($r);
$r = $spinach.what_color();
$e = "green";
$this->assertEqual($r, $e);
}
}
?>
phpunit --bootstrap src/Vegetable.php tests instructs PHPUnit to load src/Vegetable.php before running the tests found in tests.
Note that --bootstrap should be used with an autoloader script, for instance one generated by Composer or PHPAB.
Also have a look at the Getting Started section on PHPUnit's website.
Related
I'm trying to unit-test my class-function using PHPUnit, but I keep running into Class not found error, even though it is present.
Here's my func.php where the class is defined:
<?php
class func {
public function url($var) {
//do something
return myvalue;
}
?>
And here's funcCase.php where the Test class is defined:
<?php
require 'func.php';
require 'PHPUnit.php';
class funcTest extends PHPUnit_TestCase {
// contains the object handle of the string class
var $box;
// constructor of the test suite
function funcTest($name) {
$this->PHPUnit_TestCase($name);
}
// called before the test functions will be executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function setUp() {
// create a new instance of String with the
// string 'abc'
$this->box = new func();
}
// called after the test functions are executed
// this function is defined in PHPUnit_TestCase and overwritten
// here
function tearDown() {
// delete your instance
unset($this->box);
}
// test the url
function testurl() {
$result = $this->box->url('myvalue');
$expected = 'myvalue';
echo $result;
$this->assertTrue($result == $expected);
}
}
?>
And the funcTest.php which runs the PHPTestSuite:
<?php
require_once 'funcCase.php';
require_once 'PHPUnit.php';
$suite = new PHPUnit_TestSuite("funcTest");
$result = PHPUnit::run($suite);
echo $result -> toString();
?>
When running the funcTest.php using phpunit funcTest.php I get this error:
TestCase funcTest->testurl() failed: expected TRUE, actual FALSE
Class 'funcTest' could not be found in 'C:\xampp\htdocs\funcTest.php'.
Why am I getting this if the funcTest class is defined and funcCase.php is included in funcTest.php?
I'm trying to override a built in php function using a namespaced test like this:
Original Class:
<?php
namespace My\Namespace;
class OverrideCommand
{
public function myFileExists($path)
{
return file_exists($path);
}
}
Unit Test
<?php
namespace My\Namespace\Test\Unit\Console\Command;
function file_exists($path)
{
return true;
}
class OverrideCommandTest extends \PHPUnit_Framework_TestCase
{
/**
* #var OverrideCommand
*/
protected $command;
protected function setUp()
{
$this->command = new \My\Namespace\OverrideCommand();
}
public function testMyFileExists()
{
$result = $this->command->myFileExists('some/path/file.txt');
$this->assertTrue($result);
}
}
In this case the file_exists function in my test should always return true, however when I run PHPUnit I get:
PHPUnit 5.7.21 by Sebastian Bergmann and contributors.
There was 1 failure:
1) My\Namespace\Test\Unit\Console\Command\OverrideCommandTest::testMyFileExists
Failed asserting that false is true.
It's as if the namespaced function is being ignored and it's just calling the built in function instead, am I missing something?
According to your code sample, you define the function file_exists() in the namespace My\Namespace\Test\Unit\Console\Command:
namespace My\Namespace\Test\Unit\Console\Command;
function file_exists($path)
{
return true;
}
so of course, you actually never override the function file_exists() in the root namespace.
As far as I know, you can't do that. Whenever you would try to define a function that already exists, a fatal error will be triggered, see https://3v4l.org/JZHcp.
However, if what you want to achieve is asserting that OverrideCommand::myFileExists() returns true if a file exists, and false if it doesn't, you can do one of the following
Refer to files which do and do not exist in your test
public function testMyFileExistsReturnsFalseIfFileDoesNotExist()
{
$command = new OverrideCommand();
$this->assertTrue($command->myFileExists(__DIR__ . '/NonExistentFile.php');
}
public function testMyFileExistsReturnsTrueIfFileExists()
{
$command = new OverrideCommand();
$this->assertTrue($command->myFileExists(__FILE__);
}
Mock the file system
Use https://github.com/mikey179/vfsStream to mock the file system.
Note: For your example, I would recommend the former.
First of all, I'm new in PHPUnit testing and PHP, sorry if I'm missing something too obvious.
Ok, now, for my question: I'm using a Virtual File System called VfsStream to test the function unlink( ). For some reason in my testing this error occurred:
[bianca#cr-22ncg22 tests-phpunit]$ phpunit
PHPUnit 4.6.10 by Sebastian Bergmann and contributors.
Configuration read from /var/www/html/tests-phpunit/phpunit.xml
E
Time: 27 ms, Memory: 4.50Mb
There was 1 error:
1) test\UnlinkTest\UnlinkTest::testUnlink
Object of class App\Libraries\Unlink could not be converted to string
/var/www/html/tests-phpunit/test/UnlinkTest.php:21
/home/bianca/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:153
/home/bianca/.composer/vendor/phpunit/phpunit/src/TextUI/Command.php:105
FAILURES!
Tests: 1, Assertions: 0, Errors: 1.
I know is something with my Unlink class and what it's returning, but I don't know what is.
The class I'm testing:
class Unlink {
public function unlinkFile($file) {
if (!unlink($file)) {
echo ("Error deleting $file");
}
else {
echo ("Deleted $file");
}
return unlink($file);
}
}
?>
The class where my tests are:
use org\bovigo\vfs\vfsStream;
use App\Libraries\Unlink;
class UnlinkTest extends \PHPUnit_Framework_TestCase {
public function setUp() {
$root = vfsStream::setup('home');
$removeFile = new Unlink();
}
public function tearDown() {
$root = null;
}
public function testUnlink() {
$root = vfsStream::setup('home');
$removeFile = new Unlink();
vfsStream::newFile('test.txt', 0744)->at($root)->setContent("The new contents of the file");
$this->$removeFile->unlinkFile(vfsStream::url('home/test.txt'));
$this->assertFalse(var_dump(file_exists(vfsStream::url('home/test.txt'))));
}
}
?>
Anybody can help me to fix it?
The error you're getting is because initially you create this local variable:
$removeFile = new Unlink();
But then you refer to it as $this->$removeFile when you do:
$this->$removeFile->unlinkFile(vfsStream::url('home/test.txt'));
That's not correct; you might use that where you have a class variable and you want to refer to it dynamically. e.g.
class YourClass {
public $foo;
public $bar;
public function __construct() {
$this->foo = 'hello';
$this->bar = 'world';
}
public function doStuff() {
$someVariable = 'foo';
echo $this->$someVariable; // outputs 'hello'
}
}
All you need to do is get rid of the $this, and change it to:
$removeFile->unlinkFile(vfsStream::url('home/test.txt'));
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
So I have started to use PHPUnit to test my programs.
I have this problem where I get an error when I try to test a program where the program is gonna control if a webpage exists.
The code:
<?php
class RemoteConnect
{
public function connectToServer($serverName=null)
{
if($serverName==null){
throw new Exception("That's not a server name!");
}
$fp = fsockopen($serverName,80);
return ($fp) ? true : false;
}
public function returnSampleObject()
{
return $this;
}
}
?>
And the test code to it:
<?php
require_once('RemoteConnect.php');
class RemoteConnectTest extends PHPUnit_Framework_TestCase
{
public function setUp(){ }
public function tearDown(){ }
public function testConnectionIsValid()
{
// test to ensure that the object from an fsockopen is valid
$connObj = new RemoteConnect();
$serverName = 'www.google.com';
$this->assertTrue($connObj->connectToServer($serverName) !== false);
}
}
?>
They are in the same directory named: PHPUnit inside the www (C:\wamp\www\PHPUnit)
But I don't understand why i get the error (Fatal error: Class 'PHPUnit_Framework_TestCase' not found in C:\wamp\www\PHPUnit\RemoteConnectTest.php on line 5)
My PHPUnit package path is (C:\wamp\bin\php\php5.3.10\pear\PHPUnit)
I have tried making a program MailSender, where it sends a mail with a text content in it, that was just for using PEAR. And it succeded, but I don't understand why this doesn't work.
Regards
Alex
Don't you need to have the PHPUnit_Framework_TestCase class available in RemoteConnectTest.php?
Add the following on top of the file:
require_once 'PHPUnit/Autoload.php';