OpenTelemetry SDK Testing utilities providing comprehensive testing support for OpenTelemetry Java SDK applications with AssertJ assertions, in-memory exporters, and JUnit integration.
—
Comprehensive fluent assertions for validating OpenTelemetry telemetry data. Built on AssertJ, these assertions provide type-safe, readable validation of spans, metrics, logs, and their associated attributes, events, and metadata.
Main entry point providing factory methods for all OpenTelemetry assertion types.
class OpenTelemetryAssertions extends Assertions {
// Primary assertion factory methods
static SpanDataAssert assertThat(SpanData spanData);
static MetricAssert assertThat(MetricData metricData);
static LogRecordDataAssert assertThat(LogRecordData logRecord);
static AttributesAssert assertThat(Attributes attributes);
static EventDataAssert assertThat(EventData eventData);
// Attribute entry creation utilities
static Map.Entry<AttributeKey<String>, String> attributeEntry(String key, String value);
static Map.Entry<AttributeKey<Boolean>, Boolean> attributeEntry(String key, boolean value);
static Map.Entry<AttributeKey<Long>, Long> attributeEntry(String key, long value);
static Map.Entry<AttributeKey<Double>, Double> attributeEntry(String key, double value);
static Map.Entry<AttributeKey<List<String>>, List<String>> attributeEntry(String key, String... value);
static Map.Entry<AttributeKey<List<Boolean>>, List<Boolean>> attributeEntry(String key, boolean... value);
static Map.Entry<AttributeKey<List<Long>>, List<Long>> attributeEntry(String key, long... value);
static Map.Entry<AttributeKey<List<Double>>, List<Double>> attributeEntry(String key, double... value);
// Attribute assertion builders
static <T> AttributeAssertion satisfies(AttributeKey<T> key, Consumer<T> assertion);
static <T> AttributeAssertion equalTo(AttributeKey<T> key, T value);
}Comprehensive assertions for validating SpanData objects including identity, hierarchy, timing, attributes, events, links, and status.
class SpanDataAssert extends AbstractAssert<SpanDataAssert, SpanData> {
// Identity assertions
SpanDataAssert hasTraceId(String traceId);
SpanDataAssert hasSpanId(String spanId);
SpanDataAssert hasName(String name);
SpanDataAssert hasKind(SpanKind kind);
// Hierarchy assertions
SpanDataAssert hasParent(SpanData parent);
SpanDataAssert hasParentSpanId(String parentSpanId);
SpanDataAssert hasNoParent();
// State assertions
SpanDataAssert isSampled();
SpanDataAssert isNotSampled();
SpanDataAssert hasEnded();
SpanDataAssert hasNotEnded();
// Timing assertions
SpanDataAssert startsAt(long epochNanos);
SpanDataAssert startsAt(Instant timestamp);
SpanDataAssert endsAt(long epochNanos);
SpanDataAssert endsAt(Instant timestamp);
// Attribute assertions
SpanDataAssert hasAttribute(AttributeKey<T> key, T value);
SpanDataAssert hasAttribute(AttributeAssertion assertion);
SpanDataAssert hasAttributes(Attributes attributes);
SpanDataAssert hasAttributesSatisfying(Consumer<Attributes> condition);
SpanDataAssert hasAttributesSatisfying(AttributeAssertion... assertions);
SpanDataAssert hasAttributesSatisfyingExactly(AttributeAssertion... assertions);
// Event assertions
SpanDataAssert hasException(Throwable exception);
SpanDataAssert hasEvents(EventData... events);
SpanDataAssert hasEventsSatisfying(Consumer<List<? extends EventData>> condition);
SpanDataAssert hasEventsSatisfyingExactly(Consumer<EventDataAssert>... assertions);
// Link assertions
SpanDataAssert hasLinks(LinkData... links);
SpanDataAssert hasLinksSatisfying(Consumer<List<? extends LinkData>> condition);
// Status assertions
SpanDataAssert hasStatus(StatusData status);
SpanDataAssert hasStatusSatisfying(Consumer<StatusDataAssert> condition);
// Metadata assertions
SpanDataAssert hasResource(Resource resource);
SpanDataAssert hasResourceSatisfying(Consumer<ResourceAssert> resource);
SpanDataAssert hasInstrumentationScopeInfo(InstrumentationScopeInfo scope);
SpanDataAssert hasTotalRecordedEvents(int count);
SpanDataAssert hasTotalRecordedLinks(int count);
SpanDataAssert hasTotalAttributeCount(int count);
}Usage examples:
// Basic span validation
assertThat(span)
.hasName("http-request")
.hasKind(SpanKind.CLIENT)
.hasEnded()
.hasAttribute(AttributeKey.stringKey("http.method"), "GET")
.hasAttribute(AttributeKey.longKey("http.status_code"), 200L);
// Complex attribute validation with custom assertions
assertThat(span)
.hasAttributesSatisfying(
equalTo(AttributeKey.stringKey("service.name"), "my-service"),
satisfies(AttributeKey.longKey("duration"), duration ->
assertThat(duration).isBetween(100L, 5000L))
);
// Event validation
assertThat(span)
.hasEventsSatisfyingExactly(
event -> assertThat(event).hasName("request.start"),
event -> assertThat(event).hasName("request.end")
);Assertions for validating MetricData objects with support for all metric types (gauges, sums, histograms, exponential histograms, summaries).
class MetricAssert extends AbstractAssert<MetricAssert, MetricData> {
// Basic metric properties
MetricAssert hasName(String name);
MetricAssert hasDescription(String description);
MetricAssert hasUnit(String unit);
// Metadata assertions
MetricAssert hasResource(Resource resource);
MetricAssert hasResourceSatisfying(Consumer<ResourceAssert> resource);
MetricAssert hasInstrumentationScopeInfo(InstrumentationScopeInfo scope);
// Data type specific assertions
MetricAssert hasDoubleGaugeSatisfying(Consumer<DoubleGaugeAssert> assertion);
MetricAssert hasLongGaugeSatisfying(Consumer<LongGaugeAssert> assertion);
MetricAssert hasDoubleSumSatisfying(Consumer<DoubleSumAssert> assertion);
MetricAssert hasLongSumSatisfying(Consumer<LongSumAssert> assertion);
MetricAssert hasHistogramSatisfying(Consumer<HistogramAssert> assertion);
MetricAssert hasExponentialHistogramSatisfying(Consumer<ExponentialHistogramAssert> assertion);
MetricAssert hasSummarySatisfying(Consumer<SummaryAssert> assertion);
}Usage examples:
// Gauge metric validation
assertThat(gaugeMetric)
.hasName("memory.usage")
.hasUnit("bytes")
.hasDoubleGaugeSatisfying(gauge ->
gauge.hasPointsSatisfying(point ->
point.hasValue(1024.0)
.hasAttributes(attributeEntry("heap", "used"))
)
);
// Histogram metric validation
assertThat(histogramMetric)
.hasName("request.duration")
.hasUnit("ms")
.hasHistogramSatisfying(histogram ->
histogram.hasPointsSatisfying(point ->
point.hasCount(100)
.hasSum(5000.0)
.hasBucketCounts(10, 30, 40, 20)
)
);Assertions for validating LogRecordData objects including body, severity, timestamps, and associated context.
class LogRecordDataAssert extends AbstractAssert<LogRecordDataAssert, LogRecordData> {
// Basic log properties
LogRecordDataAssert hasBody(String body);
LogRecordDataAssert hasBodyValue(Value<?> body);
LogRecordDataAssert hasSeverity(Severity severity);
LogRecordDataAssert hasSeverityText(String severityText);
// Timing assertions
LogRecordDataAssert hasTimestamp(long epochNanos);
LogRecordDataAssert hasTimestamp(Instant instant);
LogRecordDataAssert hasObservedTimestamp(long epochNanos);
LogRecordDataAssert hasObservedTimestamp(Instant instant);
// Context assertions
LogRecordDataAssert hasSpanContext(SpanContext spanContext);
LogRecordDataAssert hasResource(Resource resource);
LogRecordDataAssert hasResourceSatisfying(Consumer<ResourceAssert> resource);
LogRecordDataAssert hasInstrumentationScopeInfo(InstrumentationScopeInfo scope);
// Attribute assertions
LogRecordDataAssert hasAttributes(Attributes attributes);
LogRecordDataAssert hasAttributesSatisfying(AttributeAssertion... assertions);
LogRecordDataAssert hasTotalAttributeCount(int count);
}Usage examples:
// Basic log validation
assertThat(logRecord)
.hasBody("Request completed successfully")
.hasSeverity(Severity.INFO)
.hasAttribute(AttributeKey.stringKey("service.name"), "my-service")
.hasSpanContext(span.getSpanContext());
// Timestamp validation
assertThat(logRecord)
.hasTimestamp(Instant.parse("2023-01-01T12:00:00Z"))
.hasObservedTimestamp(Instant.parse("2023-01-01T12:00:00.100Z"));Assertions for validating Attributes collections with support for key existence, value matching, and collection properties.
class AttributesAssert extends AbstractAssert<AttributesAssert, Attributes> {
// Entry assertions
AttributesAssert containsEntry(AttributeKey<T> key, T value);
AttributesAssert containsKey(AttributeKey<?> key);
AttributesAssert doesNotContainKey(AttributeKey<?> key);
// Collection assertions
AttributesAssert containsOnly(Map.Entry<? extends AttributeKey<?>, ?>... entries);
AttributesAssert containsOnlyKeys(AttributeKey<?>... keys);
AttributesAssert hasSize(int expectedSize);
AttributesAssert isEmpty();
AttributesAssert isEqualTo(Attributes expected);
// Condition-based assertions
AttributesAssert satisfies(Consumer<Attributes> condition);
}Assertions for collections of traces (grouped spans) with support for validating trace relationships and structure.
class TracesAssert extends AbstractAssert<TracesAssert, Collection<List<SpanData>>> {
// Factory methods
static TracesAssert assertThat(List<SpanData> spanData);
static TracesAssert assertThat(Collection<List<SpanData>> traces);
// Trace collection assertions
TracesAssert hasTracesSatisfyingExactly(Consumer<TraceAssert>... assertions);
TracesAssert hasTracesSatisfyingExactly(Iterable<? extends Consumer<TraceAssert>> assertions);
}
class TraceAssert extends AbstractAssert<TraceAssert, List<SpanData>> {
TraceAssert hasSpansSatisfyingExactly(Consumer<SpanDataAssert>... assertions);
TraceAssert hasSize(int expectedSize);
}The library provides specialized assertion classes for each metric data type:
// Gauge assertions
class DoubleGaugeAssert extends AbstractAssert<DoubleGaugeAssert, GaugeData<DoublePointData>> {
DoubleGaugeAssert hasPointsSatisfying(Consumer<DoublePointAssert>... assertions);
}
class LongGaugeAssert extends AbstractAssert<LongGaugeAssert, GaugeData<LongPointData>> {
LongGaugeAssert hasPointsSatisfying(Consumer<LongPointAssert>... assertions);
}
// Sum assertions
class DoubleSumAssert extends AbstractAssert<DoubleSumAssert, SumData<DoublePointData>> {
DoubleSumAssert isMonotonic();
DoubleSumAssert isNotMonotonic();
DoubleSumAssert isCumulative();
DoubleSumAssert isDelta();
DoubleSumAssert hasPointsSatisfying(Consumer<DoublePointAssert>... assertions);
}
class LongSumAssert extends AbstractAssert<LongSumAssert, SumData<LongPointData>> {
LongSumAssert isMonotonic();
LongSumAssert isNotMonotonic();
LongSumAssert isCumulative();
LongSumAssert isDelta();
LongSumAssert hasPointsSatisfying(Consumer<LongPointAssert>... assertions);
}
// Histogram assertions
class HistogramAssert extends AbstractAssert<HistogramAssert, HistogramData> {
HistogramAssert hasPointsSatisfying(Consumer<HistogramPointAssert>... assertions);
}
class HistogramPointAssert extends AbstractPointAssert<HistogramPointAssert, HistogramPointData> {
HistogramPointAssert hasSum(double expectedSum);
HistogramPointAssert hasCount(long expectedCount);
HistogramPointAssert hasBucketBoundaries(Double... expectedBoundaries);
HistogramPointAssert hasBucketCounts(Long... expectedCounts);
HistogramPointAssert hasExemplars(ExemplarData... expectedExemplars);
}
// Exponential histogram assertions
class ExponentialHistogramAssert extends AbstractAssert<ExponentialHistogramAssert, ExponentialHistogramData> {
ExponentialHistogramAssert hasPointsSatisfying(Consumer<ExponentialHistogramPointAssert>... assertions);
}
class ExponentialHistogramPointAssert extends AbstractPointAssert<ExponentialHistogramPointAssert, ExponentialHistogramPointData> {
ExponentialHistogramPointAssert hasSum(double expectedSum);
ExponentialHistogramPointAssert hasCount(long expectedCount);
ExponentialHistogramPointAssert hasScale(int expectedScale);
ExponentialHistogramPointAssert hasZeroCount(long expectedZeroCount);
ExponentialHistogramPointAssert hasPositiveBuckets(ExponentialHistogramBuckets expectedBuckets);
ExponentialHistogramPointAssert hasNegativeBuckets(ExponentialHistogramBuckets expectedBuckets);
}
// Point data assertions
class DoublePointAssert extends AbstractPointAssert<DoublePointAssert, DoublePointData> {
DoublePointAssert hasValue(double expectedValue);
DoublePointAssert hasExemplars(DoubleExemplarData... expectedExemplars);
}
class LongPointAssert extends AbstractPointAssert<LongPointAssert, LongPointData> {
LongPointAssert hasValue(long expectedValue);
LongPointAssert hasExemplars(LongExemplarData... expectedExemplars);
}Additional assertion classes for supporting data types:
class EventDataAssert extends AbstractAssert<EventDataAssert, EventData> {
EventDataAssert hasName(String name);
EventDataAssert hasEpochNanos(long epochNanos);
EventDataAssert hasTimestamp(Instant timestamp);
EventDataAssert hasAttributes(Attributes attributes);
EventDataAssert hasTotalAttributeCount(int count);
}
class StatusDataAssert extends AbstractAssert<StatusDataAssert, StatusData> {
StatusDataAssert hasCode(StatusCode code);
StatusDataAssert hasDescription(String description);
StatusDataAssert isOk();
StatusDataAssert isError();
StatusDataAssert isUnset();
}
class ResourceAssert extends AbstractAssert<ResourceAssert, Resource> {
ResourceAssert hasAttribute(AttributeKey<T> key, T value);
ResourceAssert hasAttributes(Attributes attributes);
ResourceAssert hasSchemaUrl(String schemaUrl);
}// Attribute assertion builder
class AttributeAssertion {
static <T> AttributeAssertion satisfies(AttributeKey<T> key, Consumer<T> assertion);
static <T> AttributeAssertion equalTo(AttributeKey<T> key, T value);
}
// Abstract base for point assertions
abstract class AbstractPointAssert<SELF extends AbstractPointAssert<SELF, ACTUAL>, ACTUAL extends PointData>
extends AbstractAssert<SELF, ACTUAL> {
SELF hasStartEpochNanos(long expectedStartEpochNanos);
SELF hasEpochNanos(long expectedEpochNanos);
SELF hasAttributes(Attributes expectedAttributes);
SELF hasAttribute(AttributeKey<T> key, T value);
}
// Functional interfaces for type-safe attribute assertions
interface StringAssertConsumer extends Consumer<StringAssert> { }
interface BooleanAssertConsumer extends Consumer<BooleanAssert> { }
interface LongAssertConsumer extends Consumer<LongAssert> { }
interface DoubleAssertConsumer extends Consumer<DoubleAssert> { }
interface StringListAssertConsumer extends Consumer<ListAssert<String>> { }
interface BooleanListAssertConsumer extends Consumer<ListAssert<Boolean>> { }
interface LongListAssertConsumer extends Consumer<ListAssert<Long>> { }
interface DoubleListAssertConsumer extends Consumer<ListAssert<Double>> { }Install with Tessl CLI
npx tessl i tessl/maven-io-opentelemetry--opentelemetry-sdk-testing