Changes

Jump to navigation Jump to search
226 bytes added ,  16:19, 7 December 2023
=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 [httphttps://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.
=Usage=
Tests are started via the [[Commands#TEST{{Command|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
generated and returned, which resembles the format returned by other xUnit testing frameworks,
=Annotations=
==%unit:test==
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:test}}<br/>{{Code|%unit:test("expected", CODE)}}
|-valign="top"
| '''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.<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.
|-valign="top"
| '''Examples'''
|
* The following test does will be successful, as it does nothing (and, hence, nothing wrong):<pre classlang="brush:'xquery"'>
declare %unit:test function local:void() { () };
</pre>
* The following test will be successful, as the function body will raise <code>err:XPTY0004</code>:
<pre classlang="brush:'xquery"'>
declare %unit:test('expected', "err:XPTY0004") function local:add() {
123 + 'strings and integers cannot be added'
|}
==%unit:before==
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:before}}<br/>{{Code|%unit:before(FUNCTION)}}
|-valign="top"
| '''Summary'''
|A function decorated with this annotation will be evaluated '''before each''' unit testas a separate transaction.<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.|-valign="top"
| '''Examples'''
|
* The first function will be evaluated before the actual test:
<pre classlang="brush:'xquery"'>
declare %updating %unit:before("local:check") function local:before-check() {
db:create('test-db')
|}
==%unit:after==
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:after}}<br/>{{Code|%unit:after(FUNCTION)}}
|-valign="top"
| '''Summary'''
|A function decorated with this annotation will be evaluated '''after each''' unit testas a separate transaction.<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.
|}
==%unit:before-module== 
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:before-module}}
|-valign="top"
| '''Summary'''
|If a function is decorated with this annotation, it will be evaluated '''before all''' unit tests in the current moduleas a separate transaction.
|}
==%unit:after-module== 
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:after-module}}
|-valign="top"
| '''Summary'''
|If a function is decorated with this annotation, it will be evaluated '''after all''' unit tests in the current moduleas a separate transaction.
|}
==%unit:ignore== 
{| width='100%'
|-valign="top"
| width='120' | '''Syntax'''
|{{Code|%unit:ignore}}<br/>{{Code|%unit:ignore(MESSAGE)}}
|-valign="top"
| '''Summary'''
|If a function is decorated with this annotation, it will temporarily be ignored by the test suite runner.
==unit:assert==
 
{| width='100%'
|-valign="top"| width='120' | '''SignaturesSignature'''|{{Func|unit:assert|$test as item()*|empty-sequence()}}<br /pre>{{Func|unit:assert|( $test as item()*, $info as item()| := ()) as empty-sequence()}}<br /pre>|-valign="top"
| '''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 default failure message can be overridden with the {{Code|$info}} argument.
|-valign="top"
| '''Errors'''
|{{Error|fail|#Errors}} the assertion failed, or an error was raised.
{| width='100%'
|-valign="top"| width='120' | '''SignaturesSignature'''|{{Func|unit:assert-equals|$returned as item()*, $expected as item()*|empty-sequence()}}<br /pre>{{Func|unit:assert-equals|( $returned as item()*, $expected as item()*, $info as item()| := ()) as empty-sequence()}}<br /pre>|-valign="top"
| '''Summary'''
|Asserts that the specified arguments are equal according to the rules of the [httphttps://www.w3.org/TR/xpath-functions-3031/#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.|-valign="top"
| '''Errors'''
|{{Error|fail|#Errors}} the assertion failed, or an error was raised.
{| width='100%'
|-valign="top"| width='120' | '''SignaturesSignature'''|{{Func|unit:fail||empty-sequence()}}<br /pre>{{Func|unit:fail|( $info as item()| := ()) as empty-sequence()}}<br /pre>|-valign="top"
| '''Summary'''
|Raises a unit error. The default failure message can be overridden with the {{Code|$info}} argument.
|-valign="top"
| '''Errors'''
|{{Error|fail|#Errors}} default error raised by this function.
==Query==
<pre classlang='brush:xquery'>
module namespace test = 'http://basex.org/modules/xqunit-tests';
==Result==
<pre classlang='brush:"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">
! width="110"|Code
|Description
|-valign="top"
|{{Code|fail}}
|An assertion failed, or an error was raised.
|-valign="top"
|{{Code|no-args}}
|A test function must have no arguments.
|-valign="top"
|{{Code|private}}
|A test function must not be private.
* Deleted: {{Code|UNIT0006}} (ignore results returned by functions).
* Added: [[#unit:fail{{Function||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{{Function||unit:before]] }} and [[#unit:after{{Function||unit:after]] }} can be extended by a filter argument.
;Version 7.9
* Added: TEST command
* Removed: [[#unit:test{{Function||unit:test]]}}, [[#unit:test-uris{{Function||unit:test-uris]]}}
;Version 7.8
* Added: [[#unit:assert-equals{{Function||unit:assert-equals]]}}
* Updated: enhanced test report output
This module was introduced with Version 7.7.
Bureaucrats, editor, reviewer, Administrators
13,554

edits

Navigation menu