On Github ericmann / two-test-suites
I once worked with a developer who ...
No one wants to be that guy at the conference admitting they've not yet built out a test suite.The Core Framework aims to test the entire WordPress stack
The Core testing framework isn't a unit test suite, it's an integration test suite. It loads the entire WordPress API and communicates actively with a real MySQL database.class Importer {
/**
* @var Array Mapping of MT usernames to WordPress user IDs
*/
private $mtnames = array();
/**
* Check that the author exists within WordPress and, if not, create it.
*
* @param String $author
*
* @return int|\WP_Error
*/
public function checkauthor( $author ) {
$pass = wp_generate_password();
if ( ! isset( $this->mtnames[ $author ] ) ) {
$user_id = wp_create_user( $author, $pass );
$this->mtnames[ $author ] = $user_id;
} else {
$user_id = $this->mtnames[ $author ];
}
return $user_id;
}
}
Our test code comes from a MovableType importer. Our object needs to test incoming author names against existing WordPress objects. First things first, it tests to see if we already know of an author - if so, we return the existing ID and move along. If not, we create a new WordPress user, store their ID for later, and return the new entry./**
* Make sure new authors are created in WordPress
*/
public function test_checkauthor() {
$command = new Importer();
// First author
$mary_id = $command->checkauthor( 'maryshelley' );
$mary = \get_user_by( 'id', $mary_id );
$this->assertEquals( 'maryshelley', $mary->user_login );
// Second author
$jane_id = $command->checkauthor( 'janeausten' );
$this->assertNotEquals( $mary_id, $jane_id );
// Repeat first
$mary_redux = $command->checkauthor( 'maryshelley' );
$this->assertEquals( $mary_id, $mary_redux );
}
We test our checkauthor() function by requesting authors that should be in the database. If a user doesn't exist, a new entry is created. We want to verify new entries are created each time and are unique. We'll test against a real WordPress database.Two sides of the same coin ...
Integration testing and unit testing are different, but share many of the same goals: preventing regressions, ensuring proper behavior, and documenting potential side-effects.WP_Mock tests only your code, not its environment
WPMock isn't an integration testing suite, its goal is to separate your code into the smallest _units possible and test them individually.class Importer {
/**
* @var Array Mapping of MT usernames to WordPress user IDs
*/
private $mtnames = array();
/**
* Check that the author exists within WordPress and, if not, create it.
*
* @param String $author
*
* @return int|\WP_Error
*/
public function checkauthor( $author ) {
$pass = wp_generate_password();
if ( ! isset( $this->mtnames[ $author ] ) ) {
$user_id = wp_create_user( $author, $pass );
$this->mtnames[ $author ] = $user_id;
} else {
$user_id = $this->mtnames[ $author ];
}
return $user_id;
}
}
For comparison's sake, we're going to use the same code as before. This way, we compare apples to apples when viewing the two different test paradigms./**
* Make sure new authors are created in WordPress
*/
public function test_checkauthor() {
\WP_Mock::wpFunction( 'wp_generate_password', array(
'times' => 3,
'return' => 'password',
) );
\WP_Mock::wpFunction( 'wp_create_user', array(
'times' => 2,
'return_in_order' => array( 1, 2 ),
) );
$command = new Importer();
// First author
$mary_id = $command->checkauthor( 'maryshelley' );
$this->assertEquals( 1, $mary_id );
// Second author
$jane_id = $command->checkauthor( 'janeausten' );
$this->assertNotEquals( $mary_id, $jane_id );
// Repeat first
$mary_redux = $command->checkauthor( 'maryshelley' );
$this->assertEquals( $mary_id, $mary_redux );
}
We test the same function as before, but this time we use WPMock to _mock WordPress' API. There is no wp_generate_password() or wp_create_user() function, so we have to program the implementations.