it-swarm.com.de

Wordpress Unit Testing - Tabellen können nicht erstellt werden

Ich verwende PHPUnit, um mein WP Plugin über die WP Testsuite zu Unit-Testen. Alles funktioniert einwandfrei, außer dass beim Versuch, eine Tabelle mit der setUp-Methode zu erstellen, die Tabelle nicht erstellt wird.

Hier ist mein Code:

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

}

Die Klasse PAO_UnitTestCase ist einfach eine Erweiterung der WP_UnitTestCase-Klasse, die eine Methode enthält - die el-Methode - die einfach alles in eine Datei meiner Wahl schreibt.

Wie Sie sehen können, habe ich die el-Methode verwendet, um

  1. Schreiben Sie die Antwort von dbDelta in das Protokoll
  2. Schreiben Sie die Namen aller vorhandenen Tabellen in das Protokoll

Dem Protokoll zufolge konnte dbDelta die Tabelle erstellen, sie wird jedoch nicht als Teil der vorhandenen Tabellen aufgelistet.

Meine Fragen sind also:

  1. Ist es möglich, Tabellen während des Unit-Tests über PHPUnit zu erstellen?
  2. Wenn ja, was mache ich falsch?

Hoffe mir kann jemand helfen.

Vielen Dank!

Update: Wie in der Diskussion und der akzeptierten Antwort unten zu sehen, werden die Tabellen erstellt, jedoch als TEMPORARY-Tabellen. Sie können die Tabellen zwar nicht über SHOW TABLES anzeigen, aber Sie überprüfen ihre Existenz, indem Sie eine Zeile einfügen und dann versuchen, die Zeile abzurufen.

5
Paolo

Sie haben gerade eine wichtige Funktion der Kerntestsuite entdeckt: Sie erzwingt, dass alle während des Tests erstellten Tabellen temporäre Tabellen sind.

Wenn Sie sich die WP_UnitTestCase::setUp() -Methode ansehen, werden Sie feststellen, dass eine Methode namens start_transaction() aufgerufen wird. Diese start_transaction() -Methode startet eine MySQL-Datenbanktransaktion :

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

Auf diese Weise können alle Änderungen, die Ihr Test in der Datenbank vornimmt, einfach in der Methode tearDown() rückgängig gemacht werden. Dies bedeutet, dass jeder Test mit einer sauberen WordPress-Datenbank beginnt, die von den vorherigen Tests nicht beeinträchtigt wurde.

Sie werden jedoch feststellen, dass start_transaction() auch zwei Methoden mit dem Filter 'query' verknüpft : _create_temporary_tables und _drop_temporary_tables. Wenn Sie sich die Quelle dieser Methoden ansehen, werden Sie feststellen, dass CREATE- oder DROP-Tabellenabfragen stattdessen für temporäre Tabellen gelten:

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

Der Filter 'query' wird auf alle Datenbankabfragen angewendet, die durch $wpdb->query(), die dbDelta() verwendet geleitet werden. Das heißt, wenn Ihre Tabellen erstellt werden, werden sie als temporär Tabellen erstellt.

Also, um diese Tabellen aufzulisten, Ich denke, Sie müssten stattdessen temporäre Tabellen anzeigen: $sql = "SHOW TEMPORARY TABLES LIKE '%'";

Update: In MySQL können Sie die temporären Tabellen nicht wie in den regulären Tabellen auflisten. Sie müssen eine andere Methode verwenden, um zu überprüfen, ob die Tabelle vorhanden ist, z. B. den Versuch, eine Zeile einzufügen.

Aber warum erfordert der Komponententest überhaupt, dass temporäre Tabellen erstellt werden? Denken Sie daran, dass wir MySQL-Transaktionen verwenden, damit die Datenbank sauber bleibt. Wir möchten die Transaktionen jedoch niemals festschreiben, sondern sie immer am Ende des Tests zurücksetzen. Es gibt jedoch einige MySQL-Anweisungen, die ein implizites commit verursachen. Unter diesen sind, wie Sie es erraten haben, CREATE TABLE und DROP TABLE. In den MySQL-Dokumenten heißt es jedoch:

Mit den Anweisungen CREATE TABLE und DROP TABLE wird keine Transaktion festgeschrieben, wenn das Schlüsselwort TEMPORARY verwendet wird.

Um ein implizites Commit zu vermeiden, erzwingt der Testfall, dass alle erstellten oder gelöschten Tabellen temporäre Tabellen sind.

Dies ist keine gut dokumentierte Funktion, aber wenn Sie erst einmal verstanden haben, was los ist, sollte es ziemlich einfach sein, damit zu arbeiten.

9
J.D.