Skip to main content

Built-in Matchers

KTestify ships 12 RecordMatcher<V> implementations, split into raw (String) and Avro (GenericRecord) variants. They are selected automatically by RecordMatcherFactory based on the matchMethod in MatchContext.


Factory resolution tableโ€‹

matchMethod constantRaw matcherAvro matcher
methodMatchFileFileRecordMatcherAvroFileRecordMatcher
methodMatchKeyValueFileKeyRecordMatcherAvroFileKeyRecordMatcher
methodFieldsToMatchFieldsRecordMatcherAvroFieldsRecordMatcher
methodMatchXMLXmlRecordMatcherโŒ ConsumerException
methodMatchXPathXPathRecordMatcherโŒ ConsumerException
methodRecordKeyMatchKeyRecordMatcherAvroKeyRecordMatcher
methodMatchAttributesAttributeRecordMatcher<V>โŒ ConsumerException
null / blankNoOpRecordMatcher<V>NoOpRecordMatcher<V>
// Usage
RecordMatcher<String> raw = RecordMatcherFactory.forRaw("matchFile");
RecordMatcher<GenericRecord> avro = RecordMatcherFactory.forAvro("matchFile");

Raw matchers (V = String)โ€‹

FileRecordMatcherโ€‹

Compares the record value character-for-character against a file's content after dynamic variable resolution. Uses StringDiffUtils to produce a coloured ANSI diff on failure.

  • MatchContext fields used: matchFilePaths.get(0)
  • On failure: returns MatchResult.fail(diff, expected, actual)

FileKeyRecordMatcherโ€‹

Asserts both the record key and value. The expected file must contain the key on line 1 and the value from line 2 onwards.

  • MatchContext fields used: matchFilePaths.get(0)

KeyRecordMatcherโ€‹

Asserts only the record key, the value is not evaluated.

  • MatchContext fields used: matchKey (falls back to matchFilePaths.get(0) if blank)

FieldsRecordMatcherโ€‹

Extracts a character range [from, to) from line line of the record value and compares it against the same range from the expected file. Implemented via FieldMatcherUtils.

  • MatchContext fields used: matchFilePaths.get(0), matchKey (encodes line:from:to)

XmlRecordMatcherโ€‹

Parses both the record value and the expected file as XML, optionally removes excluded elements from both, then compares structurally using XMLUtils. Element order does not matter.

  • MatchContext fields used: matchFilePaths.get(0), excludedFields (element name list)
  • Not available for Avro.

XPathRecordMatcherโ€‹

Runs one or more XPath expressions against the record value and compares each extracted value against the corresponding line of the expected file.

  • MatchContext fields used: matchFilePaths.get(0), matchKey (comma-separated XPath expressions)
  • Not available for Avro.

NoOpRecordMatcher<V>โ€‹

Always returns MatchResult.pass(). Used when matchMethod is null or blank, typically for watcher steps that only care about record presence, not content.


AttributeRecordMatcher<V> (1.1.1)โ€‹

Generic, transport agnostic matcher introduced alongside RequestResponseClient<Req, V> for synchronous transports. Asserts one or more entries of ConsumedRecord.getAttributes() against MatchContext.getExpectedAttributes(). Never inspects getValue(), so it works for any V, not only String.

  • MatchContext fields used: expectedAttributes (map of key to expected value)
  • Matching rule: every key in expectedAttributes must be present in the actual record's attributes with an exactly equal String value, only the first record in the list is used
  • On empty expectedAttributes: returns MatchResult.pass() immediately, nothing to assert
  • Typical use: HTTP status code assertions ({"statusCode": "200"}), reusable later by any future transport that populates attributes (gRPC status, MQ reason code, script exit code)
  • Not available for Avro, attributes is populated by synchronous request/response clients, not Avro consumers

Avro matchers (V = GenericRecord)โ€‹

All Avro matchers first deserialise the GenericRecord to a JSON Map via AvroUtils.toJsonMap(), then delegate to comparison logic equivalent to their raw counterparts.

AvroFileRecordMatcherโ€‹

Avro equivalent of FileRecordMatcher. Converts GenericRecord โ†’ JSON string, excludes top-level keys in excludedFields, then compares against the expected file.

  • MatchContext fields used: matchFilePaths.get(0), excludedFields

AvroFileKeyRecordMatcherโ€‹

Avro equivalent of FileKeyRecordMatcher. Asserts key + Avro-serialised JSON value.


AvroKeyRecordMatcherโ€‹

Avro equivalent of KeyRecordMatcher. Key-only assertion; Avro value ignored.


AvroFieldsRecordMatcherโ€‹

Avro equivalent of FieldsRecordMatcher. Extracts a character range from the JSON-serialised Avro value.


Key design rulesโ€‹

  1. excludedFields defaults to Collections.emptyList(), matchers check isEmpty(), never null.
  2. matchFilePaths is always a List<String>, single-record matchers use get(0), batch matchers iterate by index.
  3. XML/XPath matchers throw ConsumerException when called via RecordMatcherFactory.forAvro().
  4. NoOpRecordMatcher is the default when no match method is configured.
  5. expectedAttributes defaults to Collections.emptyMap(), AttributeRecordMatcher checks isEmpty(), never null, same convention as excludedFields.