最合适的回答,由SO网友:J.D. 整理而成
您刚刚发现了核心测试套件的一个重要特性:它强制在测试期间创建的任何表都是临时表。
如果你看看WP_UnitTestCase::setUp()
方法你会看到it calls a method called start_transaction()
. 那个start_transaction()
method 启动MySQL database transaction:
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\' ) );
}
它这样做是为了您的测试在数据库中所做的任何更改都可以
rolled back afterward in the tearDown()
method. 这意味着每个测试都从一个干净的WordPress数据库开始,不受之前测试的污染。
但是,您会注意到start_transaction()
还将两个方法挂接到\'query\'
filter: _create_temporary_tables
和_drop_temporary_tables
. 如果你看the source of these methods, 你会发现他们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;
}
The
\'query\'
过滤器应用于通过的所有数据库查询
$wpdb->query()
,
which dbDelta()
uses. 这意味着在创建表时,它们将被创建为临时表。
因此,为了列出这些表,我认为您必须显示临时表:$sql = "SHOW TEMPORARY TABLES LIKE \'%\'";
删除>
Update: MySQL不允许您像列出常规表一样列出临时表。您必须使用另一种方法检查表是否存在,例如尝试插入行。
但是为什么单元测试用例首先需要创建临时表呢?请记住,我们正在使用MySQL事务,以便数据库保持干净。但是,我们不想提交事务,我们希望总是在测试结束时回滚它们。但是有some MySQL statements that will cause an implicit commit. 其中包括,你猜对了,CREATE TABLE
和DROP TABLE
. 但是,根据MySQL文档:
CREATE TABLE
和DROP TABLE
如果TEMPORARY
使用关键字。
因此,为了避免隐式提交,测试用例强制创建或删除的任何表都是临时表。
这不是一个文档化很好的特性,但一旦您了解了发生了什么,应该很容易使用它。