# tests.json

Search tests, checked before every publish.

## `tests`

array of objects

A request and its expectations. Plan expectations (`redirect`, `resolved`, `rules`, `sections`) need no engine and run against every draft in milliseconds; result expectations run against the index, also after index runs.

- `id` (string · required): An id unique within its file, such as a search test's, an overlay's or a pattern's.

- `description` (string)

- `request` (object · required): The request, exactly as the Query API receives it. A fixed `time` makes scheduled rules testable.
  
  One search, category page or autocomplete request.
  
  - `query` (string): What the shopper typed. Empty on a category page they only browse.
  
  - `on` (string): Where the request comes from. Default: `search`.
    
    - `search`: The search page's results.
    
    - `category_page`: A category's listing.
    
    - `autocomplete`: A search box's suggestions while the shopper types.
  
  - `channel` (string): The channel. Default: the release's first channel.
  
  - `locale` (string): The locale. Default: the channel's first locale.
  
  - `category` (string): The category page being browsed.
  
  - `filters` (object): The shopper's choices in the page's facets, by field: value or group codes `{ "color": ["grey", "green"] }`, bucket codes `{ "price": ["100-300"] }`, a range `{ "width": { "gte": 160, "lte": 220 } }`, a toggle `{ "on_sale": true }`, and the category facet's choice `{ "category": { "within": "wohnen/sofas" } }`. Values of one field are alternatives; fields narrow each other.
    
    Picks entities (`where`). Attribute codes and the built-in fields `brand`, `price`, `on_sale`, `availability` and `delivery_days` are keys of the same object; `category` takes `is` or `within`.
    
    `{ "any": [{ "brand": "bosch" }, { "quality": "oe" }], "not": { "availability": "out_of_stock" } }`
    
    - `category` (object): The entity is in this category, or below it with `within`.
      
      A category, exactly or including everything below it.
      
      - `is` (string or array of strings): One value, or a list meaning any of them.
      
      - `within` (string or array of strings): One value, or a list meaning any of them.
    
    - `any` ([array of objects](#request.filters) · at least 1 item): At least one of these holds.
    
    - `all` ([array of objects](#request.filters) · at least 1 item): All of these hold; useful inside `any`.
    
    - `not` ([object](#request.filters)): This does not hold.
    
    - `<key>` (boolean, number, string, array of (boolean, number or string) or object): A plain value (equal), a list (any of them), or an operator object such as \{ "lt": 20 \}.
      
      - `lt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
      
      - `lte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
      
      - `gt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
      
      - `gte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
      
      - `between` (array of (boolean, number or string) · 2 items): From the first value to the second, both included.
      
      - `exists` (boolean): True: the field has a value. False: it has none.
  
  - `dismissed` (array of objects): What the shopper took back of what the query named: those words stay text, however often the query is sent again. A value, such as `{ "field": "color", "value": "black" }` or `{ "field": "category", "value": "wohnen/sofas" }`, or every detection of a field, such as `{ "field": "width" }` for a width a pattern read.
    
    A detection the shopper removed.
    
    - `field` (string · required): The field the detection filtered, or `category`.
    
    - `value` (boolean, number or string): The value, a value or group code or a category id; without one, every detection of the field.
  
  - `redirect` (boolean): Lets the response send the shopper elsewhere: to the category page a query names completely, or where a rule redirects. `false` answers with the results instead, as the way back from such a page does. Default: `true`.
  
  - `sort` (string): A sort option. Default: the page's default sort.
  
  - `page` (integer · at least 1): The page, counted from 1.
  
  - `per_page` (integer · 1 to 100): Hits per page, up to the limit [`per_page`](/docs/reference/limits#per_page). Default: 24, which fills rows of two, three, four and six tiles.
  
  - `facets` (array of strings): Facets to count in full, besides those the page counts first (the limit [`counted_facets`](/docs/reference/limits#counted_facets) of its layout, and every one with a choice): a facet the response lists as `deferred` or with `more` comes with every value when it is named here, as a shopper opening it needs. Each must be a facet of some page of the release; one the page does not show is left out.
  
  - `count_only` (boolean): Answers with each section's total alone: no hits, and no facets but those `facets` names, as a filter sheet's "Show 128 results" needs.
  
  - `context` (map of strings): Declared context keys and their values, such as `{ "customer_group": "b2b" }`.
  
  - `time` (string): The time the request is answered at. The Query API stamps it on arrival; only search tests and the preview (`previewSearch`) may fix it, which makes scheduled rules testable.
  
  - `debug` (boolean): Adds the trace to the response.
  
  - `page_view` (string): The page the shopper loaded, which the storefront names anew on every page load. The search log counts a query in the reports once two page views typed it on a day.
  
  - `traffic` (string): Whose search this is: tests and benchmarks say so, and the reports leave them out. Default: `shopper`.
    
    - `shopper`: Everyone a storefront serves that none of the below is.
    
    - `test`: End-to-end tests, which mark their requests so.
    
    - `bench`: A latency benchmark, which marks its requests so.
    
    - `bot`: A crawler or another bot, as uap-core's maintained user agent rules name it; the Query API decides this from the `User-Agent` header of a request that says it is a shopper's.

- `expect` (object · required): - `redirect` (object): The request redirects here.
    
    Where a redirect goes: an entity's page, whose URL follows the merchant's catalog, or a fixed URL.
    
    - `to` (string): An entity named with its type, `type:id`, such as `product:SOFA-LUND-3`.
    
    - `filters` (object): With a category: the filters chosen on its page, as a request's filters name them.
      
      Picks entities (`where`). Attribute codes and the built-in fields `brand`, `price`, `on_sale`, `availability` and `delivery_days` are keys of the same object; `category` takes `is` or `within`.
      
      `{ "any": [{ "brand": "bosch" }, { "quality": "oe" }], "not": { "availability": "out_of_stock" } }`
      
      - `category` (object): The entity is in this category, or below it with `within`.
        
        A category, exactly or including everything below it.
        
        - `is` (string or array of strings): One value, or a list meaning any of them.
        
        - `within` (string or array of strings): One value, or a list meaning any of them.
      
      - `any` ([array of objects](#expect.redirect.filters) · at least 1 item): At least one of these holds.
      
      - `all` ([array of objects](#expect.redirect.filters) · at least 1 item): All of these hold; useful inside `any`.
      
      - `not` ([object](#expect.redirect.filters)): This does not hold.
      
      - `<key>` (boolean, number, string, array of (boolean, number or string) or object): A plain value (equal), a list (any of them), or an operator object such as \{ "lt": 20 \}.
        
        - `lt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `lte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `between` (array of (boolean, number or string) · 2 items): From the first value to the second, both included.
        
        - `exists` (boolean): True: the field has a value. False: it has none.
    
    - `url` (string): A fixed URL: a path such as `/werkstatt`, or one that starts with `https://`.
  
  - `resolved` (object): The resolution contains at least this.
    
    - `category` (string): The id of a category node, such as `wohnen/sofas`: the merchant's id of a `category` entity.
    
    - `filters` (object): Detected filters, such as `{ "color": "grey" }`. Further detected filters do not fail the test.
      
      Picks entities (`where`). Attribute codes and the built-in fields `brand`, `price`, `on_sale`, `availability` and `delivery_days` are keys of the same object; `category` takes `is` or `within`.
      
      `{ "any": [{ "brand": "bosch" }, { "quality": "oe" }], "not": { "availability": "out_of_stock" } }`
      
      - `category` (object): The entity is in this category, or below it with `within`.
        
        A category, exactly or including everything below it.
        
        - `is` (string or array of strings): One value, or a list meaning any of them.
        
        - `within` (string or array of strings): One value, or a list meaning any of them.
      
      - `any` ([array of objects](#expect.resolved.filters) · at least 1 item): At least one of these holds.
      
      - `all` ([array of objects](#expect.resolved.filters) · at least 1 item): All of these hold; useful inside `any`.
      
      - `not` ([object](#expect.resolved.filters)): This does not hold.
      
      - `<key>` (boolean, number, string, array of (boolean, number or string) or object): A plain value (equal), a list (any of them), or an operator object such as \{ "lt": 20 \}.
        
        - `lt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `lte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `between` (array of (boolean, number or string) · 2 items): From the first value to the second, both included.
        
        - `exists` (boolean): True: the field has a value. False: it has none.
    
    - `text` (string): The text left after resolution.
    
    - `complete` (boolean)
  
  - `rules` (object): - `applied` (array of strings)
    
    - `not_applied` (array of strings)
  
  - `sections` (array of strings): The section order begins with these types.
  
  - `results` (object): Expectations on the hits of the first section of the entity's type.
    
    - `top` (integer): How many hits `contains`, `excludes`, `all` and `none` look at. Default: 10.
    
    - `first` (string): An entity named with its type, `type:id`, such as `product:SOFA-LUND-3`.
    
    - `contains` (array of strings)
    
    - `excludes` (array of strings)
    
    - `all` (object): Every hit within `top` matches this.
      
      Picks entities (`where`). Attribute codes and the built-in fields `brand`, `price`, `on_sale`, `availability` and `delivery_days` are keys of the same object; `category` takes `is` or `within`.
      
      `{ "any": [{ "brand": "bosch" }, { "quality": "oe" }], "not": { "availability": "out_of_stock" } }`
      
      - `category` (object): The entity is in this category, or below it with `within`.
        
        A category, exactly or including everything below it.
        
        - `is` (string or array of strings): One value, or a list meaning any of them.
        
        - `within` (string or array of strings): One value, or a list meaning any of them.
      
      - `any` ([array of objects](#expect.results.all) · at least 1 item): At least one of these holds.
      
      - `all` ([array of objects](#expect.results.all) · at least 1 item): All of these hold; useful inside `any`.
      
      - `not` ([object](#expect.results.all)): This does not hold.
      
      - `<key>` (boolean, number, string, array of (boolean, number or string) or object): A plain value (equal), a list (any of them), or an operator object such as \{ "lt": 20 \}.
        
        - `lt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `lte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `between` (array of (boolean, number or string) · 2 items): From the first value to the second, both included.
        
        - `exists` (boolean): True: the field has a value. False: it has none.
    
    - `none` (object): No hit within `top` matches this.
      
      Picks entities (`where`). Attribute codes and the built-in fields `brand`, `price`, `on_sale`, `availability` and `delivery_days` are keys of the same object; `category` takes `is` or `within`.
      
      `{ "any": [{ "brand": "bosch" }, { "quality": "oe" }], "not": { "availability": "out_of_stock" } }`
      
      - `category` (object): The entity is in this category, or below it with `within`.
        
        A category, exactly or including everything below it.
        
        - `is` (string or array of strings): One value, or a list meaning any of them.
        
        - `within` (string or array of strings): One value, or a list meaning any of them.
      
      - `any` ([array of objects](#expect.results.none) · at least 1 item): At least one of these holds.
      
      - `all` ([array of objects](#expect.results.none) · at least 1 item): All of these hold; useful inside `any`.
      
      - `not` ([object](#expect.results.none)): This does not hold.
      
      - `<key>` (boolean, number, string, array of (boolean, number or string) or object): A plain value (equal), a list (any of them), or an operator object such as \{ "lt": 20 \}.
        
        - `lt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `lte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gt` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `gte` (boolean, number or string): A single value in a selector, filter or test: text, a number or a boolean. Dates are text, such as `2026-10-01`.
        
        - `between` (array of (boolean, number or string) · 2 items): From the first value to the second, both included.
        
        - `exists` (boolean): True: the field has a value. False: it has none.

## `$schema`

string

The JSON Schema an editor checks this file against; kept as written.

## Example

```json title="tests/fixtures/home/tests.json (trimmed)"
{
  "$schema": "../../../contracts/schema/tests.json",
  "tests": [
    {
      "id": "rug-size-from-query",
      "description": "A rug size in the query becomes the size filter",
      "request": { "query": "160x230 teppich" },
      "expect": { "resolved": { "filters": { "size": "160x230" } } }
    },
    {
      "id": "three-seater-in-grey",
      "description": "Seats and a color group from one query",
      "request": { "query": "3-sitzer grau" },
      "expect": { "resolved": { "filters": { "color": "grey", "seats": 3 } } }
    }
  ]
}
```

**Guide:** [Search tests](/docs/releases#search-tests)
