私はWPテストスイートの上にある私のWPプラグインをユニットテストするためにPHPUnitを使っています。 setUpメソッドでテーブルを作成しようとしたときにテーブルが作成されないことを除けば、すべてうまくいきます。
これが私のコードです:
class Test_Db extends PAO_UnitTestCase {
function setUp() {
parent::setUp();
global $wpdb;
$sql = "CREATE TABLE {$wpdb->prefix}mytest (
id bigint(20) NOT NULL AUTO_INCREMENT,
column_1 varchar(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$this->el(dbDelta($sql));
}
function tearDown() {
parent::tearDown();
}
function test_db_stuff(){
global $wpdb;
$sql = "SHOW TABLES LIKE '%'";
$results = $wpdb->get_results($sql);
foreach($results as $index => $value) {
foreach($value as $tableName) {
$this->el($tableName);
}
}
}
}
クラスPAO_UnitTestCaseは、単純にWP_UnitTestCaseクラスを拡張したもので、1つのメソッド(elメソッド)が含まれています。これは、選択したファイルに単純に何でも記録します。
ご覧のとおり、私はelメソッドを使用して
ログによると、dbDeltaはテーブルを作成できましたが、既存のテーブルの一部としてリストされていません。
だから私の質問は次のとおりです。
誰かが私を助けることができると思います。
ありがとうございます。
更新: 以下の議論と受け入れられた答えに見られるように、テーブルは作成されますがTEMPORARYテーブルとして。 SHOW TABLESでテーブルを見ることはできませんが、行を挿入してから行を検索してその存在を確認します。
コアテストスイートの重要な機能を発見しました。テスト中に作成されたすべてのテーブルを一時テーブルに強制します。
WP_UnitTestCase::setUp()
メソッドを見ると、 start_transaction()
というメソッドを呼び出している がわかります。 start_transaction()
method は MySQLデータベーストランザクション を開始します:
function start_transaction() {
global $wpdb;
$wpdb->query( 'SET autocommit = 0;' );
$wpdb->query( 'START TRANSACTION;' );
add_filter( 'query', array( $this, '_create_temporary_tables' ) );
add_filter( 'query', array( $this, '_drop_temporary_tables' ) );
}
これにより、テストでデータベースに加えられた変更を tearDown()
メソッドで後でロールバック することができます。つまり、各テストは、以前のテストで汚染されていない、きれいなWordPressデータベースで開始されます。
ただし、start_transaction()
は2つのメソッドを 'query'
フィルター :_create_temporary_tables
および_drop_temporary_tables
にもフックすることに注意してください。 これらのメソッドのソース を見ると、CREATE
またはDROP
テーブルクエリが一時テーブル用であることがわかります。
function _create_temporary_tables( $query ) {
if ( 'CREATE TABLE' === substr( trim( $query ), 0, 12 ) )
return substr_replace( trim( $query ), 'CREATE TEMPORARY TABLE', 0, 12 );
return $query;
}
function _drop_temporary_tables( $query ) {
if ( 'DROP TABLE' === substr( trim( $query ), 0, 10 ) )
return substr_replace( trim( $query ), 'DROP TEMPORARY TABLE', 0, 10 );
return $query;
}
'query'
フィルタは、$wpdb->query()
、 dbDelta()
が使用する を介して渡されるすべてのデータベースクエリに適用されます。つまり、テーブルが作成されると、それらはtemporaryテーブルとして作成されます。
したがって、これらのテーブルをリストするには、 代わりに一時テーブルを表示する必要があると思います:$sql = "SHOW TEMPORARY TABLES LIKE '%'";
更新:MySQLでは、通常のテーブルと同様に一時テーブルをリストすることはできません。行の挿入を試みるなど、テーブルが存在するかどうかを確認する別の方法を使用する必要があります。
しかし、なぜユニットテストケースでは、最初に一時テーブルを作成する必要があるのですか?データベースをクリーンな状態に保つために、MySQLトランザクションを使用していることに注意してください。ただし、トランザクションをコミットすることは望みません。テストの終了時には常にロールバックしたいと考えています。しかし、 implicitcommit を引き起こすMySQLステートメントがいくつかあります。これらの中には、CREATE TABLE
とDROP TABLE
という推測があります。ただし、MySQLのドキュメントによると:
TEMPORARY
キーワードが使用されている場合、CREATE TABLE
およびDROP TABLE
ステートメントはトランザクションをコミットしません。
したがって、暗黙的なコミットを回避するために、テストケースは作成または削除されたテーブルを一時テーブルに強制します。
これは十分に文書化された機能ではありませんが、何が起こっているのかを理解したら、作業がかなり簡単になります。