Table of Contents
In that article I will focus more on practice and working with the tools themselves to create a first example of an integration.
Due to that, I will assume that you already set up your environment and that you already have a testing workflow.
If you don’t have an environment setup, then here is my article about it.
If you don’t don’t have a test workflow, my article on the topic is here.
Plan your steps
As writing code starts before writing the first line of code, it is exactly the same for your tests.
For that reason it is key to remind yourself what are the different stages of a test and follow their flow.
First, you will have to set up the initial state for the test, which makes sure everything run from the test will have a similar starting point.
Second, you will have to run the logic you want to test.
Last but not least, you will have to make some assertions to make sure the final state matches with expected results.
Create your test
Now that we know how our plan is for the test, it is time to write the actual code.
For that purpose we are going to use a simple example where we are only supposed to update an option following theses acceptance criteria:
GIVEN the current user is an admin WHEN the user goes on back-office; THEN the option admin_counter should be incremented.
GIVEN the current user is a regular user WHEN the user goes on back-office; THEN the option admin_counter should be the same
To test this functionality, we will have to create a new testcase inside our test directory named adminCounter.php with the following content:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
public function testShouldIncrementWhenAdmin() {
}
}
Once the base class has been created then the code related to setting up the initial state from the first acceptance criteria can be written.
For that purpose it is necessary to define an initial value for the option admin_counter:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
public function testShouldIncrementWhenAdmin() {
update_option('admin_counter', 0);
}
}
Then the second thing to set is a user who is also an admin.
For that it is possible to use one of the factories injected inside WordPress testing classes that the testcase extends from:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
public function testShouldIncrementWhenAdmin() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'administrator' ] );
wp_set_current_user( $user_id );
}
}
Now that the first step is done the next one is to launch the actual logic that is tested.
For that the action admin_init needs to be fired:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
public function testShouldIncrementWhenAdmin() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'administrator' ] );
wp_set_current_user( $user_id );
do_action('admin_init');
}
}
Finally the last step is assert that output state is the one expected.
For that it is necessary to assert on meaningful values. In this case the value from the option:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
public function testShouldIncrementWhenAdmin() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'administrator' ] );
wp_set_current_user( $user_id );
do_action('admin_init');
$this->assertEquals(1, get_option('admin_counter', 0);
}
}
Now that the test is complete it is now time to run it to make sure it fails and it is not yet implemented.
As no code as been written yet it should be red.
Write the matching code
Once the test has been completed then it is time for you to write the easiest code possible which will make the tests pass.
In our case the code would look like this:
<?php
add_action('my_action', function() {
update_option('my_option', 42);
});
Once the test pass we need to make sure all tests are also passing as they are the only way of knowing if the assertions from the project have been respected or not.
Iterate
Once the first acceptance criteria implemented it is now time to pass to the next one:
GIVEN the current user is a regular user WHEN the user goes on back-office; THEN the option admin_counter should be the same
For that on the previous testcase you need to add a new test method this way:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
...
public function testShouldDoNothingWhenNormalUser() {
}
}
As for the last acceptance criteria we start by implementing the initial state.
For that we need to create a regular user and an empty option:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
...
public function testShouldDoNothingWhenNormalUser() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'subscriber' ] );
wp_set_current_user( $user_id );
}
}
Once this is done the next step will be to execute the code to test:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
...
public function testShouldDoNothingWhenNormalUser() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'subscriber' ] );
wp_set_current_user( $user_id );
do_action('admin_init');
}
}
Finally the last thing you need do is to assert that the final state is the one expected for that we can check the value from the option is still the same:
<?php
namespace MyPlugin\Tests\Integration;
class Test_adminCounter extends TestCase {
...
public function testShouldDoNothingWhenNormalUser() {
update_option('admin_counter', 0);
$user_id = $this->factory->user->create( [ 'role' => 'subscriber' ] );
wp_set_current_user( $user_id );
do_action('admin_init');
$this->assertEquals(0, get_option('admin_counter', 0);
}
}
Once this is done then you should write the matching code:
<?php
add_action('my_action', function() {
$user = wp_get_current_user();
if( ! is_super_admin( $user->ID ) ) {
return;
}
update_option('my_option', 42);
});
Finally when this iteration is done the test is passing you need to check the previous one does as well and check if there is a way to refactor the logic in a better manner.
Here as it is an example there is not refactoring possible so the next step would be to continue to implement acceptance criteria one by one until all of them are implemented correctly.
Conclusion
I hope this helps you with implementing your first integration test in WordPress.
If you need more in depth tests I will continue that series of articles with scenarios you will face on a daily basis while testing.
Laisser un commentaire