gRPC Plugin

The gRPC plugin tests gRPC services against their Protocol Buffers definition. Drift reads your .proto file, exposes every RPC method as a testable operation, encodes each request as a protobuf message, and compares the decoded response against your expectations.

Supported features

  • Scalar fields, nested messages, and enum fields

  • Repeated fields and map fields

  • oneof fields

  • Unary, server-streaming, client-streaming, and bidirectional-streaming methods

  • gRPC status codes and status messages

Prerequisites

  • The .proto file that defines the service (it must be fully resolved with no external files/dependencies)

  • A running gRPC server

  • The grpc plugin installed in your plugin directory

Write a test

Point sources at your .proto file and declare the grpc plugin:

drift-testcase-file: v1
title: "RouteGuide"
sources:
  - name: routeguide
    path: ../routeguide.proto
plugins:
  - name: grpc
operations:
  GetFeature_KnownLocation:
    target: routeguide:routeguide.RouteGuide/GetFeature
    description: "Returns a named feature at a known location"
    parameters:
      request:
        body:
          latitude: 407838351
          longitude: -746143763
    expected:
      response:
        body:
          name: "Patriots Path, Mendham, NJ 07945, USA"

Run the tests against your server:

drift verify \
  --server-url grpc://localhost:50051 \
  --test-files drift/routeguide.testcases.yaml

Target format

A target names the source namespace, the fully qualified service, and the method:

<namespace>:<package>.<Service>/<Method>

Request and response

Set request fields under parameters.request.body and assert on response fields under expected.response.body. Field names match the field names in your .proto file.

Drift compares only the fields you list, so you can assert on part of a response and ignore the rest. Enum fields are returned as their string names, such as HIGH or FEATURE_QUALITY_UNSPECIFIED.

Streaming methods

Use a YAML list wherever a stream carries more than one message:

Method type

parameters.request.body

expected.response.body

Unary

Map

Map

Server-streaming

Map

List, compared in order

Client-streaming

List, sent in order

Map

Bidirectional-streaming

List, sent in order

List, compared in order

RecordRoute_BasicClientStream:
  target: routeguide:routeguide.RouteGuide/RecordRoute
  parameters:
    request:
      body:
        - latitude: 407838351
          longitude: -746143763
        - latitude: 413628156
          longitude: -749015468
  expected:
    response:
      body:
        point_count: 2
        feature_count: 2

Streaming assertions compare messages by position, so the order of your list matters.

gRPC errors

Assert on the status code and message returned by a failed call:

GetFeature_NotFound:
  target: routeguide:routeguide.RouteGuide/GetFeatureStrict
  parameters:
    request:
      body:
        latitude: 0
        longitude: 0
  expected:
    response:
      grpc-status: NOT_FOUND
      grpc-message: "feature not found"

Use grpc-status with the status name rather than its numeric value. To match part of a message, use the contains matcher:

grpc-message:
        contains: "not found"

When you assert a non-successful grpc-status, Drift skips response body validation, because a failed call carries no message body.

Publishing to PactFlow

When publishing to PactFlow, use grpc or protobuf as the value for the specification e.g.

pact pactflow publish-provider-contract \
  --provider grpc-example \
  --provider-app-version 1.0.0 \
  ./routeguide.proto \
  --specification grpc \
  ...

Differences from the OpenAPI plugin

If you have written Drift tests for a REST API, three things change:

  • Targets name a service and method, not an HTTP path and verb.

  • Request data goes under parameters.request.body as protobuf fields. There are no query parameters, path parameters, or HTTP headers.

  • You assert on grpc-status and grpc-message instead of an HTTP status code.

Limitations

  • Drift compares streamed messages by position. It does not support unordered or partial stream matching.

  • Drift does not currently support asserting on gRPC metadata.

Publication date: