Examples of test assertions
Practical examples of test assertions
This page lists examples of how to specify common test assertions to cover message structure and content requirements. Before diving into details, we recommend to get familiar with the basics of test assertions.
Around 80-90% of requirements can be usually specified using our no-code/low-code interface (Truugo Subset Editor). The rest can be implemented as test assertions using Assertion Editor.
Test assertions for XML
Cardinality
Set an element required
A credit note must contain a non-empty reference to an initial invoice.
- Target
- /CreditNote
- Predicate
- InvoiceReferenceID[normalize-space()]
- Error notice
- 'Missing a non-empty element InvoiceReferenceID'
Set an element required using a filter
Each invoice line must contain an item number.
- Target
- /ZORDERS5/IDOC/E1EDP01
- Predicate
- E1EDP19[QUALF="001"]
- Error notice
- 'E1EDP01 is missing E1EDP19[QUALF="001"]'
Set an attribute required
Each monetary amount must include a non-empty currency code.
- Target
- //Amount
- Predicate
- @currencyID[normalize-space()]
- Error notice
- 'Missing a non-empty attribute @currencyID'
Set a limit for item repeat
The credit note must contain a reference to one and only one invoice document.
- Target
- /CreditNote
- Predicate
- count(BillingReference/InvoiceDocumentReference)=1
- Error notice
- concat('Found ', count(BillingReference/InvoiceDocumentReference), ' invoice references')
Set a dependency rule (if-then)
Postal code must be stated when an address includes a street name.
- Target
- //Address
- Precondition
- StreetName[normalize-space()]
- Predicate
- PostalCode[normalize-space()]
- Error notice
- concat('Address with a street "', StreetName, '" is missing a postal code.')
Set a dependency rule (either-or)
Either name or id must be specified for each party role.
- Target
- //Party
- Predicate
- Name[normalize-space()] or ID[normalize-space()]
- Error notice
- 'Party missing both name and id'
Format and enumeration
Specify a list of valid values for an element (enumeration)
An element employment_type must contain one of the values: 01, 02, 03, 05
- Target
- /job_announcement/place_of_work/employment_type
- Predicate
- appFunction('validPattern', text(), '01|02|03|05')
- Error notice
- concat('Invalid value: "', text(), '"')
Specify a list of valid values for an attribute (enumeration)
Bank account's identification scheme must be either BBAN or IBAN.
- Target
- //SellerAccountID[@schemaID]
- Predicate (option 1)
- @schemeID="BBAN" or @schemeID="IBAN"
- Predicate (option 2)
- appFunction('validPattern', @schemeID, 'BBAN|IBAN')
- Error notice
- concat('Invalid value: "', text(), '"')
Set a pattern check #1 (IBAN)
Seller's and buyer's bank accounts are identified using the IBAN number.
- Target
- //SellerAccountID|//BuyerAccountID
- Predicate
- appFunction('validIBAN', text())
- Error notice
- concat('Invalid value: ', text())
Set a pattern check #2 (country code)
Country must be identified using ISO 2-letter country code.
- Target
- //CountryCode
- Predicate
- appFunction('validCountryCode', text())
- Error notice
- concat('Invalid value: ', text())
Set a pattern check #3 (no links)
Text content must not contain URLs/links.
- Target
- //description|//contact_details
- Local variables
-
$pattern = '.*https?:\/\/.*'
$caseSensitive = false
- Precondition
- normalize-space()
- Predicate
- not(appFunction('validPattern', text(), $pattern, $caseSensitive))
- Error notice
- concat('Links found from: ', text())
Integrity
Compare values (date)
The invoice due date must be later than the invoice issue date.
- Target
- /Invoice/InvoiceDueDate
- Precondition
- normalize-space()
- Predicate
- translate(text(), '-', '') > translate(/Invoice/IssueDate, '-', '')
- Error notice
- concat('InvoiceDueDate ' = "', text(), '" (IssueDate = "', /Invoice/IssueDate, '")')
Check item correspondence
- Target
- /Invoice/InvoiceLine[not(VatPercent=preceding-sibling::InvoiceLine/VatPercent)]/VatPercent
- Local variables
- $vatPercent = string()
- Predicate
- /Invoice/TaxTotal/TaxSubtotal[VatPercent=$vatPercent]
- Error notice
- concat('Missing TaxTotal/TaxSubtotal for the VAT percent "', text(), '"')
Set a sum check
Tax amount must match the value of the taxable amount multiplied with the tax percent.
- Target
- /Invoice/TaxTotal/TaxSubtotal/TaxAmount
- Local variables
-
$taxableAmount = ../TaxableAmount
$taxPercent = ../TaxCategory/Percent
$calculatedTaxAmount = $taxableAmount * ($taxPercent div 100)
$statedTaxAmount = text()
- Predicate
- appFunction('countDiff', $statedTaxAmount, $calculatedTaxAmount, 2) <= 0.01
- Error notice
- concat('The stated tax amount ', $statedTaxAmount, ' does not match with the calculated amount ', appFunction('formatNumber', $calculatedTaxAmount, 2), ').')
Test assertions for EDIFACT
Cardinality
Set an segment required
Each despatched item (GRP17) must contain quantity details (QTY).
- Target
- /DESADV/GRP10/GRP17
- Predicate
- QTY
- Error notice
- 'Missing QTY segment'
Set a qualified segment required
The invoice must contain a payment reference (RFF+PQ).
- Target
- /INVOIC
- Predicate
- GRP1/RFF/C506[e1153="PQ"]
- Error notice
- 'Payment reference (RFF="PQ") is missing.'
Set an element required
UNH segment must contain a non-empty element 0057 (association assigned code).
- Target
- /INVOIC/UNH/S009
- Predicate
- e0057[normalize-space()]
- Error notice
- 'Missing a non-empty element 0057.'
Set a element required within a qualified segment
Order reference (RFF+CO) on an invoice line must contain a line number (1156).
- Target
- /INVOIC/GRP21/GRP25/RFF/C506[e1153="CO"]
- Predicate
- e1156[normalize-space()]
- Error notice
- 'RFF+CO missing a non-empty line number 1156.'
Set a limit for item repeat
The credit note must contain a reference to one and only one invoice document.
- Target
- /*
- Predicate
- count(GRP1/RFF[C506/e1153="IV"])=1
- Error notice
- concat('Found ', count(GRP1/RFF[C506/e1153="IV"]), ' invoice references')
Set a dependency rule
The measurement details (MEA) must be provided either as an exact value (e6314) or as a range with both minimum and maximum value (e6162 and e6152).
- Target
- /DESADV/MEA/C174
- Precondition
- not(e6162) or not(e6152)
- Predicate
- e6314
- Error notice
- 'Missing an exact value (6314) or a range (6162+6152).'
Format and enumeration
Specify a list of valid values (enumeration)
The invoice message type must be either a commercial invoice (380) or a credit note (381).
- Target
- /INVOIC/BGM/C002/e1001
- Predicate (option 1)
- text()="380" or text()="381"
- Predicate (option 2)
- appFunction('validPattern', text(), '380|381')
- Error notice
- concat('Invalid value "', text(), '"')
Set a pattern check
Date values (DTM.C507.2380) must be specified using the format CCYYMMDD when 2379=102.
- Target
- //DTM/C507[e2379=102]/e2380
- Precondition
- normalize-space()
- Predicate
- appFunction('validDate', text(), 'YYYYMMDD')
- Error notice
- concat('Invalid value "', text(), '"')
Integrity
Set a sum check
The tax-inclusive total amount (MOA+39) must match the value calculated from the line-level values MOA+79 (total line items amount, tax exclusive) and TAX++VAT (Value added tax).
- Target
- /INVOIC/GRP44/MOA/C516[e5025="39"]/e5004
- Local variables
-
$lineTaxExclusiveAmounts = /*/GRP21/GRP22/MOA/C516[e5025="79"]/e5004
$lineTaxPercents = /*/GRP21/GRP29/TAX[C241/e5153="VAT"]/C243/e5278
$lineTaxTotal = appFunction('countSumProduct', $lineTaxPercents, $lineTaxExclusiveAmounts) div 100
$lineTaxExclusiveTotal = sum($lineTaxExclusiveAmounts)
$lineTaxInclusiveTotal = $lineTaxExclusiveTotal+$lineTaxTotal
- Predicate
- appFunction('countDiff', $lineTaxInclusiveTotal, text()) < 1
- Error notice
- concat('Value "', text(), '" does not match with the calculated line sum "', $lineTaxInclusiveTotal, '".')
Check packaging hierarchy
The packaging level must be specified in the following way: The parent level must be stated before its children and the parent level must have a higher packaging level (CPS.7075) than its children have.
- Target
- /DESADV/GRP10/CPS
- Local variables
- $e7166 = string(e7166)
$parent_CPS = ../preceding-sibling::GRP10/CPS[e7164=$e7166] - Predicate
- $parent_CPS and $parent_CPS/e7075 > e7075
- Error notice
- concat('CPS has the hierarchy level "', e7075, '". Its parent CPS was not found or it does not have a higher packaging level code.')
Check item correspondence
The consolidation item number (receptacle serial number) must be identical to the characters 21–23 of the document identifier (receptacle-ID).
- Target
- /IFCSUM/GRP26/CNI
- Predicate
- string(e1490)=substring(C503/e1004, 21, 3)
- Error notice
- concat('Consolidation item number "', e1490, '" does not match with the chars 21-23 "', C503/e1004, '" of the receptacle-id.')
Examples for use of advanced options
Namespace prefix (XML only)
The credit note must contain a reference to a commercial invoice.
- Namespaces
- doc = urn:oasis:names:specification:ubl:schema:xsd:Invoice-2
cac = urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2
cbc = urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2
- Target
- /doc:CreditNote
- Predicate
- cac:BillingReference/cac:InvoiceDocumentReference/cbc:ID[normalize-space()]
- Error notice
- 'Missing non-empty cac:InvoiceDocumentReference/cbc:ID'
Global variable (separate data file)
The ordered item must be from the product catalog.
- Global variable
- $enumItemID = document('ProductCatalog.xml')//Item/ID
- Target
- //Item/ID
- Predicate
- $enumItemID = text()
- Error notice
- concat(appFunction('getPath', self::node()), ' = ', text())
Global variable (strict/loose validation)
Each order line must contain item ID except in work orders.
- Global variable
- $strictValidation = appFunction('IfThenElse', /Order/ProfileID="WORK", false(), true());
- Target
- //OrderLine
- Precondition
- $strictValidation=true()
- Predicate
- Item/ID[normalize-space()]
- Error notice
- 'Missing a non-empty Item/ID'
Local variable
The invoice total amount must match with a sum of line amounts.
- Target
- /Invoice/InvoiceTotalAmount
- Local variable
- $sumLineAmount = appFunction('countSum', //InvoiceLine/LineAmount, 2)
- Predicate
- appFunction('countDiff', text(), $sumLineAmount) <= 0.01
- Error notice
- concat('InvoiceTotalAmount = ', text(), '(calculated amount: ', $sumLineAmount, ')')
Need further examples? Send us a suggestion of an assertion type you wish to see!