WPGraphQL TestCase Guide

Francis Agulto Avatar

·

WPGraphQL TestCase is a library of tools for testing WPGraphQL APIs along with its additional extensions.  With this library, developers can write test cases that simulate different scenarios and interactions with their plugin. By arranging the test environment, acting on the plugin’s functionality, and asserting the expected outcomes, developers can validate that their code works as intended.

Special thanks to Geoff Taylor for creating the library!

In this article, I will discuss its implementation and usage when developing custom extensions within WPGraphQL.

Getting Started

The prerequisites you need are:

  • A WP install. I used Local for this one
  • Composer 
  • Docker (To follow this specific tutorial) to run tests locally and in environments like GitHub Actions or Circle CI

Note: If you do choose to clone down my repo, do not forget to change all the instances from my WPGraphQL plugin name to yours.  The only files that I will be walking through are the extension I am writing in this tutorial to test with the TestCase library file helper.  I am not going to go over the boilerplate.

Step 1: Spin up a WordPress install on any platform you are using for hosting.

Step 2: Get a docker container running.  This will allow you to run the WPGraphQL test within the TestCase library and your local machine.  In my walkthrough, Docker is running and contains the PHP files from WordPress. If you need a guide to do this, please reference it here.

Step 3: Install the Composer dependency manager for PHP. The composer installation guide can be found here.

Step 4:  Install WPGraphQL TestCase via the GitHub repository instructions or you can clone down the boilerplate repository I made and go from there.

Once the steps to scaffold are complete, we now can write and test our code.

Custom WPGraphQL Extension

The file for my plugin lives in /plugins/wpgraphql-testcase.php.

The test directory is where we contain and store our test files with WPGraphQL TestCase.

The first extension we want to write is a dummy extension to ensure the test library is working and we fail something on purpose and then correct it to pass.  This is php code that executes a function to return a string of "Hello World" every time there is a query for franField.

<?php


/**
* Plugin Name: WPGraphQL Test Case
* Description: Test Plugin for a custom field in WPGraphQL to test with TestCase lib
* Version: 0.1.0
* Author: Fran Agulto
* License: GPLv2 or later
* License URI: http://www.developers.wpengine.com
*/








add_action('graphql_register_types', function(){
   register_graphql_field('RootQuery', 'franField',[
       'type'=> 'String',
       'resolve'=> function() {
           return 'Stoked!!! Hello Stoked World!';
       }
   ]);
});

Code language: HTML, XML (xml)

WPGraphQL TestCase Library

Now that we have a dummy extension written, let’s write out a test for it using WPGraphQL TestCase.

At the root of the project, go to test/fran-field-test.php.  This file is where we will utilize the WPGraphQL TestCase library and its helper functions to test the extension we just wrote.

<?php
class FranFieldTest extends \Tests\WPGraphQL\TestCase\WPGraphQLTestCase {

  
   public function setUp(): void {

       parent::setUp();
   }

   public function tearDown(): void {
     parent::tearDown();
   }

   public function testFranFields(){
    $title='Fran test post';
    $post_id = $this->factory()->post->create([
      'Post_title'=>$title
    ]);
    $query = '
    {
      recentPosts {
        nodes {
          __typename
          databaseId
          title
        }
      } 
    }
    ';
    $this->graphql([
      'Query'=>$query
    ])
  ;
    //assertQuerySuccessful is a function that comes from WPGraphQL Test Case library
    //expectedNode is a function from the library too that runs when you expect a certain node
    self::assertQuerySuccessful($actual, [
      $this->expectedField( '__typename'. 'Post' ),
      $this->expectedField( 'databaseId', $post_id ),
      $this->expectedField( 'title', $title ),
    ]);
    
   }
}
Code language: HTML, XML (xml)

The first thing we need to do is declare a class and extend it to the WPGraphQL TestCase library which is what is happening at line one at the top of the file.

Next, we open up an object and add the boilerplate functions for the test file to execute its library helpers.

