liveBook · Manning

End-to-end testing

As explained in gRPC Microservices in Go

End-to-end testing verifies a complete user or business workflow across all relevant application components and external dependencies.

End-to-end testing checks an application flow against a running stack, rather than testing one component in isolation or the integration of two modules. For an order flow, the stack contains the minimum required services: MySQL, Payment, and Order. A client creates an order, retrieves it, and checks the returned fields. section 7.4 section 7.1

Keep these tests selective. More running components reduce isolation, increase resource use, and make execution slower and more expensive. The testing pyramid therefore places fewer end-to-end tests above larger suites of unit and integration tests; it does not suggest omitting them. section 7.1

To run the order-flow test:

  • Create a separate Go e2e module. Put the Docker Compose definition and database setup files in its resources directory; provide Dockerfiles for the services and use mysql:8 for the database. section 7.4.3 section 7.4.1
  • Start the Compose stack in SetupSuite through Testcontainers. Connect a gRPC Order client to the running service, create an order, retrieve it, and assert that the returned fields match. Stop the stack in TearDownSuite even when the test fails, so it does not keep consuming resources. section 7.4.7 section 7.4

Create an order through the running stack

Run `go test -run "^TestCreateOrderTestSuite$"` from the e2e module. The test connects to the Order service at `localhost:8080`, calls Create with a user and an order item, checks for a creation error, then gets the order and verifies its fields. The suite shuts down the Compose stack afterward. section 7.4.7

func (c *CreateOrderTestSuite) SetupSuite() {
    composeFilePaths := []string{"resources/docker-compose.yml"}      #1
    identifier := strings.ToLower(uuid.New().String())                #2
 
    compose := testcontainers.NewLocalDockerCompose(composeFilePaths,
     identifier)
    c.compose = compose                                               #3
    execError := compose.
        WithCommand([]string{"up", "-d"}).
        Invoke()                                                      #4
    err := execError.Error
    if err != nil {
        log.Fatalf("Could not run compose stack: %v", err)
    }
}

The SetupSuite listing shows Testcontainers invoking `docker-compose up -d` before the gRPC assertions run. section 7.4.7

How gRPC Microservices in Go covers it

How deep it goes
Works through stack setup, gRPC assertions, and teardown, without specifying a wider catalog of workflows.
Examples
Uses a containerized create-order test that retrieves the order and checks response fields.
What it assumes
Assumes existing Order and Payment services; treats Docker experience as helpful while specifying the test stack and module setup.
What you can do after
Build it from scratch using a Go test suite, Docker Compose, and Testcontainers to verify a running order workflow.
How it connects
Relates end-to-end tests to unit tests, integration tests, the testing pyramid, test containers, and test suites.

Also explained in

Compare how 12 books explain end-to-end testing →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of gRPC Microservices in Go. The section links point to the parts of the book it draws on.