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:
1
<?php
2
3
use Codeception\Module\WPQueries;
4
5
class WPQueriesUsageTest extends \Codeception\TestCase\WPTestCase
6
{
7
public function test_queries_made_by_factory_are_not_tracked()
8
{
9
$currentQueriesCount = $this->queries()->countQueries();
10
11
$this->assertNotEmpty($currentQueriesCount);
12
13
static::factory()->post->create_many(3);
14
15
$this->assertNotEmpty($currentQueriesCount);
16
$this->assertEquals($currentQueriesCount, $this->queries()->countQueries());
17
}
18
19
public function test_count_queries()
20
{
21
$currentQueriesCount = $this->queries()->countQueries();
22
23
$this->assertNotEmpty($currentQueriesCount);
24
25
foreach (range(1, 3) as $i) {
26
wp_insert_post(['post_title' => 'Post ' . $i, 'post_content' => str_repeat('test', $i)]);
27
}
28
29
$this->assertNotEmpty($currentQueriesCount);
30
$this->assertGreaterThan($currentQueriesCount, $this->queries()->countQueries());
31
}
32
}
Copied!

Public API

assertCountQueries

Asserts that n queries have been made.
1
$posts = $this->factory()->post->create_many(3);
2
$cachedUsers = $this->factory()->user->create_many(2);
3
$nonCachedUsers = $this->factory()->user->create_many(2);
4
foreach($cachedUsers as $userId){
5
wp_cache_set('page-posts-for-user-' . $userId, $posts, 'acme');
6
}
7
// Run the same query as different users
8
foreach(array_merge($cachedUsers, $nonCachedUsers) as $userId){
9
$pagePosts = $plugin->getPagePostsForUser($userId);
10
}
11
$I->assertCountQueries(2, 'A query should be made for each user missing cached posts.')
Copied!
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.
1
$posts = $this->factory()->post->create_many(3);
2
wp_cache_set('page-posts', $posts, 'acme');
3
$pagePosts = $plugin->getPagePosts();
4
$I->assertNotQueries('Queries should not be made if the cache is set.')
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_delete_post($bookId);
6
$this->assertNotQueriesByAction('edit_post');
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);
3
if($post->post_type !== 'book'){
4
return $title;
5
}
6
$new = get_option('acme_new_prefix');
7
return "{$new} - " . $title;
8
});
9
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
10
$this->assertNotQueriesByFilter('the_title');
Copied!
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.
1
$this->assertEmpty(Acme\get_orphaned_posts());
2
Acme\delete_orphaned_posts();
3
$this->assertNotQueriesByFunction('Acme\delete_orphaned_posts');
Copied!
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.
1
$options = new Acme\Options();
2
$options->update('adsSource', 'not-a-real-url.org');
3
$I->assertNotQueriesByMethod('Acme\Options', 'update');
Copied!
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.
1
$bookRepository = new Acme\BookRepository();
2
$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
3
$this->assertNotQueriesByStatement('INSERT', 'Deferred write should happen on __destruct');
4
Regular expressions must contain delimiters.
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_delete_post($bookId);
6
$this->assertNotQueriesByStatementAndAction('DELETE', 'delete_post');
7
Regular expressions must contain delimiters.
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);
3
if($post->post_type !== 'book'){
4
return $title;
5
}
6
$new = get_option('acme_new_prefix');
7
return "{$new} - " . $title;
8
});
9
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
10
$this->assertNotQueriesByStatementAndFilter('SELECT', 'the_title');
11
Regular expressions must contain delimiters.
Copied!
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.
1
wp_insert_post(['ID' => $bookId, 'post_title' => 'The Call of the Wild']);
2
$this->assertNotQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
3
$this->assertQueriesByStatementAndFunction('UPDATE', 'wp_insert_post');
4
Regular expressions must contain delimiters.
Copied!
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.
1
Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
2
$this->assertQueriesByStatementAndMethod('INSERT', Acme\BookRepository::class, 'commit');
3
Regular expressions must contain delimiters.
Copied!
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.
1
wp_cache_delete('page-posts', 'acme');
2
$pagePosts = $plugin->getPagePosts();
3
$I->assertQueries('Queries should be made to set the cache.')
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_update_post(['ID' => $bookId, 'post_title' => 'New Title']);
6
$this->assertQueriesByAction('edit_post');
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);
3
if($post->post_type !== 'book'){
4
return $title;
5
}
6
$new = get_option('acme_new_prefix');
7
return "{$new} - " . $title;
8
});
9
$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
10
$this->assertQueriesByFilter('the_title');
Copied!
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.
1
acme_clean_queue();
2
$this->assertQueriesByFunction('acme_clean_queue');
Copied!
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.
1
$options = new Acme\Options();
2
$options->update('showAds', false);
3
$I->assertQueriesByMethod('Acme\Options', 'update');
Copied!
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.
1
wp_cache_flush();
2
cached_get_posts($args);
3
$I->assertQueriesByStatement('SELECT');
4
Regular expressions must contain delimiters.
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_update_post(['ID' => $bookId, 'post_title' => 'New']);
6
$this->assertQueriesByStatementAndAction('UPDATE', 'edit_post');
7
Regular expressions must contain delimiters.
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);
3
if($post->post_type !== 'book'){
4
return $title;
5
}
6
$new = get_option('acme_new_prefix');
7
return "{$new} - " . $title;
8
});
9
$title = apply_filters('the_title', get_post($bookId)->post_title, $bookId);
10
$this->assertQueriesByStatementAndFilter('SELECT', 'the_title');
11
Regular expressions must contain delimiters.
Copied!
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.
1
wp_insert_post(['post_type' => 'book', 'post_title' => 'Alice in Wonderland']);
2
$this->assertQueriesByStatementAndFunction('INSERT', 'wp_insert_post');
3
Regular expressions must contain delimiters.
Copied!
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.
1
Acme\BookRepository::new(['title' => 'Alice in Wonderland'])->commit();
2
$this->assertQueriesByStatementAndMethod('UPDATE', Acme\BookRepository::class, 'commit');
3
Regular expressions must contain delimiters.
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_update_post(['ID' => $bookOneId, 'post_title' => 'One']);
6
wp_update_post(['ID' => $bookTwoId, 'post_title' => 'Two']);
7
wp_update_post(['ID' => $bookThreeId, 'post_title' => 'Three']);
8
$this->assertQueriesCountByAction(3, 'edit_post');
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);
3
if($post->post_type !== 'book'){
4
return $title;
5
}
6
$new = get_option('acme_new_prefix');
7
return "{$new} - " . $title;
8
});
9
$title = apply_filters('the_title', get_post($bookOneId)->post_title, $bookOneId);
10
$title = apply_filters('the_title', get_post($notABookId)->post_title, $notABookId);
11
$title = apply_filters('the_title', get_post($bookTwoId)->post_title, $bookTwoId);
12
$this->assertQueriesCountByFilter(2, 'the_title');
Copied!
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.
1
$this->assertCount(3, Acme\get_orphaned_posts());
2
Acme\delete_orphaned_posts();
3
$this->assertQueriesCountByFunction(3, 'Acme\delete_orphaned_posts');
Copied!
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.
1
$bookRepository = new Acme\BookRepository();
2
$repository->where('ID', 23)->commit('title', 'Peter Pan');
3
$repository->where('ID', 89)->commit('title', 'Moby-dick');
4
$repository->where('ID', 2389)->commit('title', 'The call of the wild');
5
$this->assertQueriesCountByMethod(3, 'Acme\BookRepository', 'commit');
Copied!
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.
1
$bookRepository = new Acme\BookRepository();
2
$repository->where('ID', 23)->set('title', 'Peter Pan', $deferred = true);
3
$repository->where('ID', 89)->set('title', 'Moby-dick', $deferred = true);
4
$repository->where('ID', 2389)->set('title', 'The call of the wild', $deferred = false);
5
$this->assertQueriesCountByStatement(1, 'INSERT', 'Deferred write should happen on __destruct');
6
Regular expressions must contain delimiters.
Copied!
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.
1
add_action( 'edit_post', function($postId){
2
$count = get_option('acme_title_updates_count');
3
update_option('acme_title_updates_count', ++$count);
4
} );
5
wp_delete_post($bookOneId);
6
wp_delete_post($bookTwoId);
7
wp_update_post(['ID' => $bookThreeId, 'post_title' => 'New']);
8
$this->assertQueriesCountByStatementAndAction(2, 'DELETE', 'delete_post');
9
$this->assertQueriesCountByStatementAndAction(1, 'INSERT', 'edit_post');
10
Regular expressions must contain delimiters.
Copied!
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.
1
add_filter('the_title', function($title, $postId){
2
$post = get_post($postId);