私は次のテストケースを持っています:
include_once('../Logger.php');
class LoggerTest extends PHPUnit_Framework_TestCase {
public function providerLogger() {
return new Logger;
}
/**
* @dataProvider providerLogger
*/
public function testAddStream($logger) {
$this->assertTrue(false);
}
}
PHPUnitで実行すると、次のようになります。
PHPUnit 3.4.14 by Sebastian Bergmann.
..........
Time: 0 seconds, Memory: 5.75Mb
OK (1 tests, 0 assertions)
テストは失敗するはずですが、失敗しません。私は持ってみました:
public function providerLogger() {
return array(new Logger);
}
しかし、私は得ます:
The data provider specified for LoggerTest::testAddStream is invalid.
static
(マニュアルに記載されているように)を宣言しようとしましたが、それでも違いはありません。
以前も同じように機能していたことを覚えていますが、間違っている可能性があります。何が足りないのですか?
よろしくお願いします。
PHPUnit 3.4.14(PEARから取得)on PHP 5.3.
マイナーアップデート:バージョン3.2以降(またはその周辺)、インスタンスメソッドをプロバイダーとして使用しても問題ありません。コメントを見てください
プロバイダーは次のようになっている必要があります。
public static function providerLogger() {
return array(
array(new Logger)
);
}
まず第一に:3.3より前のバージョンのphpunitを使用している場合、メソッドはstaticでなければなりません。
array sは重要です。理解するのはそれほど難しいことではありません。外側の配列には、テストが呼び出される反復ごとに1つの値があります。ここでは、テストは1回だけ呼び出されます。内部配列は、テストが呼び出される(順序で)パラメーターです。テストでは正確に1つのパラメーターが必要であるため、内部配列には常に正確に1つの値が必要です。別の小さな例
public static function addTestProvider () {
return array(
/* First + Second = third? */
array(1,4,5),
array(3,3,6),
array(5,5,6)
);
}
public function testAdd ($a, $b, $result) {
$this->assertEquals($result, $a + $b);
}
ここでtestAddは3回実行され、1秒ごとに1つレベルarrayであり、内部のarray sから値を受け取ります。テストが失敗し、データセットの反復(5 + 5は6ではないためここでは#3;))アサーションが失敗したというメッセージが表示されることに気付くかもしれません。
同じ問題が発生しましたが、空のコンストラクターを削除すると、自動生成されて解決しました。なぜこれで問題が解決するのかわかりません。クラスのような名前のテストメソッドもありませんでした。プロバイダーメソッドは静的である必要はありません。これまでのところ、静的なしでテストを実行しています。しかし、プロバイダーメソッドを静的にすると実行されます
<?php
require_once 'calculator.php';
/**
* Calculator test case.
*/
class CalculatorTest extends PHPUnit_Framework_TestCase {
/**
* @var Calculator
*/
private $Calculator;
/**
* Prepares the environment before running a test.
*/
protected function setUp() {
parent::setUp ();
// TODO Auto-generated CalculatorTest::setUp()
$this->Calculator = new Calculator(/* parameters */);
}
/**
* Cleans up the environment after running a test.
*/
protected function tearDown() {
// TODO Auto-generated CalculatorTest::tearDown()
$this->Calculator = null;
parent::tearDown ();
}
/**
* Constructs the test case.
*/
public function __construct() {
// TODO Auto-generated constructor
}
/**
* Tests Calculator->add()
*
* @dataProvider provider
*/
public function testAdd($a, $b, $c) {
// TODO Auto-generated CalculatorTest->testAdd()
//$this->markTestIncomplete ( "add test not implemented" );
//$this->Calculator->add(/* parameters */);
$this->assertEquals($this->Calculator->add($a, $b), $c);
}
public static function provider()
{
return array(
array(1, 1, 1),
array(1, 1, -1),
array(4, 2, 2),
array(1, 1, 1)
);
}
}
コードの完全なセットです
また、データプロバイダーを直接チェーンすることはできないこともわかりました。
class ProviderTest extends PHPUnit_Framework_TestCase {
public function provider() {
return array(array('test'));
}
/**
* @dataProvider provider
*/
public function providerTest1($test) {
$this->assertTrue($test);
return array(array($test));
}
/**
* @dataProvider providerTest1
*/
public function providerTest2($test) {
$this->assertEquals('test', $test);
}
}
どうやら、PHPUnitはテストを実行する前にすべてのプロバイダー関数を呼び出すため、個別のプロバイダー関数を使用してテスト結果データを他のテストにフィードすることもできません。あなたができる最善のことは、シミュレートすることです:
class ProviderTest extends PHPUnit_Framework_TestCase {
private $provider_data = array();
public function provider() {
return array(array('test'));
}
/**
* @dataProvider provider
*/
public function testProvider1($test) {
$this->assertFalse(empty($test));
array_Push($this->provider_data, array($test));
}
/**
* @depends testProvider1
*/
public function testProvider2($test = NULL) {
if(is_null($test)) {
// simulate a provider
foreach($this->provider_data as $row) {
call_user_func_array(array($this, __METHOD__), $row);
}
} else {
$this->assertEquals('test', $test);
}
}
}