6

I've started to incorporate unit testing in my build. I have a class that creates a database table and a database version option.

I have no idea how to test if the table and option are being created. Here's the class

class Safety_links_Create_Database {

    public function __construct() {
        $this->create_db();
    }

    /**
     * Get the databse version
     * @return string the databse version
     */
    public function get_db_version() {
        $database_version = SAFETY_LINKS_DB_VERSION;
        return $database_version;
    }


    public function get_table_name() {
        $table_name = SAFETY_LINKS_DB_TABLE_NAME;
        return $table_name;
    }

    public function get_db_option_name() {
        $option_name = SAFETY_LINKS_DB_OPTION_NAME;
        return $option_name;
    }

    public function get_charset() {
        $charset = SAFETY_LINKS_DB_CHARSET_NAME;
        return $charset;
    }

    public function check_table_name() {
        $table_name = $this->get_table_name();
        $check_name = $GLOBALS['wpdb']->get_var("show tables like '$table_name'");
        if( $check_name != $table_name ) {
            return true;
        } 
        return false;
    }

    public function create_db() {
        global $wpdb;
        $table_name = $this->get_table_name();
        $charset =  $this->get_charset();

        if( $wpdb->get_var( "SHOW TABLES LIKE '$table_name'" ) != $table_name ) {
            $sql = "CREATE TABLE $table_name (
                id mediumint(9) NOT NULL AUTO_INCREMENT,
                ulr VARCHAR(2083) NOT NULL,
                code smallint(3) NOT NULL,
                body tinytext NOT NULL,
                date datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
                UNIQUE KEY id (id)
            ) $charset;";

            require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
            dbDelta($sql);
            if( !get_option( $this->get_db_option_name() ) ) {
                add_option( $this->get_db_option_name(), $this->get_db_version() );
            }
        }
    }
} 

Like I said I'm not sure how to build a test for this or if this even needs to be tested.

5

Should you test this? Yes.

How should you test this? That depends.

There are several different approaches to unit testing WordPress plugins. The one that I prefer and am most familiar with is more like integration testing. I can't tell from your post whether you are using this approach or not, but I'll answer from this perspective anyway.

For my own plugins, I've created a base testcase that will help you do this. It let's you test installation, and uninstallation as well, and provides some custom assertions that you'll probably find useful.

From the readme:

The purpose of this testcase is to allow you to make plugin uninstall testing as realistic as possible. WordPress uninstalls plugins when they aren't active, and these tools allow you simulate that. The installation is performed remotely, so the plugin is not loaded when the tests are being run.

I created these tools after finding that there was a fatal error in one of my plugin's uninstall scripts. Not that I didn't have unit tests for uninstallation. I did. But the uninstall tests were being run with the plugin already loaded. So I never realized that I was calling one of the plugin's functions that wouldn't normally be available. That's when I decided to create these testing tools, so my uninstall tests would fail if I wasn't including all required dependencies in my plugin's uninstall script.

In addition to providing a realistic uninstall testing environment, it also provides some assertions to help you make sure that your plugin entirely cleaned up the database.

An portion of an example testcase, also from the readme:

    /**
     * Test installation and uninstallation.
     */
    public function test_uninstall() {

        /*
         * First test that the plugin installed itself properly.
         */

        // Check that a database table was added.
        $this->assertTableExists( $wpdb->prefix . 'myplugin_table' );

        // Check that an option was added to the database.
        $this->assertEquals( 'default', get_option( 'myplugin_option' ) );

        /*
         * Now, test that it uninstalls itself properly.
         */

        // You must call this to perform uninstallation.
        $this->uninstall();

        // Check that the table was deleted.
        $this->assertTableNotExists( $wpdb->prefix . 'myplugin_table' );

        // Check that all options with a prefix was deleted.
        $this->assertNoOptionsWithPrefix( 'myplugin' );

        // Same for usermeta and comment meta.
        $this->assertNoUserMetaWithPrefix( 'myplugin' );
        $this->assertNoCommentMetaWithPrefix( 'myplugin' );
    }

Edit (Thu Jan 22 2015 3:28 PM):

Even if you don't want to go all out and adopt this approach fully, you can probably still find some useful bits in it that will give you an idea of what is needed to test table creation, etc.

  • Hey, great. I actually had your repo bookmarked to look at. I'll take a look it seems to be exactly what I need. Thanks – gilgimech Jan 23 '15 at 21:43
  • I took a look at your repo. I may use it, but it seems to be a bit cumbersome for what I'm testing right now. I've managed to make a test that passed locally, but it's failing on travis ci. – gilgimech Jan 26 '15 at 16:47
  • @gilgimech if you give me a link I can help you debug it. I have used it on Travis CI without issue. – J.D. Jan 26 '15 at 16:50
  • I think I just figured it out. I was using the globals array $GLOBALS['wpdb']in the test. I just changed it to the basic $wpdb global variable and everything passed. Now, I'm on the search as to why and if I should or shouldn't use the globals array. – gilgimech Jan 27 '15 at 17:04
  • @gilgimech I'm glad you figured it out. That is strange, because it should work either way. Maybe you are using PHPUnit's preserve globals option or something? – J.D. Jan 27 '15 at 20:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.