Responsive

Testing Span Order with Assertions

Testing Span Order with Assertions
Oct 14, 2024
2min
read
Daniel Dias
Software Engineer
Tracetest

Validate trace propagation and service communication with Tracetest by testing if Service B is called after Service A using OpenTelemetry instrumentation.

Share on X
Share on LinkedIn
Share on Reddit
Share on HackerNews
Copy URL

Table of Contents

💡 Are you not sure how OpenTelemetry instrumentation or Trace-based testing works? Click here to see more details.

When you are instrumenting services with OpenTelemetry, you want to see traces propagated from service A to service B, and check if their communication is working as expected. For instance, in the example below, a user sends data to `Service A` and `Service A` calls `Service B` to augment it.

You can validate the communication flow with Tracetest using a selector in the following format.

```yaml
 specs:
 - selector: span[service.name="service-a"] span[service.name="service-b"]
   assertions:
   - attr:tracetest.selected_spans.count >= 1
```

- Declaring the selector in this order means that it will only select spans from `service-b` that come after spans from `service-a`.

- The assertion `attr:tracetest.selected_spans.count >= 1` validates that at least one span exists with that criteria. For further details, visit the [selector documentation](https://docs.tracetest.io/concepts/selectors#parent-child-relation-filtering).

Going back to the example above, you can write a test with a specific assertion to validate it.

```yaml
type: Test
spec:
 id: FMqdxukHg
 name: Test if service B is called after service A
 trigger:
   type: http
   httpRequest:
     method: POST
     url: http://service-a:8800/sendData
     body: "{\n  \"some\": \"test\" \n}"
     headers:
     - key: Content-Type
       value: application/json
 specs:
 - selector: span[tracetest.span.type="http" service.name="service-a" name="POST /sendData"]
             span[tracetest.span.type="http" service.name="service-b" name="POST /augmentData"]
   name: Service B was called after Service A
   assertions:
   - attr:tracetest.selected_spans.count >= 1
```

When running this test with the CLI, you should have the following result.

```bash
tracetest run test -f ./tracetest/test.yaml


# It should output something like this:


# ✔ RunGroup: #uv8yYXkNg (https://app.tracetest.io/organizations/ttorg_1cbdabae7b8fd1c6/environments/ttenv_6e983cd1e9edbecf/run/uv8yYXkNg)
#  Summary: 1 passed, 0 failed, 0 pending
#   ✔ Test if service B is called after service A (https://app.tracetest.io/organizations/ttorg_1cbdabae7b8fd1c6/environments/ttenv_6e983cd1e9edbecf/test/FMqdxukHg/run/9/test) - trace id: 008075c573faf4583f42e67c9bdb4f83
#         ✔ Service B was called after Service A
```

By doing this type of assertion you can validate if the dependencies are organized as intended, and even use it to validate if a trace is being propagated between services.

Here’s what it looks like in the Tracetest UI.

The [example sources](https://github.com/kubeshop/tracetest/tree/main/examples/testing-context-propagation/automatic-instrumentation) used in this article and [setup instructions](https://github.com/kubeshop/tracetest/tree/main/examples/testing-context-propagation/automatic-instrumentation#readme) are available in the Tracetest GitHub repository.

Would you like to learn more about Tracetest and what it brings to the table? Visit the Tracetest [docs](https://docs.tracetest.io/getting-started/installation) and try it out by [signing up today](https://app.tracetest.io)!

Also, please feel free to join our [Slack Community](https://dub.sh/tracetest-community), give [Tracetest a star on GitHub](https://github.com/kubeshop/tracetest), or schedule a [time to chat 1:1](https://calendly.com/ken-kubeshop/45min).