Jak na PHPUnit a NETTE__?

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
ZETCHA
Člen | 59
+
0
-

Chtěl bych začít programovat pomocí testů (TDD).
Nainstaloval jsem si PHPUnit a nastavil ho v NetBeans.

Připravil první test:

<?php
require_once 'PHPUnit/Framework.php';
require_once '../document_root/index.php';

class Admin_MenuModelTest extends PHPUnit_Framework_TestCase
{
    protected $object;

    protected function setUp()
    {
        $this->object = new Admin_MenuModel;
    }

    protected function tearDown()
    {
    }

    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));
    }

}
?>

Ať napíšu jakýkoli test, skončím u ‚<h1>Method is not implemented</h1>PHPUnit 3.4.12 by Sebastian Bergmann.‘. Nevíte co dělám špatně?
Díky za radu.

radas
Člen | 218
+
0
-

Taky se tak u mě děje. PHPUnit spouštím přes Eclipse. Máš v config.ini sekci [console], popř. test na spuštění v konzoli v souboru bootstrap.php? Něco k tomu je v tutoriálu Návštěvní kniha v Nette s testy TDD.

Nicméně i přes toto hlášení mi test projde vypíše OK (1 test, 5 assertions).

Možná ti pomůže najít příčinu zdrojový kód.

Ondřej Mirtes
Člen | 1536
+
0
-

Taky bych si dal pozor na to, že při spuštění testů zbytečně spouštíš aplikaci. Nastavil bych si tedy v testovacím bootstrapu nějakou proměnnou a v aplikačním bootstrapu bych volal $application->run() jen v případě, že tahle proměnná není nastavená.

radas
Člen | 218
+
0
-

Je to tak, stačí mít v bootstrap.php tuto podmínku:

<?php
 if (!Environment::isConsole())
   $application->run();
?>
ZETCHA
Člen | 59
+
0
-

