gRPC is a high-performance RPC framework from Google used for service-to-service communication. Instead of JSON over REST endpoints, clients call methods defined in a .proto file and exchange compact binary Protocol Buffers messages over HTTP/2. You can't test it with a plain REST client, so this guide covers the tools and the test approach.

gRPC vs REST for Testers

RESTgRPC
ContractOptional OpenAPI specMandatory .proto file
PayloadJSON (text)Protocol Buffers (binary)
TransportHTTP/1.1 or 2HTTP/2
Call typesRequest–responseUnary, server streaming, client streaming, bidirectional streaming
ErrorsHTTP status codesgRPC status codes (OK, INVALID_ARGUMENT, NOT_FOUND, UNAUTHENTICATED, DEADLINE_EXCEEDED…)
Manual toolsPostman, curlgrpcurl, Postman (gRPC request), BloomRPC-style GUIs
Advertisement

Testing gRPC Manually with grpcurl

# List services (needs server reflection enabled, or pass -proto)
grpcurl -plaintext localhost:50051 list

# Describe a method
grpcurl -plaintext localhost:50051 describe user.UserService.GetUser

# Call it with a JSON-formatted request
grpcurl -plaintext -d '{"id": "42"}' localhost:50051 user.UserService/GetUser

Automated gRPC Tests in Java

// gRPC test with grpc-java library
// Proto definition (user.proto):
// service UserService {
//   rpc GetUser(GetUserRequest) returns (UserResponse);
//   rpc ListUsers(ListUsersRequest) returns (stream UserResponse);
// }

public class GrpcUserServiceTest {

    private ManagedChannel channel;
    private UserServiceGrpc.UserServiceBlockingStub stub;

    @BeforeClass
    public void setup() {
        channel = ManagedChannelBuilder
            .forAddress(ConfigReader.get("grpc.host"),
                        Integer.parseInt(ConfigReader.get("grpc.port")))
            .usePlaintext()  // no TLS for test env
            .build();

        // Add auth interceptor
        stub = UserServiceGrpc.newBlockingStub(channel)
            .withInterceptors(new AuthHeaderInterceptor(TokenManager.getServiceToken()));
    }

    @Test
    public void getUser_validId_returnsUser() {
        GetUserRequest request = GetUserRequest.newBuilder()
            .setId(42L)
            .build();

        UserResponse response = stub.getUser(request);

        assertThat(response.getId())      .isEqualTo(42L);
        assertThat(response.getName())    .isNotEmpty();
        assertThat(response.getIsActive()).isTrue();
    }

    @Test
    public void getUser_notFound_throwsStatusRuntimeException() {
        GetUserRequest request = GetUserRequest.newBuilder().setId(9999L).build();

        assertThatThrownBy(() -> stub.getUser(request))
            .isInstanceOf(StatusRuntimeException.class)
            .satisfies(e -> {
                StatusRuntimeException sre = (StatusRuntimeException) e;
                assertThat(sre.getStatus().getCode()).isEqualTo(Status.Code.NOT_FOUND);
                assertThat(sre.getStatus().getDescription()).contains("user not found");
            });
    }

    @AfterClass
    public void teardown() throws InterruptedException {
        channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
    }
}
gRPC Status CodeMeaningREST Equivalent
OK (0)Success200 OK
CANCELLED (1)Operation cancelled by client—
NOT_FOUND (5)Resource not found404 Not Found
ALREADY_EXISTS (6)Duplicate resource409 Conflict
PERMISSION_DENIED (7)Not authorised403 Forbidden
UNAUTHENTICATED (16)Missing/invalid credentials401 Unauthorized
RESOURCE_EXHAUSTED (8)Rate limit exceeded429 Too Many Requests
INVALID_ARGUMENT (3)Invalid request data400 / 422
INTERNAL (13)Server error500 Internal Server Error
UNAVAILABLE (14)Service temporarily unavailable503 Service Unavailable

gRPC Test Checklist

  • Every RPC: valid request, missing and invalid fields (expect INVALID_ARGUMENT), unknown IDs (NOT_FOUND), no or bad credentials (UNAUTHENTICATED / PERMISSION_DENIED).
  • Deadlines: set a short deadline and check the client gets DEADLINE_EXCEEDED rather than hanging.
  • Streaming: number and order of streamed messages, behaviour when the client cancels mid-stream.
  • Backward compatibility: old clients still work after the proto changes (adding fields is safe; renumbering or changing field types is not).
  • Metadata: headers such as auth tokens and correlation IDs are passed and enforced.

FAQs

Can Postman test gRPC APIs?

Yes. Postman supports gRPC requests: import the .proto file or use server reflection, choose the method, and send a message written as JSON.

What is the gRPC equivalent of a 404?

The NOT_FOUND status code. gRPC has its own set of status codes, returned in the response trailers, instead of HTTP status codes.

Can REST Assured test gRPC?

No. REST Assured speaks HTTP/JSON. Use the generated gRPC client stubs in Java tests (with JUnit or TestNG), or tools such as grpcurl, Postman or Karate's gRPC support.