-
-
Notifications
You must be signed in to change notification settings - Fork 907
Add an HTTP client dedicated to functional API testing #2608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
It could be great adding the possibility of testing objects with the Symfony Validator. It would allow testing an object with the following assertion: $this->assertSymfonyValidate($objectToTest); What do you think about implementing it in |
@baudev I plan to add extra assertions in other PRs (like a response against a JSON Schema), but the one you're talking about should be added directly to Symfony IMHO (it can benefit to non-API Platform projects as well). |
src/Bridge/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Outdated
Show resolved
Hide resolved
Actually, is there any reason why this goes into API Platform instead of in Symfony? I can see that the implementation is completely decoupled from API Platform? |
@teohhanhui there are some API Platform specifics (JSON-LD by default), and @bendavies and I plan to add more (specific helpers to navigate in links, JSON Schema assertions...). But the current implementation could go in Symfony FrameworkBundle yes, technically speaking. That being said, I prefer to keep API-related stuff in this project, and this client is definitely API-related. |
I just added a nice API to deal with API errors (validation errors for instance), and namespace App\Tests;
use ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Hautelook\AliceBundle\PhpUnit\RefreshDatabaseTrait;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
class ProjectsTest extends ApiTestCase
{
use RefreshDatabaseTrait;
public function testNotAbleToCreateProjectWithoutOwner()
{
$this->expectException(ClientExceptionInterface::class);
$this->expectExceptionCode(400); // HTTP status code
$this->expectExceptionMessage(<<<ERROR
users: This collection should contain 1 element or more.
users: The current logged in user must be part of the users owning this resource.
ERROR
);
$client = static::createClient();
$response = $client->request('POST', '/api/projects', [
'basic_auth' => ['[email protected]', 'maman'],
'json' => [
'name' => 'My project',
],
]);
$response->getContent();
}
} To get these nice error messages pre-populated, and to be able to assert on them your API just have to respect the Hydra convention for errors, or the RFC 7807 one). |
i would prefer optional throwing (configurable?). in my tests, is manually check response codes and response content on error. |
@bendavies you can do it too, it's natively supported by HttpClient, just pass |
yeah thanks i should have remembered that... (you mean |
This PR was squashed before being merged into the 4.3-dev branch (closes #30549). Discussion ---------- [HttpClient] Make exceptions public | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no<!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | n/a Makes it easier to implement the interface. See api-platform/core#2608 Commits ------- 928d774e4a [HttpClient] Make exceptions public
This PR was squashed before being merged into the 4.3-dev branch (closes #30549). Discussion ---------- [HttpClient] Make exceptions public | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no<!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | n/a Makes it easier to implement the interface. See api-platform/core#2608 Commits ------- 928d774 [HttpClient] Make exceptions public
… exception messages (dunglas) This PR was squashed before being merged into the 4.3-dev branch (closes #30559). Discussion ---------- [HttpClient] Parse common API error formats for better exception messages | Q | A | ------------- | --- | Branch? | master <!-- see below --> | Bug fix? | no | New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | todo? Use extra details provided by popular error formats following to improve HTTP exception messages. The following formats are supported: * Hydra (default in API Platform) * RFC 7807 (followed by Symfony's [ConstraintViolationListNormalizer](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php) and supported by API Platform and Apigility) * JSON:API (because it respects the semantic of the RFC 7807) It allows to write code like the following (here in a test context): ```php public function testBadRequest() { $this->expectException(ClientExceptionInterface::class); $this->expectExceptionCode(400); // HTTP status code $this->expectExceptionMessage(<<<ERROR Validation Failed users: This collection should contain 1 element or more. users: The current logged in user must be part of the users owning this resource. ERROR ); $response = (HttpClient::create())->request('POST', 'http://example.com/api/projects', [ 'json' => [ 'name' => 'My project', ], ]); $response->getContent(); } ``` Port of api-platform/core#2608 (comment). Commits ------- 96df4464a1 [HttpClient] Parse common API error formats for better exception messages
… exception messages (dunglas) This PR was squashed before being merged into the 4.3-dev branch (closes #30559). Discussion ---------- [HttpClient] Parse common API error formats for better exception messages | Q | A | ------------- | --- | Branch? | master <!-- see below --> | Bug fix? | no | New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | todo? Use extra details provided by popular error formats following to improve HTTP exception messages. The following formats are supported: * Hydra (default in API Platform) * RFC 7807 (followed by Symfony's [ConstraintViolationListNormalizer](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php) and supported by API Platform and Apigility) * JSON:API (because it respects the semantic of the RFC 7807) It allows to write code like the following (here in a test context): ```php public function testBadRequest() { $this->expectException(ClientExceptionInterface::class); $this->expectExceptionCode(400); // HTTP status code $this->expectExceptionMessage(<<<ERROR Validation Failed users: This collection should contain 1 element or more. users: The current logged in user must be part of the users owning this resource. ERROR ); $response = (HttpClient::create())->request('POST', 'http://example.com/api/projects', [ 'json' => [ 'name' => 'My project', ], ]); $response->getContent(); } ``` Port of api-platform/core#2608 (comment). Commits ------- 96df446 [HttpClient] Parse common API error formats for better exception messages
478116b
to
7d7d038
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this stuff rocks
…ns with Panther and API Platform's test client (dunglas) This PR was submitted for the 4.3 branch but it was merged into the 4.4 branch instead (closes #32207). Discussion ---------- [FrameworkBundle] Allow to use the BrowserKit assertions with Panther and API Platform's test client | Q | A | ------------- | --- | Branch? | 4.3 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a | License | MIT | Doc PR | n/a I'm adding a testing client for API Platform that implements the interfaces of HttpClient: api-platform/core#2608 Most PHPUnit assertions provided by Symfony are useful and can be reused, but the ones using the crawler are not relevant and pollute auto-complete suggestions (because a web API usually returns JSON, not HTML). This PR splits the existing trait to allow reusing the HTTP related assertions only. Commits ------- cd0341e [FrameworkBundle] Allow to use the BrowserKit assertions with Panther and API Platform's test client
This PR was squashed before being merged into the 4.3-dev branch (closes #30549). Discussion ---------- [HttpClient] Make exceptions public | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no<!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | n/a Makes it easier to implement the interface. See api-platform/core#2608 Commits ------- 928d774e4a [HttpClient] Make exceptions public
… exception messages (dunglas) This PR was squashed before being merged into the 4.3-dev branch (closes #30559). Discussion ---------- [HttpClient] Parse common API error formats for better exception messages | Q | A | ------------- | --- | Branch? | master <!-- see below --> | Bug fix? | no | New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no <!-- see https://symfony.com/bc --> | Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tests pass? | yes <!-- please add some, will be required by reviewers --> | Fixed tickets | n/a <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | todo? Use extra details provided by popular error formats following to improve HTTP exception messages. The following formats are supported: * Hydra (default in API Platform) * RFC 7807 (followed by Symfony's [ConstraintViolationListNormalizer](https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/ConstraintViolationListNormalizer.php) and supported by API Platform and Apigility) * JSON:API (because it respects the semantic of the RFC 7807) It allows to write code like the following (here in a test context): ```php public function testBadRequest() { $this->expectException(ClientExceptionInterface::class); $this->expectExceptionCode(400); // HTTP status code $this->expectExceptionMessage(<<<ERROR Validation Failed users: This collection should contain 1 element or more. users: The current logged in user must be part of the users owning this resource. ERROR ); $response = (HttpClient::create())->request('POST', 'http://example.com/api/projects', [ 'json' => [ 'name' => 'My project', ], ]); $response->getContent(); } ``` Port of api-platform/core#2608 (comment). Commits ------- 96df4464a1 [HttpClient] Parse common API error formats for better exception messages
Currently, there are no very satisfactory solutions to write functional tests for web APIs built in PHP (API Platform and Symfony included):
It's time to say hi to
ApiTestCase
andTest\Client
! This new set of API testing utilities is built on top of the Symfony'sClient
test class, and implements the exact same interface than the brand new Symfony HttpClient component.As you'll see, it also plays very well with Alice (the fixture generator with an official Symfony recipe), that gets new power in the operation!
Let's see how it looks:
The following fixtures are loaded automatically. The database is reseted to a known test between every test (regardless of it fails or not) using transactions for maximum performance.
TODO: