Skip to main content

Advanced: check options

By default, when doing regular file-based testing or testing against immediate values, DepotTest will apply the following policy:

  • data that has a primary key will be matched by that key in order to improve the legibility of difference reports
  • additional fields provided by the actual data but missing from the expectations are ignored
  • array ordering is significant, i.e. if you expect a property with type array<integer> to contain [1, 2, 3] but the value returned by the database is [3, 2, 1], this will be flagged as an error.

Controlling the primary key

By default, DepotTest will attempt to match the actual and the expected value sets using the primary key of the schema, if it exists. It uses the following policy:

  • if the schema is an object schema, then the rows are matched using the id
  • if the schema is a view or query schema that has a primary key defined, then the rows are matched using that key (the key can span multiple properties and can also look for nested field values).
  • if there is no primary key defined, then DepotTest will look for a column that is:
    1. present in all values of the actual and expected value sets
    2. has no duplicate values (each value must be unique within the actual or expected value sets)
    3. has the greatest overlap between the actual and expected value sets
    4. to break ties, a column ending in id is preferred to a column containing id in its name which is preferred to any other column.

It is possible to force DepotTest to use a specific column (or set of columns) as a primary key for the purpose of testing, by setting the indexRowsBy property of the checks global option or the indexRowsBy of the specific .check() clause:

it("should use the `foo` and `bar.baz` columns to match rows for comparison", async () => {
await DepotTest.in(namespace)
.options({
checks: {
comparisonKey: ['foo', 'bar.baz'], /* Do this (global to the scenario)... */
}
})
.setContent({ /* ... */})
.check({
/* ... */
})
.run();
})

or

it("should use the `foo` and `bar.baz` columns to match rows for comparison", async () => {
await DepotTest.in(namespace)
.setContent({ /* ... */ })
.check({
/* ... */
comparisonKey: ['foo', 'bar.baz'], /* ...or that (specific to this check) */
})
.run();
})

The following values for comparisonKey have special meaning:

  • ['*'] (the default): try to figure out which testing primary key to use, using the policy described above
  • []: do not use any primary key for testing, treat the actual and expected value sets as unordered lists and compare them like that. This reverts the policy to what was implemented in DepotTest version 7.6.2 and prior.

Relaxing array ordering

It is possible to relax the array ordering check by doing one of:

  • setting the ignoreArrayOrder property of the checks option to true in the test file
  • setting the ignoreArrayOrder property in one .check() clause to true.

As an example:


it("should ignore array order", async () => {
await DepotTest.in(namespace)
.options({
checks: {
ignoreArrayOrder: true, /* Do this (global to the scenario)... */
}
})
.setContent({ /* ... */})
.check({
/* ... */
})
.run();
})

or


it("should ignore array order", async () => {
await DepotTest.in(namespace)
.setContent({ /* ... */ })
.check({
/* ... */
ignoreArrayOrder: true, /* ...or that (specific to this check) */
})
.run();
})

Behind the scenes

DepotTest uses the JsonUnit library to compare JSON values.

It is possible to use directly some of that library's abilities:

  • Using escapes to perform regex matching is available: "${json-unit.regex}[A-Z][a-z]+"
  • Ignoring a field explicitly: a value of "${json-unit.ignore}" will mark the field to be explicitly ignored.
  • Enforcing that a field contains a number of any value: "${json-unit.any-number}"