I have a MacBook Pro, installed PEAR, installed PHPUnit, so at the command line I can type phpunit and I get the usage help.
Now I want to get a test going so that I can build from there.
I have a file named index.php with this content:
<?php
require_once '?????';
class Product {
protected $id;
public function __construct($id)
{
$this->id = $id;
}
public function get_id()
{
return $this->id;
}
}
class ProductTest extends PHPUnit_Framework_TestCase
{
function testBasis()
{
$instance = new Product(1);
$this->assertInstanceOf('Product',$instance);
$this->assert($instance->get_id(), 1);
}
}
At the command line, I want to go to the directory in which the file is located and type something like:
phpunit ?????
What are the next steps so that I am able to test the above class with PHPUnit from the command line?
If you installed phpunit proprely you don't need the include line .
class ProductTest extends PHPUnit_Framework_TestCase
Save the file ProductTest.php
At the command line browse using "cd" to the directory where you saved ProductTest.php
If you installed phpunit proprely you should be able to enter phpunit --verbose ProductTest.php
Your ProductTest.php file will have to look like this :
<?php
class Product {
protected $id;
public function __construct($id)
{
$this->id = $id;
}
public function get_id()
{
return $this->id;
}
}
class ProductTest extends PHPUnit_Framework_TestCase
{
function testBasis()
{
$instance = new Product(1);
$this->isInstanceOf('Product',$instance);
$this->assertEquals($instance->get_id(), 1);
}
}
?>
At the command line running phpunit --verbose ProductTest , will output :
PHPUnit 3.4.13 by Sebastian Bergmann.
ProductTest
.
Time: 0 seconds, Memory: 6.50Mb
OK (1 test, 1 assertion)
dorin#ubuntu:/var/www$ phpunit --verbose ProductTest
PHPUnit 3.4.13 by Sebastian Bergmann.
ProductTest
.
Time: 0 seconds, Memory: 6.50Mb
OK (1 test, 1 assertion)
I upgraded the phpunit version from 3.4 to 3.6 using these instructions and it solved my assertInstanceOf missing function problem. if someone came on this thread for looking same problem, should think to upgrade to latest version of phpunint test
Related
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
I am new to PHP and trying to write a basic test case that verifies a connection to a database. Clearly I'm missing something fundamental. I understand from reading the manual online that this involves extending the PHPUnit_Extensions_Database_TestCase and implementing a couple of functions (getConnection() and getDataSet()). Please see my code below of the simplest case I could come up with to still get the head-scratching issue I'm encountering:
<?php
abstract class DBTest extends PHPUnit_Extensions_Database_TestCase
{
public function getConnection()
{
return true;
}
public function getDataSet()
{
return true;
}
}
?>
As you can see, the tests do nothing but return true. However, when I do a "phpUnit DBTest" I get the following message back:
PHPUnit 4.2.6 by Sebastian Bergmann.
F
Time: 1 ms, Memory: 7.50Mb
There was 1 failure:
1) Warning
No tests found in class "DBTest".
FAILURES!
Tests: 1, Assertions: 0, Failures: 1.
What am I missing? Any advice would help. Thanks.
PHPUnit complains about not finding any test. You must add at least a test method:
<?php
abstract class DBTest extends PHPUnit_Extensions_Database_TestCase
{
public function getConnection()
{
return true;
}
public function getDataSet()
{
return true;
}
public function testDummy()
{
$this->assertTrue(true);
}
}
?>
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.
I use a class to execute a testsuite with PhpUnit like :
$suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework');
$suite->addTestSuite('ClassOne');
$suite->addTestSuite('ClassTwo');
return $suite;
To start the unit test :
# phpunit --stop-on-failure TestSuite.php
If "ClassOne" has an error or exception, the test continue with "ClassTwo".
How I could stop all the testsuites if the first test failed?
Works with PHPUnit 3.5.14
Using the code below the outputs are as expected:
Two fails running it normally:
phpunit AllTests.php
PHPUnit 3.5.14 by Sebastian Bergmann.
FF
Time: 0 seconds, Memory: 6.25Mb
There were 2 failures:
1) Framework_AssertTest::testFails
Failed asserting that <boolean:true> matches expected <boolean:false>.
/home/edo/test/AllTests.php:7
2) Other_AssertTest::testFails
Failed asserting that <boolean:true> matches expected <boolean:false>.
/home/edo/test/AllTests.php:13
FAILURES!
Tests: 2, Assertions: 2, Failures: 2.
and one fail running it with --stop-on-failure
phpunit --stop-on-failure AllTests.php
PHPUnit 3.5.14 by Sebastian Bergmann.
F
Time: 0 seconds, Memory: 6.25Mb
There was 1 failure:
1) Framework_AssertTest::testFails
Failed asserting that <boolean:true> matches expected <boolean:false>.
/home/edo/test/AllTests.php:7
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
AllTests.php
<?php
class Framework_AssertTest extends PHPUnit_Framework_TestCase {
public function testFails() {
$this->assertSame(false, true);
}
}
class Other_AssertTest extends PHPUnit_Framework_TestCase {
public function testFails() {
$this->assertSame(false, true);
}
}
class Framework_AllTests
{
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework');
$suite->addTestSuite('Framework_AssertTest');
$suite->addTestSuite('Other_AssertTest');
return $suite;
}
}
class Other_AllTests
{
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('PHPUnit Framework');
$suite->addTestSuite('Other_AssertTest');
return $suite;
}
}
class AllTests
{
public static function suite()
{
$suite = new PHPUnit_Framework_TestSuite('PHPUnit');
$suite->addTest(Framework_AllTests::suite());
return $suite;
}
}
As a side node. If you look at the documentation of the current version only "suites by file system" and "suites by xml config" are explained options. Just to keep that in mind if you can migrate at the point.
Sounds like a bug in phpunit. Upgrade phpunit to the latest version. If that does not help, open a bug report.
In my TDD project I am trying to test a method in an abstract class.
abstract class Database_Mapper_Abstract
{
public function setTable($sTablename){
return('foo');
}
}
This is the way I wrote my simple test:
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$oMock->expects($this->once())
->method('setTable')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$this->assertEquals('foo',$oMock->setTable());
}
When I run this test i get the following error:
PHPUnit 3.5.13 by Sebastian Bergmann.
E
Time: 1 second, Memory: 6.75Mb
There was 1 error:
1)
Database_Mapper_AbstractTest::testCanSetTable
Missing argument 1 for
Database_Mapper_Abstract::setTable(), called in
K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php
on line 15 and defined
K:\xampp\htdocs\library\Database\Mapper\Abstract.php:4
K:\xampp\htdocs\tests\library\Database\Mapper\Abstract.php:15
FAILURES! Tests: 1, Assertions: 0,
Errors: 1.
The way I understand this is that it can't find the argument for the setTable function.
But I set it with the with() method. I also tried with('foo'). That also doesn't help me.
Does anyone have an idea?
Testing an abstract class:
For testing an abstract class you don't want to use the "create behavior methods".
Just getMockForAbstractClass() like this:
<?php
abstract class JCMS_Database_Mapper_Abstract
{
public function setTable($sTablename){
return $sTablename."_test";
}
}
class myTest extends PHPUnit_Framework_TestCase {
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$this->assertEquals('foo_test', $oMock->setTable('foo'));
}
}
You just use the mocking functionality to create an instance of that abstract class and test against that.
It's only a shortcut for writing
class MyDataMapperAbstractTest extends JCMS_Database_Mapper_Abstract {
// and filling out the methods
}
The actual error:
What happens is that you have a method with one parameter:
public function setTable($sTablename){
but you call it with zero paremters:
$oMock->setTable()
so you get an error from PHP and if PHP throws a warnings PHPUnit will show you an error.
Reproduce:
<?php
abstract class JCMS_Database_Mapper_Abstract
{
public function setTable($sTablename){
return('foo');
}
}
class myTest extends PHPUnit_Framework_TestCase {
public function testCanSetTable(){
$oMock = $this->getMockForAbstractClass('JCMS_Database_Mapper_Abstract');
$oMock->expects($this->once())
->method('setTable')
->with($this->equalTo('foo'))
->will($this->returnValue('foo'));
$this->assertEquals('foo',$oMock->setTable());
}
}
Results in:
phpunit blub.php
PHPUnit 3.5.13 by Sebastian Bergmann.
E
Time: 0 seconds, Memory: 3.50Mb
There was 1 error:
1) myTest::testCanSetTable
Missing argument 1 for JCMS_Database_Mapper_Abstract::setTable(), called in /home/.../blub.php on line 19 and defined
Fixing
Change:
$this->assertEquals('foo',$oMock->setTable());
to
$this->assertEquals('foo',$oMock->setTable('foo'));
then you don't get a PHP Warning and it should work out :)