Skip to content

Testing Uninstallation

J.D. Grimes edited this page Sep 9, 2016 · 5 revisions

This library includes tools to help you test that your plugin is installed and uninstalled properly. These revolve around a special testcase that you will subclass, called WPPPB_TestCase_Uninstall.

Background

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 using this testcase will simulate that. When uninstallation is being tested, the loader won't activate the plugin so that it is loaded by WordPress before the tests run, as it normally would. Instead, it waits and let's the testcase remotely install and then deactivate the plugin, without loading it. That way, when the testcase uninstalls the plugin with uninstall_plugin(), the plugin is inactive and unloaded, just like in real life.

The benefit of this is that it can catch errors in a plugin's uninstall script that wouldn't be caught otherwise. J.D. Grimes recalls finding a fatal error in one of his plugins' uninstall scripts, even though he had tests for uninstallation. The problem was that the uninstall tests for the plugin were being run with the plugin already loaded. So they didn't catch that a function was being called in uninstall.php without the file containing that function being included there. That's what lead to the creation of this testcase, so that the plugin's uninstall tests would fail if it wasn't including all of the required dependencies in its uninstall script.

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

Set Up

Because we need to skip loading the plugin when running the uninstall tests, they need to run separately from all of the others. To accomplish this, you need to create a separate PHPUnit XML config file for them, like this:

<phpunit
	bootstrap="tests/phpunit/includes/bootstrap.php"
	backupGlobals="false"
	colors="true"
	>
	<testsuites>
		<testsuite>
			<file>tests/phpunit/test-uninstall.php</file>
		</testsuite>
	</testsuites>
</phpunit>

You can call the file phpunit.uninstall.xml.dist, and place it alongside your regular phpunit.xml.dist file. Then you can run the uninstall tests with the command phpunit -c phpunit.uninstall.xml.dist.

Note: You may also need to exclude the uninstall test from running along with your regular tests, depending on how your primary test suite is structured. You can do this by adding changing where your uninstall test is placed, or by adding a line to the <testsuite> definition inside of your phpunit.xml.dist file:

			<exclude>tests/phpunit/test-uninstall.php</exclude>

Usage

Now, it's time to create the uninstall testcase for your plugin, by extending the WPPPB_TestCase_Uninstall class:

<?php

/**
 * Test uninstallation.
 */

/**
 * Plugin uninstall test case.
 */
class My_Plugin_Uninstall_Test extends WPPPB_TestCase_Uninstall {

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

		global $wpdb;
		
		/*
		 * 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' );
	}
}

Save your testcase in tests/phpunit/test-uninstall.php and you are all set!

Simulating Plugin Use

The above example is a great first step in testing that your plugin is uninstalling itself completely. However, you can probably do better. This example only tests uninstallation from a fresh, clean install of your plugin. But what about after the user has actually used your plugin for awhile? It will probably have added some more options to the database somewhere along the way. To have more robust and complete uninstall tests, it is necessary to simulate plugin use.

The testcase has provided for this. To use this feature, write up a script that will simulate your plugin being used. Call your various functions that add data to the database, for example. Save your code in a file.

Now all you need to do to have the testcase to run the simulation, is specify the path of the file you just created in the $simulation_file class property.

The plugin usage simulation script will then automatically be run remotely before the plugin is uninstalled. You can also run it before this if needed, by calling $this->simulate_usage(). That would allow you to test that the simulation file actually worked.

To aid in usage simulation, you can utilize WordPress's tests' factories just as you would in a testcase. The WP_UnitTest_Factory object is made available via the $wp_test_factory global.

Clone this wiki locally