{

  
   public function setUp(): void {

       parent::setUp();
   }

   public function tearDown(): void {
     parent::tearDown();
   }
Code language: PHP (php)

Arrange Our Conditions

The first step that is used for testing is arranging our conditions here which allows us to now write our customized test.  On the next lines, we have a function called testFranFields.  The test syntax is what makes a function named, run as a test.  

Following that, we have a variable that is the title which is Fran test post.  

Act-On The Function

What we need to do next is act on this with what is called a test factory which creates an actual post in WordPress for us with the title we chose.

Once we have this factory creating the post, we now can make the GraphQL query which is a variable, we want against our WPGraphQL schema with the extended node that is recentPosts with its fields.  The fields we are asking for are databaseID, __typename, and title. It is here that we want to assert that Fran Test Post is returned because it is equal to the most recent post and included in the response.

Assert

We execute the query on line 30, taking $this function as a variable in order to execute the GraphQL query.  The last steps are to assert what we expect to happen.  In order to do this, we use the assertQuerySuccesful function which is a helper from the WPGraphQL TestCase library.  This allows us to check the query and ensure there are no errors. In this instance, we are passing in our GraphQL query as it executes.

Next, we use the expectedNode function which is coming from WPGraphQL TestCase to declare what expected node we want to return.  We pass in the path to assert it which is our recentPosts.

Then in an array, we input and define what node should be and what fields it has.  In this array, we have the fields we asked for in our query.

This test is now built out.  Let’s run it and see what happens.  In my terminal, I run composer run-test.

This test failed because the functionality that I am testing is being tested against the wrong extension within my php file for WPGraphQL. Let’s write an extension that will create a passing test.

Passing Test For WPGraphQL Extension

The current file at the root of my project  that is making the test fail is this:


<?php

/**
 * Plugin Name: WPGraphQL Scratch Test 
 * 
 * 
 */

 add_action('graphql_register_types', function(){
    register_graphql_field('RootQuery', 'franField',[
        'type'=> 'String',
        'resolve'=> function() {
            return 'Stoked!!! Hello Stoked World!';
        }
    ]);
 });
Code language: HTML, XML (xml)

This is a function that returns a string of “Stoked, Hello World” when franField type is queried.

This does not match the function that we wrote in our TestCase file.  Let’s re-write the code to this extension so it passes.

Here is the code block for the passing file:

<?php
/**
 * Plugin Name: WPGraphQL Test Case
 * Description: Test Plugin for a custom field in WPGraphQL to test with TestCase lib
 * Version: 0.1.0
 * Author: Fran Agulto
 * License: GPLv2 or later
 * License URI: http://www.developers.wpengine.com
 */

 add_action('graphql_register_types', function(){
        register_graphql_connection([
            'fromType'=>'RootQuery',
            'toType'=>'Post',
            'fromFieldName'=>'recentPosts',
            'resolve'=>function($source, $args, $context, $info ){
                $resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver($source, $args, $context, $info);
                return $resolver->get_connection();
            },

        ]);
 });
Code language: HTML, XML (xml)

Let’s break down this code block.

Starting off, we use add_action to execute adding a type to the GraphQL schema.

We have the function within our object called register_graphql_connection coming from WPGraphQL.  This function is called and accepts an array that contains the types which will be queryable. 

add_action('graphql_register_types', function(){
       register_graphql_connection([
           'fromType'=>'RootQuery',
           'toType'=>'Post',
           'fromFieldName'=>'recentPosts',
Code language: PHP (php)

In this case, we want a Post type to have a field name called recentPosts which will allow me to query for recent posts.  This allows the connection to exist in the WPGraphQL schema.

Once we have the connection existing, we want the data back.  We use the resolve function to get the data back from our connection.  Inside the parentheses, in GraphQL, resolvers get 4 arguments:  source, args, context, and info.

  • Source: The previous object, which is for a field on the root Query type is often not used.
  • Args: The arguments provided to the field in the GraphQL query.
  • Context: A value that is provided to every resolver and holds important contextual information like the currently logged-in user, or access to a database.
  • Info: A value that holds field-specific information relevant to the current query as well as the schema details, also refer to type GraphQLResolveInfo for more details.
 'resolve'=>function($source, $args, $context, $info ){
               $resolver = new \WPGraphQL\Data\Connection\PostObjectConnectionResolver($source, $args, $context, $info);
               return $resolver->get_connection();
           },


       ]);
});

Code language: PHP (php)

Within the function body of the resolver, we have a variable that is a new resolver that will return our new connection’s data which is recentPosts.

Heading now over to GraphIQL IDE in WP Admin, let’s manually test this ourselves by querying for recentPosts.  In order to do that, don’t forget to download the zip file of the extension you created for WPGraphQL and upload it to the plugins page within the WP-Admin. 

Now in GraphIQL IDE, this is what our query looks like with the response:

This is finished and let’s test this and see if it passes.  I run composer run-test in my terminal to run the test library.

Stoked! It ran the test and executed exactly what we were testing for against the schema and extension we wrote.  We passed!!! 

Conclusion

The WPGraphQL TestCase library gives developers a better way to develop and test extensions in WPGraphQL to ensure proper functionality in features.

I hope you have a better understanding of how to work with testing and the TestCase library.  As always, super stoked to hear your feedback and any questions you might have on headless WordPress.  Hit us up in the Headless WordPress Discord or the WPGraphQL Slack workspace!