Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Testing GraphQL Queries: Tools and Automated Tests

Testing GraphQL Queries: Tools and Automated Tests

~8 Min. Lesezeit Zuletzt aktualisiert am August 9, 2026

Chapter 3 introduced GraphQL clients for manual testing - but for a project like the events API that has grown across 16 chapters, purely manual testing isn't enough anymore. This chapter shows how to systematically and automatically cover queries and mutations.

Manual tools in the daily workflow

For day-to-day development, GraphQL clients like Altair or Insomnia remain the fastest feedback loop - both support saved "environments" with variables for tokens and base URLs, so requests against the local development environment don't have to be rebuilt for every single test. Magento itself doesn't ship an admin-integrated GraphiQL UI - external tools remain the standard approach.

Automated tests with GraphQlAbstract

Magento's own test suite for GraphQL lives under dev/tests/api-functional/testsuite/Magento/GraphQl/ and builds on the base class \Magento\TestFramework\TestCase\GraphQlAbstract. A custom module can follow the exact same pattern:

dev/tests/api-functional/testsuite/Mironsoft/Event/EventsQueryTest.php
<?php

declare(strict_types=1);

namespace Mironsoft\Event;

use Magento\TestFramework\TestCase\GraphQlAbstract;

/**
 * Integration-level tests for the events GraphQL query.
 */
class EventsQueryTest extends GraphQlAbstract
{
    /**
     * Verifies that the events query returns items and pagination info.
     *
     * @magentoApiDataFixture Mironsoft_Event::Test/_files/events.php
     * @return void
     */
    public function testReturnsActiveEventsWithPagination(): void
    {
        $query = <<<QUERY
{
  events(pageSize: 2) {
    items {
      identifier
      title
    }
    total_count
    page_info {
      current_page
    }
  }
}
QUERY;

        $response = $this->graphQlQuery($query);

        self::assertArrayHasKey('items', $response['events']);
        self::assertCount(2, $response['events']['items']);
        self::assertSame(1, $response['events']['page_info']['current_page']);
    }
}

graphQlQuery() handles the HTTP setup, JSON encoding/decoding, and automatically throws a PHP exception on a GraphQL error - a test doesn't have to deal with the raw HTTP handling itself, it works directly with the decoded data array.

Testing protected mutations: tokens in headers

/**
 * Verifies that addEventToFavorites requires a customer token.
 *
 * @magentoApiDataFixture Magento/Customer/_files/customer.php
 * @magentoApiDataFixture Mironsoft_Event::Test/_files/events.php
 * @return void
 */
public function testRejectsFavoritingAsGuest(): void
{
    $mutation = 'mutation { addEventToFavorites(input: { event_id: 1 }) { event { title } } }';

    $this->expectExceptionMessage('You must be logged in as a customer to favorite an event.');
    $this->graphQlMutation($mutation);
}

/**
 * Verifies that addEventToFavorites succeeds with a valid customer token.
 *
 * @magentoApiDataFixture Magento/Customer/_files/customer.php
 * @magentoApiDataFixture Mironsoft_Event::Test/_files/events.php
 * @return void
 */
public function testAcceptsFavoritingAsLoggedInCustomer(): void
{
    $mutation = 'mutation { addEventToFavorites(input: { event_id: 1 }) { event { is_favorite } } }';

    $headers = ['Authorization' => 'Bearer ' . $this->customerTokenFixture()];

    $response = $this->graphQlMutation($mutation, [], '', $headers);

    self::assertTrue($response['addEventToFavorites']['event']['is_favorite']);
}

This pair of tests covers exactly what chapter 18 built: the rejected guest call and the successful, authenticated call - both in exactly the shape a client would actually use the mutation.

Where these tests run in the project

dev/tests/api-functional is a standalone PHPUnit suite with its own phpunit.xml.dist, separate from the unit tests used by bin/analyse - it runs against a real, fully installed Magento instance (including the database), not against mocked objects. In this project's Mark Shust setup, it's invoked via bin/cli inside the app container, where the test suite is already configured.

bin/cli vendor/bin/phpunit -c dev/tests/api-functional/phpunit.xml.dist \
  dev/tests/api-functional/testsuite/Mironsoft/Event/EventsQueryTest.php

Tipp: @magentoApiDataFixture classes (here the fictional Mironsoft_Event::Test/_files/events.php) create defined test data before each test and automatically clean it up afterward - that way every test run stays reproducible, independent of the development environment's current database content.

With manual tools for fast iteration and GraphQlAbstract tests for lasting coverage, chapter 25 turns to the opposite case: what to do when something doesn't work as expected.