Responsive

Tracetest Tip: Testing Span Order with Assertions

Tracetest Tip: 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

Get Started with Observability-Driven Development

Get Started with Observability-Driven Development

Subscribe to our monthly newsletter to stay up to date with all things Tracetest.

💡 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).