Q14 of 40 · Karate
How do you handle dynamic dates and timestamps in Karate assertions?
Short answer
Short answer: For format validation, use * match response.createdAt == '#string' or a regex: '#regex \\d{4}-\\d{2}-\\d{2}.*'. For value-relative checks (created today, expires in 30 days), compute the expected date with embedded JavaScript using Java's LocalDate, then assert equality against the computed value.
Detail
Server-generated timestamps can't be hard-coded in test assertions. Karate provides two approaches:
1. Type-only check (most common — don't care about the value):
* match response.createdAt == '#string' # any string
* match response.createdAt == '#regex \d{4}-\d{2}-\d{2}.*' # ISO date format
* match response.expiresAt == '#present' # field exists
2. Value-relative check (care about the date value):
* def today = function() { return java.time.LocalDate.now().toString() }
* match response.createdAt contains today()
* def addDays =
"""
function(n) {
return java.time.LocalDate.now().plusDays(n).toString();
}
"""
* match response.expiresAt contains addDays(30)
3. Extract and compare in JS:
* def created = response.createdAt
* def isRecent = function() {
var then = new Date(created);
var now = new Date();
return (now - then) < 5000; // within 5 seconds
}
* assert isRecent()
The key principle: avoid asserting the exact timestamp value unless you genuinely need to verify the server stores the right time. Most tests only need format validation.
// EXAMPLE
timestamp-assertions.feature
Feature: Dynamic date assertions
Scenario: Created order has timestamps in the last 5 seconds
* url 'https://api.example.com'
Given path '/orders'
And request { userId: 1, items: [{ sku: 'A1', qty: 1 }] }
When method POST
Then status 201
# Format check — is it an ISO 8601 date string?
* match response.createdAt == '#regex \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.*'
# Value check — created today?
* def today = java.time.LocalDate.now().toString()
* match response.createdAt contains today
# Expiry check — subscription expires in 30 days?
* def expectedExpiry = java.time.LocalDate.now().plusDays(30).toString()
* def order = call read('classpath:helpers/get-order.feature') { id: response.id }
* match order.expiresOn == expectedExpiry