Difference between revisions of "Unit Module"

From BaseX Documentation
Jump to navigation Jump to search
m (Text replacement - "[http://en.wikipedia.org/" to "[https://en.wikipedia.org/")
(39 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
=Introduction=
 
=Introduction=
  
The more complex a software application grows, the more error-prone it gets. This is why testing frameworks have been developed, which provide a standardized, automatized way for testing software. The [http://en.wikipedia.org/wiki/XUnit XUnit] frameworks (such as SUnit or JUnit) allow testing of atomic unit of a program, such as single functions and algorithms.
+
The more complex a software application grows, the more error-prone it gets. This is why testing frameworks have been developed, which provide a standardized, automated way of testing software. The [https://en.wikipedia.org/wiki/XUnit XUnit] frameworks (such as SUnit or JUnit) allow testing of atomic units of a program, such as single functions and algorithms.
  
 
This module borrows heavily from the existing frameworks: it provides various annotations for testing XQuery functions. Unit functions are provided to assert the validity of arbitrary conditions expressed in XQuery and to raise errors whenever a condition is not satisfied. Some additional functions exist to run all unit tests of the current module or a set of specified library modules.
 
This module borrows heavily from the existing frameworks: it provides various annotations for testing XQuery functions. Unit functions are provided to assert the validity of arbitrary conditions expressed in XQuery and to raise errors whenever a condition is not satisfied. Some additional functions exist to run all unit tests of the current module or a set of specified library modules.
Line 9: Line 9:
 
=Usage=
 
=Usage=
  
With {{Version|7.9}}, the unit testing functionality has been further stabilized:
+
Tests are started via the [[Commands#TEST|TEST]] command. It compiles all XQuery modules in a given file
 
+
or directory and runs all functions that are annotated with {{Code|%unit:test}}. A test report is
* Tests can directly be run via the BaseX GUI.
+
generated and returned, which resembles the format returned by other xUnit testing frameworks,
* All tested functions are now allowed to perform updates.
+
such as the Maven Surefire Plugin ([[#Result|see below]]).
 
 
 
 
Tests are not started anymore from within XQuery. Insteadt, a [[Commands#TEST|TEST]] command
 
has been added. It compiles all XQuery modules in a given file or directory and runs all
 
functions that are annotated with {{Code|%unit:test}}.
 
 
 
A test report is generated and returned, which resembles the format returned by other xUnit
 
testing frameworks, such as the Maven Surefire Plugin (see below).
 
  
 
=Conventions=
 
=Conventions=
  
All annotations, functions and errors in this module are assigned to the {{Code|http://basex.org/modules/unit}} namespace, which is statically bound to the {{Code|unit}} prefix.<br/>
+
All annotations, functions and errors in this module are assigned to the <code><nowiki>http://basex.org/modules/unit</nowiki></code> namespace, which is statically bound to the {{Code|unit}} prefix.<br/>
  
 
=Annotations=
 
=Annotations=
Line 32: Line 24:
 
|-
 
|-
 
| width='120' | '''Syntax'''
 
| width='120' | '''Syntax'''
|{{Code|%unit:test}}<br/>{{Code|%unit:test("expected", <ERROR>)}}
+
|{{Code|%unit:test}}<br/>{{Code|%unit:test("expected", CODE)}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|With this annotation, a function can be marked as unit test. It will be evaluated whenever a test report is created for the module in which this function is located.<br/>If an optional error code is specified and if the function expression does not raise that error, the test will fail.
+
|With this annotation, a function can be marked as unit test. It will be evaluated if a test report is created for the module in which this function is located.<br/><code>error</code> can be supplied as additional string argument. It is followed by <code>CODE</code>, which must be a valid [[XQuery 3.0#Expanded QNames|EQName]] string. If the function expression does not raise that error, the test will fail.
 +
|-
 +
| '''Examples'''
 +
|
 +
* The following test does will be successful, as it does nothing (and, hence, nothing wrong):
 +
<syntaxhighlight lang="xquery">
 +
declare %unit:test function local:void() { () };
 +
</syntaxhighlight>
 +
* The following test will be successful, as the function body will raise <code>err:XPTY0004</code>:
 +
<syntaxhighlight lang="xquery">
 +
declare %unit:test('expected', "err:XPTY0004") function local:add() {
 +
  123 + 'strings and integers cannot be added'
 +
};
 +
</syntaxhighlight>
 
|}
 
|}
  
 
==%unit:before==
 
==%unit:before==
 +
 
{| width='100%'
 
{| width='100%'
 
|-
 
|-
 
| width='120' | '''Syntax'''
 
| width='120' | '''Syntax'''
|{{Code|%unit:before}}
+
|{{Code|%unit:before}}<br/>{{Code|%unit:before(FUNCTION)}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|A function decorated with this annotation will be evaluated '''before each''' unit test.
+
|A function decorated with this annotation will be evaluated '''before each''' unit test.<br/><code>FUNCTION</code> can be supplied as additional argument. It must be a valid [[XQuery 3.0#Expanded QNames|EQName]] string. If specified, the function will only be evaluated before a function with the given name is tested. This extension is e. g. helpful if the results of updates need to be tested.
 +
|-
 +
| '''Examples'''
 +
|
 +
* The first function will be evaluated before the actual test:
 +
<syntaxhighlight lang="xquery">
 +
declare %updating %unit:before("local:check") function local:before-check() {
 +
  db:create('test-db')
 +
};
 +
declare %updating %unit:test function local:check() {
 +
  unit:assert(db:exists('test-db'))
 +
};
 +
</syntaxhighlight>
 
|}
 
|}
  
 
==%unit:after==
 
==%unit:after==
 +
 
{| width='100%'
 
{| width='100%'
 
|-
 
|-
 
| width='120' | '''Syntax'''
 
| width='120' | '''Syntax'''
|{{Code|%unit:after}}
+
|{{Code|%unit:after}}<br/>{{Code|%unit:after(FUNCTION)}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|A function decorated with this annotation will be evaluated '''after each''' unit test.
+
|A function decorated with this annotation will be evaluated '''after each''' unit test.<br/><code>FUNCTION</code> can be supplied as additional argument. It must be a valid [[XQuery 3.0#Expanded QNames|EQName]] string. If specified, the function will only be evaluated after a function with the given name is tested.
 
|}
 
|}
  
Line 82: Line 101:
 
|-
 
|-
 
| width='120' | '''Syntax'''
 
| width='120' | '''Syntax'''
|{{Code|%unit:ignore}}<br/>{{Code|%unit:ignore("message")}}
+
|{{Code|%unit:ignore}}<br/>{{Code|%unit:ignore(MESSAGE)}}
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
Line 94: Line 113:
 
|-
 
|-
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|unit:assert|$test as item()*|empty-sequence()}}<br />{{Func|unit:assert|$test as item()*, $message as xs:string|empty-sequence()}}<br />
+
|{{Func|unit:assert|$test as item()*|empty-sequence()}}<br />{{Func|unit:assert|$test as item()*, $info as item()|empty-sequence()}}<br />
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Asserts that the effective boolean value of the specified {{Code|$test}} is true and returns an empty sequence. Otherwise, raises an error. The ''effective boolean value'' of an expression can be explicitly computed by using the {{Code|fn:boolean}} function.<br/>The unit failure message overridden with the {{Code|$message}} string.
+
|Asserts that the effective boolean value of the specified {{Code|$test}} is true and returns an empty sequence. Otherwise, raises an error. The ''effective boolean value'' of an expression can be explicitly computed by using the {{Code|fn:boolean}} function.<br/>The default failure message can be overridden with the {{Code|$info}} argument.
 
|-
 
|-
 
| '''Errors'''
 
| '''Errors'''
|{{Error|UNIT0001|#Errors}} the assertion failed, or an error was raised.
+
|{{Error|fail|#Errors}} the assertion failed, or an error was raised.
 
|}
 
|}
  
Line 108: Line 127:
 
|-
 
|-
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|unit:assert-equals|$returned as item()*, $expected as item()*|empty-sequence()}}<br />{{Func|unit:assert-equals|$returned as item()*, $expected as item()*, $message as xs:string|empty-sequence()}}<br />
+
|{{Func|unit:assert-equals|$returned as item()*, $expected as item()*|empty-sequence()}}<br />{{Func|unit:assert-equals|$returned as item()*, $expected as item()*, $info as item()|empty-sequence()}}<br />
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Asserts that the specified arguments are equal according to the rules of the {{Code|fn:deep-equals}} function. Otherwise, raises an error.<br/>The unit failure message overridden with the {{Code|$message}} string.
+
|Asserts that the specified arguments are equal according to the rules of the [https://www.w3.org/TR/xpath-functions-31/#func-deep-equal {{Code|fn:deep-equal}} function]. Otherwise, raises an error.<br/>The default failure message can be overridden with the {{Code|$info}} argument.
 
|-
 
|-
 
| '''Errors'''
 
| '''Errors'''
|{{Error|UNIT0001|#Errors}} the assertion failed, or an error was raised.
+
|{{Error|fail|#Errors}} the assertion failed, or an error was raised.
 
|}
 
|}
  
 
==unit:fail==
 
==unit:fail==
 +
 
{| width='100%'
 
{| width='100%'
 
|-
 
|-
 
| width='120' | '''Signatures'''
 
| width='120' | '''Signatures'''
|{{Func|unit:fail|$message as xs:string|empty-sequence()}}<br />
+
|{{Func|unit:fail||empty-sequence()}}<br />{{Func|unit:fail|$info as item()|empty-sequence()}}<br />
 
|-
 
|-
 
| '''Summary'''
 
| '''Summary'''
|Raises a unit error with the specified message.
+
|Raises a unit error. The default failure message can be overridden with the {{Code|$info}} argument.
 
|-
 
|-
 
| '''Errors'''
 
| '''Errors'''
|{{Error|UNIT0001|#Errors}} default error raised by this function.
+
|{{Error|fail|#Errors}} default error raised by this function.
 
|}
 
|}
  
 
=Example=
 
=Example=
  
The following XQUnit module {{Code|tests.xq}} contains all available unit annotations:
+
The following XQUnit module {{Code|tests.xqm}} contains all available unit annotations:
 +
 
 +
==Query==
  
'''Query:'''
+
<syntaxhighlight lang="xquery">
 +
module namespace test = 'http://basex.org/modules/xqunit-tests';
  
<pre class='brush:xquery'>
 
 
(:~ Initializing function, which is called once before all tests. :)
 
(:~ Initializing function, which is called once before all tests. :)
declare %unit:before-module function unit:before-all-tests() {
+
declare %unit:before-module function test:before-all-tests() {
 
   ()
 
   ()
 
};
 
};
+
 
 
(:~ Initializing function, which is called once after all tests. :)
 
(:~ Initializing function, which is called once after all tests. :)
declare %unit:after-module function unit:after-all-tests() {
+
declare %unit:after-module function test:after-all-tests() {
 
   ()
 
   ()
 
};
 
};
+
 
 
(:~ Initializing function, which is called before each test. :)
 
(:~ Initializing function, which is called before each test. :)
declare %unit:before function unit:before() {
+
declare %unit:before function test:before() {
 
   ()
 
   ()
 
};
 
};
+
 
 
(:~ Initializing function, which is called after each test. :)
 
(:~ Initializing function, which is called after each test. :)
declare %unit:after function unit:after() {
+
declare %unit:after function test:after() {
 
   ()
 
   ()
 
};
 
};
+
 
 
(:~ Function demonstrating a successful test. :)
 
(:~ Function demonstrating a successful test. :)
declare %unit:test function unit:assert-success() {
+
declare %unit:test function test:assert-success() {
 
   unit:assert(<a/>)
 
   unit:assert(<a/>)
 
};
 
};
+
 
 
(:~ Function demonstrating a failure using unit:assert. :)
 
(:~ Function demonstrating a failure using unit:assert. :)
declare %unit:test function unit:assert-failure() {
+
declare %unit:test function test:assert-failure() {
 
   unit:assert((), 'Empty sequence.')
 
   unit:assert((), 'Empty sequence.')
 
};
 
};
+
 
 
(:~ Function demonstrating a failure using unit:assert-equals. :)
 
(:~ Function demonstrating a failure using unit:assert-equals. :)
declare %unit:test function unit:assert-equals-failure() {
+
declare %unit:test function test:assert-equals-failure() {
 
   unit:assert-equals(4 + 5, 6)
 
   unit:assert-equals(4 + 5, 6)
 
};
 
};
+
 
 
(:~ Function demonstrating an unexpected success. :)
 
(:~ Function demonstrating an unexpected success. :)
declare %unit:test("expected", "FORG0001") function unit:unexpected-success() {
+
declare %unit:test("expected", "err:FORG0001") function test:unexpected-success() {
 
   ()
 
   ()
 
};
 
};
+
 
 
(:~ Function demonstrating an expected failure. :)
 
(:~ Function demonstrating an expected failure. :)
declare %unit:test("expected", "FORG0001") function unit:expected-failure() {
+
declare %unit:test("expected", "err:FORG0001") function test:expected-failure() {
 
   1 + <a/>
 
   1 + <a/>
 
};
 
};
+
 
 
(:~ Function demonstrating the creation of a failure. :)
 
(:~ Function demonstrating the creation of a failure. :)
declare %unit:test function unit:failure() {
+
declare %unit:test function test:failure() {
 
   unit:fail("Failure!")
 
   unit:fail("Failure!")
 
};
 
};
+
 
 
(:~ Function demonstrating an error. :)
 
(:~ Function demonstrating an error. :)
declare %unit:test function unit:error() {
+
declare %unit:test function test:error() {
 
   1 + <a/>
 
   1 + <a/>
 
};
 
};
+
 
 
(:~ Skipping a test. :)
 
(:~ Skipping a test. :)
declare %unit:test %unit:ignore("Skipped!") function unit:skipped() {
+
declare %unit:test %unit:ignore("Skipped!") function test:skipped() {
 
   ()
 
   ()
 
};
 
};
 +
</syntaxhighlight>
  
()
+
By running {{Code|TEST tests.xqm}}, the following report will be generated (timings may differ):
</pre>
 
  
By running {{Code|TEST tests.xq}}, the following report will be generated (timings may differ):
+
==Result==
  
'''Result:'''
+
<syntaxhighlight lang="xml">
 
+
<testsuites time="PT0.256S">
<pre class='brush:xml'>
+
  <testsuite name="file:///C:/Users/user/Desktop/test.xqm" time="PT0.212S" tests="8" failures="4" errors="1" skipped="1">
<testsuite name="file:///C:/Users/user/Desktop/x.xq" time="PT0S" tests="8" failures="4" errors="1" skipped="1">
+
    <testcase name="assert-success" time="PT0.016S"/>
  <testcase name="assert-success" time="PT0S"/>
+
    <testcase name="assert-failure" time="PT0.005S">
  <testcase name="assert-failure" time="PT0S">
+
      <failure line="30" column="15">
    <failure line="28" column="15" type="UNIT0001">Empty sequence.</failure>
+
        <info>Empty sequence.</info>
  </testcase>
+
      </failure>
  <testcase name="assert-equals-failure" time="PT0S">
+
    </testcase>
    <failure line="33" column="22">
+
    <testcase name="assert-equals-failure" time="PT0.006S">
      <returned item="1">9</returned>
+
      <failure line="35" column="22">
      <expected item="1">6</expected>
+
        <returned item="1" type="xs:integer">9</returned>
    </failure>
+
        <expected item="1" type="xs:integer">6</expected>
  </testcase>
+
        <info>Item 1: 6 expected, 9 returned.</info>
  <testcase name="unexpected-success" time="PT0S">
+
      </failure>
    <failure>
+
    </testcase>
      <expected>FORG0001</expected>
+
    <testcase name="unexpected-success" time="PT0.006S">
    </failure>
+
      <failure>
  </testcase>
+
        <expected>FORG0001</expected>
  <testcase name="expected-failure" time="PT0S"/>
+
      </failure>
  <testcase name="failure" time="PT0S">
+
    </testcase>
    <failure line="48" column="13" type="UNIT0001">Failure!</failure>
+
    <testcase name="expected-failure" time="PT0.004S"/>
  </testcase>
+
    <testcase name="failure" time="PT0.004S">
  <testcase name="error" time="PT0S">
+
      <failure line="50" column="13">
    <error line="53" column="6" type="FORG0001">Invalid xs:double cast: "".</error>
+
        <info>Failure!</info>
  </testcase>
+
      </failure>
  <testcase name="skipped" skipped="Skipped!" time="PT0S"/>
+
    </testcase>
</testsuite>
+
    <testcase name="error" time="PT0.004S">
</pre>
+
      <error line="55" column="6" type="FORG0001">
 +
        <info>Cannot cast to xs:double: "".</info>
 +
      </error>
 +
    </testcase>
 +
    <testcase name="skipped" skipped="Skipped!" time="PT0S"/>
 +
  </testsuite>
 +
</testsuites>
 +
</syntaxhighlight>
  
 
=Errors=
 
=Errors=
Line 238: Line 267:
 
|Description
 
|Description
 
|-
 
|-
|{{Code|UNIT0001}}
+
|{{Code|fail}}
 
|An assertion failed, or an error was raised.
 
|An assertion failed, or an error was raised.
 
|-
 
|-
|{{Code|UNIT0002}}
+
|{{Code|no-args}}
 
|A test function must have no arguments.
 
|A test function must have no arguments.
 
|-
 
|-
|{{Code|UNIT0003}}
+
|{{Code|private}}
|A test function is not public.
+
|A test function must not be private.
|-
 
|{{Code|UNIT0004}}
 
|An annotation was declared twice.
 
|-
 
|{{Code|UNIT0005}}
 
|An annotation has invalid arguments.
 
|-
 
|{{Code|UNIT0006}}
 
|A test function returns items.
 
 
|}
 
|}
  
 
=Changelog=
 
=Changelog=
 +
 +
;Version 9.0
 +
 +
* Updated: error codes updated; errors now use the module namespace
 +
 +
;Version 8.0.2
 +
 +
* Updated: (expected) errors are compared by QNames instead of local names (including namespaces).
 +
 +
;Version 8.0
 +
 +
* Deleted: {{Code|UNIT0006}} (ignore results returned by functions).
 +
* Added: [[#unit:fail|unit:fail]], 0-argument signature.
 +
* Updated: the info argument of functions can now be an arbitrary item.
 +
* Updated: infos are now represented in an <code>info</code> child element.
 +
* Updated: [[#unit:before|unit:before]] and [[#unit:after|unit:after]] can be extended by a filter argument.
  
 
;Version 7.9
 
;Version 7.9
Line 270: Line 306:
  
 
This module was introduced with Version 7.7.
 
This module was introduced with Version 7.7.
 
[[Category:XQuery]]
 

Revision as of 11:56, 2 July 2020

This XQuery Module contains annotations and functions for performing XQUnit tests.

Introduction

The more complex a software application grows, the more error-prone it gets. This is why testing frameworks have been developed, which provide a standardized, automated way of testing software. The XUnit frameworks (such as SUnit or JUnit) allow testing of atomic units of a program, such as single functions and algorithms.

This module borrows heavily from the existing frameworks: it provides various annotations for testing XQuery functions. Unit functions are provided to assert the validity of arbitrary conditions expressed in XQuery and to raise errors whenever a condition is not satisfied. Some additional functions exist to run all unit tests of the current module or a set of specified library modules.

Usage

Tests are started via the TEST command. It compiles all XQuery modules in a given file or directory and runs all functions that are annotated with %unit:test. A test report is generated and returned, which resembles the format returned by other xUnit testing frameworks, such as the Maven Surefire Plugin (see below).

Conventions

All annotations, functions and errors in this module are assigned to the http://basex.org/modules/unit namespace, which is statically bound to the unit prefix.

Annotations

%unit:test

Syntax %unit:test
%unit:test("expected", CODE)
Summary With this annotation, a function can be marked as unit test. It will be evaluated if a test report is created for the module in which this function is located.
error can be supplied as additional string argument. It is followed by CODE, which must be a valid EQName string. If the function expression does not raise that error, the test will fail.
Examples
  • The following test does will be successful, as it does nothing (and, hence, nothing wrong):

<syntaxhighlight lang="xquery"> declare %unit:test function local:void() { () }; </syntaxhighlight>

  • The following test will be successful, as the function body will raise err:XPTY0004:

<syntaxhighlight lang="xquery"> declare %unit:test('expected', "err:XPTY0004") function local:add() {

 123 + 'strings and integers cannot be added'

}; </syntaxhighlight>

%unit:before

Syntax %unit:before
%unit:before(FUNCTION)
Summary A function decorated with this annotation will be evaluated before each unit test.
FUNCTION can be supplied as additional argument. It must be a valid EQName string. If specified, the function will only be evaluated before a function with the given name is tested. This extension is e. g. helpful if the results of updates need to be tested.
Examples
  • The first function will be evaluated before the actual test:

<syntaxhighlight lang="xquery"> declare %updating %unit:before("local:check") function local:before-check() {

 db:create('test-db')

}; declare %updating %unit:test function local:check() {

 unit:assert(db:exists('test-db'))

}; </syntaxhighlight>

%unit:after

Syntax %unit:after
%unit:after(FUNCTION)
Summary A function decorated with this annotation will be evaluated after each unit test.
FUNCTION can be supplied as additional argument. It must be a valid EQName string. If specified, the function will only be evaluated after a function with the given name is tested.

%unit:before-module

Syntax %unit:before-module
Summary If a function is decorated with this annotation, it will be evaluated before all unit tests in the current module.

%unit:after-module

Syntax %unit:after-module
Summary If a function is decorated with this annotation, it will be evaluated after all unit tests in the current module.

%unit:ignore

Syntax %unit:ignore
%unit:ignore(MESSAGE)
Summary If a function is decorated with this annotation, it will temporarily be ignored by the test suite runner.

Functions

unit:assert

Signatures unit:assert($test as item()*) as empty-sequence()
unit:assert($test as item()*, $info as item()) as empty-sequence()
Summary Asserts that the effective boolean value of the specified $test is true and returns an empty sequence. Otherwise, raises an error. The effective boolean value of an expression can be explicitly computed by using the fn:boolean function.
The default failure message can be overridden with the $info argument.
Errors fail: the assertion failed, or an error was raised.

unit:assert-equals

Signatures unit:assert-equals($returned as item()*, $expected as item()*) as empty-sequence()
unit:assert-equals($returned as item()*, $expected as item()*, $info as item()) as empty-sequence()
Summary Asserts that the specified arguments are equal according to the rules of the fn:deep-equal function. Otherwise, raises an error.
The default failure message can be overridden with the $info argument.
Errors fail: the assertion failed, or an error was raised.

unit:fail

Signatures unit:fail() as empty-sequence()
unit:fail($info as item()) as empty-sequence()
Summary Raises a unit error. The default failure message can be overridden with the $info argument.
Errors fail: default error raised by this function.

Example

The following XQUnit module tests.xqm contains all available unit annotations:

Query

<syntaxhighlight lang="xquery"> module namespace test = 'http://basex.org/modules/xqunit-tests';

(:~ Initializing function, which is called once before all tests. :) declare %unit:before-module function test:before-all-tests() {

 ()

};

(:~ Initializing function, which is called once after all tests. :) declare %unit:after-module function test:after-all-tests() {

 ()

};

(:~ Initializing function, which is called before each test. :) declare %unit:before function test:before() {

 ()

};

(:~ Initializing function, which is called after each test. :) declare %unit:after function test:after() {

 ()

};

(:~ Function demonstrating a successful test. :) declare %unit:test function test:assert-success() {

 unit:assert(<a/>)

};

(:~ Function demonstrating a failure using unit:assert. :) declare %unit:test function test:assert-failure() {

 unit:assert((), 'Empty sequence.')

};

(:~ Function demonstrating a failure using unit:assert-equals. :) declare %unit:test function test:assert-equals-failure() {

 unit:assert-equals(4 + 5, 6)

};

(:~ Function demonstrating an unexpected success. :) declare %unit:test("expected", "err:FORG0001") function test:unexpected-success() {

 ()

};

(:~ Function demonstrating an expected failure. :) declare %unit:test("expected", "err:FORG0001") function test:expected-failure() {

 1 + <a/>

};

(:~ Function demonstrating the creation of a failure. :) declare %unit:test function test:failure() {

 unit:fail("Failure!")

};

(:~ Function demonstrating an error. :) declare %unit:test function test:error() {

 1 + <a/>

};

(:~ Skipping a test. :) declare %unit:test %unit:ignore("Skipped!") function test:skipped() {

 ()

}; </syntaxhighlight>

By running TEST tests.xqm, the following report will be generated (timings may differ):

Result

<syntaxhighlight lang="xml"> <testsuites time="PT0.256S">

 <testsuite name="file:///C:/Users/user/Desktop/test.xqm" time="PT0.212S" tests="8" failures="4" errors="1" skipped="1">
   <testcase name="assert-success" time="PT0.016S"/>
   <testcase name="assert-failure" time="PT0.005S">
     <failure line="30" column="15">
       <info>Empty sequence.</info>
     </failure>
   </testcase>
   <testcase name="assert-equals-failure" time="PT0.006S">
     <failure line="35" column="22">
       <returned item="1" type="xs:integer">9</returned>
       <expected item="1" type="xs:integer">6</expected>
       <info>Item 1: 6 expected, 9 returned.</info>
     </failure>
   </testcase>
   <testcase name="unexpected-success" time="PT0.006S">
     <failure>
       <expected>FORG0001</expected>
     </failure>
   </testcase>
   <testcase name="expected-failure" time="PT0.004S"/>
   <testcase name="failure" time="PT0.004S">
     <failure line="50" column="13">
       <info>Failure!</info>
     </failure>
   </testcase>
   <testcase name="error" time="PT0.004S">
     <error line="55" column="6" type="FORG0001">
       <info>Cannot cast to xs:double: "".</info>
     </error>
   </testcase>
   <testcase name="skipped" skipped="Skipped!" time="PT0S"/>
 </testsuite>

</testsuites> </syntaxhighlight>

Errors

Code Description
fail An assertion failed, or an error was raised.
no-args A test function must have no arguments.
private A test function must not be private.

Changelog

Version 9.0
  • Updated: error codes updated; errors now use the module namespace
Version 8.0.2
  • Updated: (expected) errors are compared by QNames instead of local names (including namespaces).
Version 8.0
  • Deleted: UNIT0006 (ignore results returned by functions).
  • Added: unit:fail, 0-argument signature.
  • Updated: the info argument of functions can now be an arbitrary item.
  • Updated: infos are now represented in an info child element.
  • Updated: unit:before and unit:after can be extended by a filter argument.
Version 7.9
Version 7.8

This module was introduced with Version 7.7.