Tak jsem to upravil. Hláška zmizela, ale …
Výstup na output je ‚PHPUnit 3.4.12 by Sebastian Bergmann.‘
a žádný test se neprovede. :-(

Když vyhodím

<?php
   protected function setUp()
    {
//        $this->object = new Admin_MenuModel();  <-- tohle vyhodím
    }
?>

Tak se test provede! Mám hledat chybu v Admin_MenuModel?

Ten vypadá takto:

<?php
class Admin_MenuModel extends BaseModel
// BaseModel extends Model
{
    private $menu = 'menu';


    public function listMenu(){
        $query = dibi::query('SELECT * FROM '.$this->menu.' ORDER BY type, sort');
        return count($query) > 0 ? $query->fetchAll() : FALSE;
    }


    public function getMenu($id)
    {
        $query = dibi::query('SELECT * FROM '.$this->menu.' WHERE id ='.$id);
        return count($query) > 0 ? $query->fetch() : FALSE;
    }


    public function updateMenu($id, $data)
    {
        // ještě není doděláno
    }

}
?>

Nic proč by to nejelo nevidím.

radas
Člen | 218
+
0
-

U mě ten tvůj test projde s výsledkem OK (1 test, 5 assertions). Nevím, jestli to nemůže být nastavením v NetBeans. Já mám v Eclipse toto:

Location: C:\web\prg\php\php.exe

Working Directory: ${container_loc}

Arguments: „C:\web\prg\php\phpunit“ ${resource_name}

kde za ${container_loc} se dosadí aktuální adresář, ve kterém je *Test.php

a za ${resource_name} se dosadí jméno aktuálního souboru s testem.

ZETCHA
Člen | 59
+
0
-

No nastavení v NetBeans je jedna věc, ale stejnej výsledek dostanu z příkazové řádky.
phpunit MenuModelTest hodí stejnej výsledek ‚PHPUnit 3.4.12 by Sebastian Bergmann.‘ a šlus!
Žádá hláška žádný test, nic.

radas
Člen | 218
+
0
-

A nemůže být příčinou nějaký kód v metodě startup() v BaseModel, popř. v Model? Jejich kód tu není. Třeba jestli tam náhodou nestartují sessions. To bys pak musel řešit dalším parametrem phpunit a použitím souboru bootstrap.php nebo jinak pojmenovaného, který bys předal jako parametr v příkazové řádce. Tady je k tomu něco málo.

ZETCHA
Člen | 59
+
0
-

Hmm sem se přehlédl, BaseModel extends Object a ne Model. BaseModel je čistej jak lilium (zatím).

<?php

abstract class BaseModel extends Object {

}
?>

Sessions nikde ručně nespouštím.

ZETCHA
Člen | 59
+
0
-

Ještě přikládám bootstrap pro testy, jestli v něm není ten problém.

<?php
require_once 'PHPUnit/Framework.php';
define('WWW_DIR', dirname(__FILE__).'/../document_root');

// absolute filesystem path to the application root
define('APP_DIR', WWW_DIR . '/../app');

// absolute filesystem path to the libraries
define('LIBS_DIR', WWW_DIR . '/../libs');

// Step 1: Load Nette Framework
// this allows load Nette Framework classes automatically so that
// you don't have to litter your code with 'require' statements
require LIBS_DIR . '/Nette/loader.php';


// Step 2: Configure environment
// 2a) enable Nette\Debug for better exception and error visualisation
if ( substr($_SERVER['HTTP_HOST'], -4, 4) != '.loc' )
{
	Environment::setMode(Environment::PRODUCTION);
}
else
{
	Environment::setMode(Environment::DEVELOPMENT);
}

Debug::enable(Debug::DETECT, APP_DIR . '/log/error.log', array(
    'From' => 'nette@%host%',
    'To'   => 'error@abc.cz',
    'Subject' => 'Chyba na serveru %host%',
    'Body' => '%date% - %message%. Pro více informací jděte error log.',
));



// 2b) load configuration from config.ini file
Environment::loadConfig();



// Step 3: Configure application

	//get and setup a front controller
	$application = Environment::getApplication();
	$application->errorPresenter = 'Error';

	// Configure database connection
	dibi::connect(Environment::getConfig('database'));



// Step 4: Setup application router
$router = $application->getRouter();

// mod_rewrite detection
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) {

  $router[] = new Route('admin/<presenter>/<action>/<id>', array(
    'module'    => 'Admin',
    'presenter' => 'Default',
    'action'    => 'default',
    'id'        => null
  ));

$router[] = new Route('index.php', array(
	'module' => 'Front',
	'presenter' => 'Page',
), Route::ONE_WAY);

$router[] = new Route('<presenter>/<action>/<id>', array(
	'presenter' => 'Front:Page',
	'action' => 'default',
	'id' => NULL,
));

} else {
	$router[] = new SimpleRouter('Front:Page:default');
}



 if (!Environment::isConsole()){
   $application->run();
 }
?>
radas
Člen | 218
+
0
-

No tak já mám bootstrap.php podobný, akorát tam nevkládám PHPUnit/Framework.php ani index.php – tyto dva řádky mám až v souboru s testem. A to samé i dibi::connect(), tu volám až v metodě setUp() v testu samotném.

ZETCHA
Člen | 59
+
0
-

No já po úpravách už taky nenačítám index, ale jen ten bootstrap.php a tím to končí.

ZETCHA
Člen | 59
+
0
-

Hurá!!!

Takže, celej problém byl v tom připojování databáse v bootstrapu!
To jsem vyhodil a dal to přímo do testu jak jsi mi radas poradil a jede.

Velmi ti radas děkuji za tvůj čas a rady.

Honza Marek
Člen | 1664
+
0
-

Proti problémům s dibi::connect lze bojovat vypnutím backupStaticAttributes a backupGlobals (viz někde dokumentace php unitu).