Test Glue API
Edit on GitHubThis guide explains how to set up and run Glue API end-to-end (E2E) tests using the WishlistsRestApi module as an example and the Pyz project namespace. Adjust the module name according to your requirements.
These E2E tests exercise endpoints over HTTP, so they apply regardless of whether an endpoint is served by the legacy Glue infrastructure or by API Platform—the API contract is identical. For API Platform-specific test tooling, such as kernel-based test cases for Providers and Processors, see Test API Platform resources.
Prerequisites
- Install or update Spryker Testify to version 3.12.0 or higher:
-
Check the current installed version:
composer info spryker/testify -
Install Spryker Testify:
composer require --dev spryker/testify:"^3.12.0" -
Update Spryker Testify:
composer update spryker/testify:"^3.12.0"
- To validate the response body against the OpenAPI schema, you need to generate the schema. For instructions, see Document Storefront API Resources.
Configure the project and set up test files
- Add the required configuration to the project:
config/Shared/config_default.php
<?php
use Spryker\Shared\Testify\TestifyConstants;
$glueHost = getenv('SPRYKER_API_HOST') ?: 'localhost';
$gluePort = (int)(getenv('SPRYKER_API_PORT')) ?: 443;
if (class_exists(TestifyConstants::class)) {
$config[TestifyConstants::GLUE_APPLICATION_DOMAIN] = sprintf(
'https://%s%s',
$glueHost,
$gluePort !== 443 ? ':' . $gluePort : '',
);
$config[TestifyConstants::GLUE_OPEN_API_SCHEMA] = APPLICATION_SOURCE_DIR . '/Generated/Glue/Specification/spryker_rest_api.schema.yml';
}
- Create
codeception.ymlwith the configuration required for your E2E test:
tests/PyzTest/Glue/Wishlists/codeception.yml
namespace: PyzTest\Glue\Wishlists
paths:
tests: .
data: _data
support: _support
output: _output
coverage:
enabled: true
remote: false
whitelist: { include: ['../../../../src/*'] }
suites:
RestApi:
actor: WishlistsApiTester
modules:
enabled:
- \PyzTest\Shared\Testify\Helper\Environment
- \SprykerTest\Shared\Testify\Helper\LocatorHelper:
projectNamespaces: ['Pyz']
- \SprykerTest\Shared\Propel\Helper\ConnectionHelper
- \SprykerTest\Shared\Testify\Helper\DataCleanupHelper
- \SprykerTest\Glue\Testify\Helper\GlueRest
- \SprykerTest\Glue\Testify\Helper\OpenApi3
- \SprykerTest\Glue\Testify\Helper\JsonPath
- \SprykerTest\Shared\Product\Helper\ProductDataHelper
- \SprykerTest\Shared\Wishlist\Helper\WishlistDataHelper
- \SprykerTest\Shared\Customer\Helper\CustomerDataHelper
- \SprykerTest\Shared\Testify\Helper\DependencyHelper
- \SprykerTest\Glue\AuthRestApi\Helper\AuthRestApiHelper
- \SprykerTest\Service\Container\Helper\ContainerHelper
- \SprykerTest\Shared\Store\Helper\StoreDependencyHelper
config:
\SprykerTest\Glue\Testify\Helper\GlueRest:
depends: PhpBrowser
part: Json
\SprykerTest\Shared\Testify\Helper\DataCleanupHelper:
cleanup: false
- Build Codeception:
docker/sdk testing codecept build -c tests/PyzTest/Glue/Wishlists
- Adjust the generated actor class so it extends
\SprykerTest\Glue\Testify\Tester\ApiEndToEndTester:
tests/PyzTest/Glue/Wishlists/_support/WishlistsApiTester.php
<?php
namespace PyzTest\Glue\Wishlists;
use SprykerTest\Glue\Testify\Tester\ApiEndToEndTester;
/**
* Inherited Methods
*
* @method void wantToTest($text)
* @method void wantTo($text)
* @method void execute($callable)
* @method void expectTo($prediction)
* @method void expect($prediction)
* @method void amGoingTo($argumentation)
* @method void am($role)
* @method void lookForwardTo($achieveValue)
* @method void comment($description)
* @method void pause()
*/
class WishlistsApiTester extends ApiEndToEndTester
{
use _generated\WishlistsApiTesterActions;
}
- To create fixtures, introduce the fixtures class which generates the data required for tests:
tests/PyzTest/Glue/Wishlists/RestApi/WishlistsRestApiFixtures.php
<?php
namespace PyzTest\Glue\Wishlists\RestApi;
use Generated\Shared\Transfer\CustomerTransfer;
use Generated\Shared\Transfer\ProductConcreteTransfer;
use Generated\Shared\Transfer\WishlistItemTransfer;
use Generated\Shared\Transfer\WishlistTransfer;
use PyzTest\Glue\Wishlists\WishlistsApiTester;
use SprykerTest\Shared\Testify\Fixtures\FixturesBuilderInterface;
use SprykerTest\Shared\Testify\Fixtures\FixturesContainerInterface;
/**
* Auto-generated group annotations
*
* @group PyzTest
* @group Glue
* @group Wishlists
* @group RestApi
* @group WishlistsRestApiFixtures
* Add your own group annotations below this line
* @group EndToEnd
*/
class WishlistsRestApiFixtures implements FixturesBuilderInterface, FixturesContainerInterface
{
/**
* @var string
*/
protected const TEST_USERNAME = 'UserWishlistsRestApiFixtures';
/**
* @var string
*/
protected const TEST_PASSWORD = 'change123';
/**
* @var \Generated\Shared\Transfer\WishlistTransfer
*/
protected WishlistTransfer $wishlistTransfer;
/**
* @var \Generated\Shared\Transfer\ProductConcreteTransfer
*/
protected ProductConcreteTransfer $productConcreteTransfer;
/**
* @var \Generated\Shared\Transfer\CustomerTransfer
*/
protected CustomerTransfer $customerTransfer;
/**
* @return \Generated\Shared\Transfer\ProductConcreteTransfer
*/
public function getProductConcreteTransfer(): ProductConcreteTransfer
{
return $this->productConcreteTransfer;
}
/**
* @return \Generated\Shared\Transfer\WishlistTransfer
*/
public function getWishlistTransfer(): WishlistTransfer
{
return $this->wishlistTransfer;
}
/**
* @return \Generated\Shared\Transfer\CustomerTransfer
*/
public function getCustomerTransfer(): CustomerTransfer
{
return $this->customerTransfer;
}
/**
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return \SprykerTest\Shared\Testify\Fixtures\FixturesContainerInterface
*/
public function buildFixtures(WishlistsApiTester $I): FixturesContainerInterface
{
$this->createProductConcrete($I);
$this->createCustomer($I);
$this->createWishlist($I);
return $this;
}
/**
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
protected function createProductConcrete(WishlistsApiTester $I): void
{
$this->productConcreteTransfer = $I->haveFullProduct();
}
/**
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
protected function createCustomer(WishlistsApiTester $I): void
{
$customerTransfer = $I->haveCustomer([
CustomerTransfer::USERNAME => static::TEST_USERNAME,
CustomerTransfer::PASSWORD => static::TEST_PASSWORD,
CustomerTransfer::NEW_PASSWORD => static::TEST_PASSWORD,
]);
$this->customerTransfer = $I->confirmCustomer($customerTransfer);
}
/**
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
protected function createWishlist(WishlistsApiTester $I): void
{
$this->wishlistTransfer = $I->haveWishlist([
WishlistTransfer::FK_CUSTOMER => $this->customerTransfer->getIdCustomer(),
]);
$I->haveItemInWishlist([
WishlistItemTransfer::FK_WISHLIST => $this->wishlistTransfer->getIdWishlist(),
WishlistItemTransfer::WISHLIST_NAME => $this->wishlistTransfer->getName(),
WishlistItemTransfer::SKU => $this->productConcreteTransfer->getSku(),
WishlistItemTransfer::FK_CUSTOMER => $this->customerTransfer->getIdCustomer(),
WishlistItemTransfer::PRODUCT_OFFER_REFERENCE => null,
WishlistItemTransfer::MERCHANT_REFERENCE => null,
]);
}
}
- Create the test cest file:
tests/PyzTest/Glue/Wishlists/RestApi/WishlistRestApiCest.php
<?php
namespace PyzTest\Glue\Wishlists\RestApi;
use Codeception\Util\HttpCode;
use PyzTest\Glue\Wishlists\WishlistsApiTester;
use Spryker\Glue\ProductsRestApi\ProductsRestApiConfig;
use Spryker\Glue\WishlistsRestApi\WishlistsRestApiConfig;
/**
* Auto-generated group annotations
*
* @group PyzTest
* @group Glue
* @group Wishlists
* @group RestApi
* @group WishlistRestApiCest
* Add your own group annotations below this line
* @group EndToEnd
*/
class WishlistRestApiCest
{
/**
* @var \PyzTest\Glue\Wishlists\RestApi\WishlistsRestApiFixtures
*/
protected WishlistsRestApiFixtures $fixtures;
/**
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
public function loadFixtures(WishlistsApiTester $I): void
{
/** @var \PyzTest\Glue\Wishlists\RestApi\WishlistsRestApiFixtures $fixtures */
$fixtures = $I->loadFixtures(WishlistsRestApiFixtures::class);
$this->fixtures = $fixtures;
}
/**
* @depends loadFixtures
*
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
public function requestWishlistByUuid(WishlistsApiTester $I): void
{
// Arrange
$wishlistUuid = $this->fixtures->getWishlistTransfer()->getUuid();
$oauthResponseTransfer = $I->haveAuthorizationToGlue($this->fixtures->getCustomerTransfer());
$I->amBearerAuthenticated($oauthResponseTransfer->getAccessToken());
$url = $I->buildWishlistUrl($wishlistUuid);
// Act
$I->sendGET($url);
// Assert
$I->seeResponseCodeIs(HttpCode::OK);
$I->seeResponseIsJson();
$I->seeResponseMatchesOpenApiSchema();
$I->amSure('returned resource is of correct type')
->whenI()
->seeResponseDataContainsSingleResourceOfType(WishlistsRestApiConfig::RESOURCE_WISHLISTS);
$I->amSure('returned resource has correct id')
->whenI()
->seeSingleResourceIdEqualTo($wishlistUuid);
$I->amSure('returned resource has correct self-link')
->whenI()
->seeSingleResourceHasSelfLink($url);
}
/**
* @depends loadFixtures
*
* @param \PyzTest\Glue\Wishlists\WishlistsApiTester $I
*
* @return void
*/
public function requestWishlists(WishlistsApiTester $I): void
{
$oauthResponseTransfer = $I->haveAuthorizationToGlue($this->fixtures->getCustomerTransfer());
$I->amBearerAuthenticated($oauthResponseTransfer->getAccessToken());
$wishlistUuid = $this->fixtures->getWishlistTransfer()->getUuid();
// Act
$I->sendGET($I->buildWishlistsUrl());
// Assert
$I->seeResponseCodeIs(HttpCode::OK);
$I->seeResponseIsJson();
$I->seeResponseMatchesOpenApiSchema();
$I->amSure('Response data contains resource collection')
->whenI()
->seeResponseDataContainsResourceCollectionOfType(WishlistsRestApiConfig::RESOURCE_WISHLISTS);
$I->amSure('Resource collection has resource')
->whenI()
->seeResourceCollectionHasResourceWithId($wishlistUuid);
$I->amSure('Resource has correct self-link')
->whenI()
->seeResourceByIdHasSelfLink($wishlistUuid, $I->buildWishlistUrl($wishlistUuid));
}
}
Run the test
- Generate fixtures:
docker/sdk testing codecept fixtures
- Synchronize the data to storage and search:
docker/sdk testing console queue:worker:start --stop-when-empty
- Execute tests:
docker/sdk testing codecept run -c tests/PyzTest/Glue/Wishlists
Once the testing is complete, the result of each test is returned.
Thank you!
For submitting the form