WPQueries

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 contstant 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

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.

acme_clean_queue();
$this->assertQueriesByFunction('acme_clean_queue');

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

  • null/\wpdb $wpdb - A specific instance of the wpdb class or null 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 the wpdb class or null to use the global one.

This class extends \Codeception\Module