mercredi 8 janvier 2020

Testing SLIM appication against API Specification with PHPUnit

I have an API, written in PHP with Slim (3, will be upgraded to 4 soon), I also have an extensive specification written in openapi3 YML format (I could convert to another format if necessary, but I think it would be the best to keep oas3). Currently I am testing all endpoint against this specification with Dredd. This is a Tool which goes through a API specification an, sends example data to the real API and checks if the result matches the spec. That works, but not very good. For a test run I have to wipe out and re-initialize the db with PHP and then run Dredd with npm. Plus since Dredd does not support all features of oas3 I have to do some conversion first.

Since I have some Unit-tests with PHPUnit anyway, I would love to run the other tests with PHPUnit as well (and get rid of the Node-stuff at all). I found http://opensource.byjg.com/php-swagger-test/ and https://github.com/Maks3w/SwaggerAssertions. Both of them provide this very feature, but I would have to write a separate function for every endpoint, containing sample data and so on - stuff which is already in the API spec. Any Idea how I could avoid this afford and just use my API spec as test defintion with PHPUnit or at least any PHP library?

Example from the specs:

  /users:
    get:
      summary: get a list of users
      description: get info about all registered users - in whole application or in a workspace.

      parameters:
        - in: header
          name: AuthToken
          schema:
            $ref: '#/components/schemas/auth'
          example:
            at: 132token
        - in: query
          name: ws
          description: id of a workspace to get users from. can be omitted for all users in system
          required: false
          examples:
            a:
              value: 0
            b:
              value: 1

With byjg php-swagger-test I would have to write something like this

    public function usersA()
    {
        $request = new \ByJG\Swagger\SwaggerRequester();
        $request
            ->withMethod('GET')
            ->withPath("/users")
            ->withHEader(blabla)
            ->withRequestBody(['ws'=>0]);

        $this->assertRequest($request);
    }
    public function usersB()
    {
        $request = new \ByJG\Swagger\SwaggerRequester();
        $request
            ->withMethod('GET')
            ->withPath("/users")
            ->withHEader(blabla)
            ->withRequestBody(['ws'=>1]);

        $this->assertRequest($request);
    }

Two tests (functions) containing only information which is already in the spec. Is there a better tool/way to run tests over all endpoints against the spec without writing all those?

Aucun commentaire:

Enregistrer un commentaire