This is the documentation for version 3 of the project. The current version is version 4 and the documentation can be found here.
WPQueries module
This module should be used in integration tests, see levels of testing for more information, to make assertions on the database queries made by the global $wpdb
object.
This module requires the WPLoader module to work.
The module will set, if not set already, the SAVEQUERIES
constant to true
and will throw an exception if the constant is already set to a falsy value.
Configuration
This module does not require any configuration, but requires the WPLoader module to work correctly.
Usage
This module must be used in a test case extending the \Codeception\TestCase\WPTestCase
class.
The module public API is accessible calling via the \Codeception\TestCase\WPTestCase::queries()
method:
<?php
use Codeception\Module\WPQueries;
class WPQueriesUsageTest extends \Codeception\TestCase\WPTestCase
{
public function test_queries_made_by_factory_are_not_tracked()
{
$currentQueriesCount = $this->queries()->countQueries();
$this->assertNotEmpty($currentQueriesCount);
static::factory()->post->create_many(3);
$this->assertNotEmpty($currentQueriesCount);
$this->assertEquals($currentQueriesCount, $this->queries()->countQueries());
}
public function test_count_queries()
{
$currentQueriesCount = $this->queries()->countQueries();
$this->assertNotEmpty($currentQueriesCount);
foreach (range(1, 3) as $i) {
wp_insert_post(['post_title' => 'Post ' . $i, 'post_content' => str_repeat('test', $i)]);
}
$this->assertNotEmpty($currentQueriesCount);
$this->assertGreaterThan($currentQueriesCount, $this->queries()->countQueries());
}
}
Public API
- assertCountQueries
- assertNotQueries
- assertNotQueriesByAction
- assertNotQueriesByFilter
- assertNotQueriesByFunction
- assertNotQueriesByMethod
- assertNotQueriesByStatement
- assertNotQueriesByStatementAndAction
- assertNotQueriesByStatementAndFilter
- assertNotQueriesByStatementAndFunction
- assertNotQueriesByStatementAndMethod
- assertQueries
- assertQueriesByAction
- assertQueriesByFilter
- assertQueriesByFunction
- assertQueriesByMethod
- assertQueriesByStatement
- assertQueriesByStatementAndAction
- assertQueriesByStatementAndFilter
- assertQueriesByStatementAndFunction
- assertQueriesByStatementAndMethod
- assertQueriesCountByAction
- assertQueriesCountByFilter
- assertQueriesCountByFunction
- assertQueriesCountByMethod
- assertQueriesCountByStatement
- assertQueriesCountByStatementAndAction
- assertQueriesCountByStatementAndFilter
- assertQueriesCountByStatementAndFunction
- assertQueriesCountByStatementAndMethod
- countQueries
- getQueries
assertCountQueries
Asserts that n queries have been made.
$posts = $this->factory()->post->create_many(3);
$cachedUsers = $this->factory()->user->create_many(2);
$nonCachedUsers = $this->factory()->user->create_many(2);
foreach($cachedUsers as $userId){
wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');
}
// Run the same query as different users
foreach(array_merge($cachedUsers, $nonCachedUsers) as $userId){
$pagePosts = $plugin->getPagePostsForUser($userId);
}
$I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')
Parameters
int
$n - The expected number of queries.string
$message - An optional message to override the default one.
assertNotQueries
Asserts that no queries were made. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$posts = $this->factory()->post->create_many(3);
wp_cache_set('page-posts', $posts, 'acme');
$pagePosts = $plugin->getPagePosts();
$I->assertNotQueries('Queries should not be made if the cache is set.')
Parameters
string
$message - An optional message to override the default one.
assertNotQueriesByAction
Asserts that no queries were made as a consequence of the specified action. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_delete_post($bookId);
$this->assertNotQueriesByAction('edit_post');
Parameters
string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertNotQueriesByFilter
Asserts that no queries were made as a consequence of the specified filter. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
$this->assertNotQueriesByFilter('the_title');
Parameters
string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertNotQueriesByFunction
Asserts that no queries were made by the specified function. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$this->assertEmpty(Acme\get_orphaned_posts());
Acme\delete_orphaned_posts();
$this->assertNotQueriesByFunction('Acme\delete_orphaned_posts');
Parameters
string
$function - The fully qualified name of the function to check.string
$message - An optional message to override the default one.
assertNotQueriesByMethod
Asserts that no queries have been made by the specified class method. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$options = new Acme\Options();
$options->update('adsSource', 'not-a-real-url.org');
$I->assertNotQueriesByMethod('Acme\Options', 'update');
Parameters
string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
assertNotQueriesByStatement
Asserts that no queries have been made by the specified class method. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$bookRepository = new Acme\BookRepository();
$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
$this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$message - An optional message to override the default one.
assertNotQueriesByStatementAndAction
Asserts that no queries were made as a consequence of the specified action containing the SQL query. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_delete_post($bookId);
$this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertNotQueriesByStatementAndFilter
Asserts that no queries were made as a consequence of the specified filter containing the specified SQL query. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
$this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertNotQueriesByStatementAndFunction
Asserts that no queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
wp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);
$this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
$this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$function - The name of the function to check the assertions for.string
$message - An optional message to override the default one.
assertNotQueriesByStatementAndMethod
Asserts that no queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
$this->assertQueriesByStatementAndMethod('INSERT', Acme\BookRepository::class, 'commit');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
assertQueries
Asserts that at least one query was made during the test. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
wp_cache_delete('page-posts', 'acme');
$pagePosts = $plugin->getPagePosts();
$I->assertQueries('Queries should be made to set the cache.')
Parameters
string
$message - An optional message to override the default one.
assertQueriesByAction
Asserts that at least one query was made as a consequence of the specified action. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);
$this->assertQueriesByAction('edit_post');
Parameters
string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertQueriesByFilter
Asserts that at least one query was made as a consequence of the specified filter. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
$this->assertQueriesByFilter('the_title');
Parameters
string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertQueriesByFunction
Asserts that queries were made by the specified function. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
Parameters
string
$function - The fully qualified name of the function to check.string
$message - An optional message to override the default one.
assertQueriesByMethod
Asserts that at least one query has been made by the specified class method. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$options = new Acme\Options();
$options->update('showAds', false);
$I->assertQueriesByMethod('Acme\Options', 'update');
Parameters
string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
assertQueriesByStatement
Asserts that at least a query starting with the specified statement was made. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
wp_cache_flush();
cached_get_posts($args);
$I->assertQueriesByStatement('SELECT');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$message - An optional message to override the default one.
assertQueriesByStatementAndAction
Asserts that at least one query was made as a consequence of the specified action containing the SQL query. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_update_post(['ID' => $bookId, 'post_title' => 'New']);
$this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertQueriesByStatementAndFilter
Asserts that at least one query was made as a consequence of the specified filter containing the SQL query. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
$this->assertQueriesByStatementAndFilter('SELECT', 'the_title');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertQueriesByStatementAndFunction
Asserts that queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
$this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$function - The fully qualified function name.string
$message - An optional message to override the default one.
assertQueriesByStatementAndMethod
Asserts that queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
$this->assertQueriesByStatementAndMethod('UPDATE', Acme\BookRepository::class, 'commit');
Regular expressions must contain delimiters.
Parameters
string
$statement - A simple string the statement should start with or a valid regular expression.string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
assertQueriesCountByAction
Asserts that n queries were made as a consequence of the specified action. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);
wp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);
wp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);
$this->assertQueriesCountByAction(3, 'edit_post');
Parameters
int
$n - The expected number of queries.string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertQueriesCountByFilter
Asserts that n queries were made as a consequence of the specified filter. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
$this->assertQueriesCountByFilter(2, 'the_title');
Parameters
int
$n - The expected number of queries.string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertQueriesCountByFunction
Asserts that n queries were made by the specified function. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$this->assertCount(3, Acme\get_orphaned_posts());
Acme\delete_orphaned_posts();
$this->assertQueriesCountByFunction(3, 'Acme\delete_orphaned_posts');
Parameters
int
$n - The expected number of queries.string
$function - The function to check the queries for.string
$message - An optional message to override the default one.
assertQueriesCountByMethod
Asserts that n queries have been made by the specified class method. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$bookRepository = new Acme\BookRepository();
$repository->where('ID', 23)->commit('title', 'Peter Pan');
$repository->where('ID', 89)->commit('title', 'Moby-dick');
$repository->where('ID', 2389)->commit('title', 'The call of the wild');
$this->assertQueriesCountByMethod(3, 'Acme\BookRepository', 'commit');
Parameters
int
$n - The expected number of queries.string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
assertQueriesCountByStatement
Asserts that n queries starting with the specified statement were made. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
$bookRepository = new Acme\BookRepository();
$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
$repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);
$repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);
$this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');
Regular expressions must contain delimiters.
Parameters
int
$n - The expected number of queries.string
$statement - A simple string the statement should start with or a valid regular expression.string
$message - An optional message to override the default one.
assertQueriesCountByStatementAndAction
Asserts that n queries were made as a consequence of the specified action containing the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_action( 'edit_post', function($postId){
$count = get_option('acme_title_updates_count');
update_option('acme_title_updates_count', ++$count);
} );
wp_delete_post($bookOneId);
wp_delete_post($bookTwoId);
wp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);
$this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');
$this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');
Regular expressions must contain delimiters.
Parameters
int
$n - The expected number of queries.string
$statement - A simple string the statement should start with or a valid regular expression.string
$action - The action name, e.g. 'init'.string
$message - An optional message to override the default one.
assertQueriesCountByStatementAndFilter
Asserts that n queries were made as a consequence of the specified filter containing the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
add_filter('the_title', function($title, $postId){
$post = get_post($postId);
if($post->post_type !== 'book'){
return $title;
}
$new = get_option('acme_new_prefix');
return "{$new} - " . $title;
});
// Warm up the cache.
$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
// Cache is warmed up now.
$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
$title = apply_filters('the_title', get_post($bookThreeId)->post_title, $bookThreeId);
$this->assertQueriesCountByStatementAndFilter(1, 'SELECT', 'the_title');
Regular expressions must contain delimiters.
Parameters
int
$n - The expected number of queries.string
$statement - A simple string the statement should start with or a valid regular expression.string
$filter - The filter name, e.g. 'posts_where'.string
$message - An optional message to override the default one.
assertQueriesCountByStatementAndFunction
Asserts that n queries were made by the specified function starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
wp_insert_post(['post_type' => 'book', 'post_title' => 'The Call of the Wild']);
wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
wp_insert_post(['post_type' => 'book', 'post_title' => 'The Chocolate Factory']);
$this->assertQueriesCountByStatementAndFunction(3, 'INSERT', 'wp_insert_post');
Regular expressions must contain delimiters.
Parameters
int
$n - The expected number of queries.string
$statement - A simple string the statement should start with or a valid regular expression.string
$function - The fully-qualified function name.string
$message - An optional message to override the default one.
assertQueriesCountByStatementAndMethod
Asserts that n queries were made by the specified class method starting with the specified SQL statement. Queries generated by setUp
, tearDown
and factory
methods are excluded by default.
Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
Acme\BookRepository::new(['title' => 'Moby-Dick'])->commit();
Acme\BookRepository::new(['title' => 'The Call of the Wild'])->commit();
$this->assertQueriesCountByStatementAndMethod(3, 'INSERT', Acme\BookRepository::class, 'commit');
Regular expressions must contain delimiters.
Parameters
int
$n - The expected number of queries.string
$statement - A simple string the statement should start with or a valid regular expression.string
$class - The fully qualified name of the class to check.string
$method - The name of the method to check.string
$message - An optional message to override the default one.
countQueries
Returns the current number of queries. Set-up and tear-down queries performed by the test case are filtered out.
// In a WPTestCase, using the global $wpdb object.
$queriesCount = $this->queries()->countQueries();
// In a WPTestCase, using a custom $wpdb object.
$queriesCount = $this->queries()->countQueries($customWdbb);
Parameters
\wpdb/null
$wpdb - A specific instance of thewpdb
class ornull
to use the global one.
getQueries
Returns the queries currently performed by the global database object or the specified one. Set-up and tear-down queries performed by the test case are filtered out.
// In a WPTestCase, using the global $wpdb object.
$queries = $this->queries()->getQueries();
// In a WPTestCase, using a custom $wpdb object.
$queries = $this->queries()->getQueries($customWdbb);
Parameters
null/\wpdb
$wpdb - A specific instance of thewpdb
class ornull
to use the global one.
This class extends \Codeception\Module