Echoed: Observable Integration Testing using OpenTelemetry on top of Jest
Tags: webdev, typescript, testing, showdev
Published: 2024-01-18 15:00:00

Troubleshooting integration test failures can be challenging, especially when you run multiple servers.
If you're running multiple requests in one spec, the complexity increases further.

To tackle this issue, I've created a package called Echoed, integrating OpenTelemetry into Jest.
https://github.com/mrasu/echoed

I'd like to get feedback for it.

## What is Echoed?

Echoed simplifies integration testing, aka API testing, by analyzing requests executed during testing and presenting the results in HTML format.

Key Features:

* **Efficient Debugging**: Easily debug failed tests by aggregating OpenTelemetry traces and logs and outputting HTML.
- **Coverage Measurement**: Measure the coverage of each service's endpoint in a microservices architecture.
- **Propagation Leak Detection**: Identify the lack of OpenTelemetry's context propagation.
- **Span Verification**: Verify the content of spans, such as duration, SQL queries, and more.
- **Compatibility**: No changes are required for existing tests or packages.
- **CI-Friendly**: No external services are needed, making it easy to execute in CI.
- **Jest features**: Since Echoed is built on top of Jest, it supports debugging and parallel execution.

## Visualizing Traces

Echoed creates HTML to visualize the traces of executed requests.

The following image illustrates the trace graph generated by Echoed.
![Trace Graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5nvuq19qvvoy3jm9skjj.png)

In addition to trace visualization, Echoed extends its functionality to offer coverage measurements for each service's endpoints, even when accessed internally within a microservices architecture.
![Coverage Graph](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rq57tvthitq49335a0m4.png)

## Installation
Installing Echoed is a straightforward process, offering two options:

* **New Setup:**
   - Run the command `npx echoed@latest` in your terminal. This will generate a codebase with samples, streamlining your initial setup process.

* **Integration into Existing Test Suite:**
   - Adjust Jest's configuration by modifying `jest.config.js`.
   - Add the Echoed configuration file (.echoed.yml).

For more guidance, refer to the [README](https://github.com/mrasu/echoed/blob/main/README.md) included with GitHub's repository.


## Code

To demonstrate the power of Echoed, let's explore a couple of practical examples.
The following code snippets showcase how Echoed can be seamlessly integrated into your test suites to visualize traces and ensure the correctness of your services.

### Visualizing Traces

Visualizing traces is a breeze with Echoed. Check out the examples below:

```ts
describe("Awesome test", () => {
  it("should pass", async () => {
    const response = await fetch(`http://localhost:8080/api/cart`);
    expect(response.status).toBe(200);

    const body = await response.json();
    expect(body.items.length).toBe(10);
  });
});
```

Because Echoed inspect `fetch` automatically, you can visualize a trace for the `http://localhost:8080/api/cart` without any special code.

### Verifying Executed SQL

To verify executed SQL, `waitForSpan` function is:
```ts
describe("Awesome test", () => {
  it("should create an OpenTelemetry span", async () => {
    const response = await fetch(`http://localhost:8080/api/products`, {
      method: "POST",
      body: JSON.stringify({
          name: "Awesome Product",
          price: 100,
      }),
    });
    expect(response.status).toBe(200);

    const span = await waitForSpan(response, { // <--This line!
      name: "oteldemo.ProductCatalogService/CreateProducts",
      resource: {
        attributes: {
          "service.name": "productcatalogservice",
        },
      },
      attributes: {
        "db.system": "postgresql",
        "db.statement": /INSERT INTO products .+/,
      }
    });

    const query = span.attributes.find(attr => attr.key === "db.statement");
    expect(query?.value?.stringValue).toBe("INSERT INTO products (name, price) VALUES ('Awesome Product', 100)");
  });
});
```

This test checks for the SQL statement, `INSERT INTO...`.
Like this code you can verify the behavior of your services at a detailed level.


## Conclusion

Echoed improves the experience of integration testing.
Visualize traces, measure coverage, and verify the content of spans effortlessly.
Check out the GitHub repository, and give it a try.
{% github https://github.com/mrasu/echoed %}

I'd appreciate any feedback – whether you liked it or not!