-
Notifications
You must be signed in to change notification settings - Fork 63
Unit Testing
The Roxy framework includes a unit testing component. Unit testing typically provides two main benefits:
- Good tests give you confidence that your code does what you think it does
- Tests show other developers how you expect your code will be used
To create a test app-server, make sure you have these two properties un-commented in deploy/build.properties:
test-content-db=${app-name}-content-test
test-port=8042
Change the test-port to an open port, then run "ml {env} bootstrap". Then point your browser to
http://{server}:{test-port}/test/
By convention, expect to create a test suite for a library module in your application. To get started, create a directory under src/test/suites/ named for your library module.
Inside your test suite, you can create four specially-named files:
- setup.xqy - This module will be run before each test in your suite. Here you might insert a document into the test database that each of your tests will modify.
- teardown.xqy - This module will run after each test in your suite. You might use this module to remove the document inserted by setup.xqy.
- suite-setup.xqy - Run once when your suite is started. You can use this to insert some data that will not be modified over the course of the suite's tests.
- suite-teardown.xqy - Run once when your suite is finished, to clean up after the suite's tests.
You create your test modules in the test suite directory. Typically, a module has responsibility for testing a particular function.
You can also create subdirectories in your test suite. The testing component will ignore these, so they are a good place for supporting files, like test data.
As an example, consider a hypothetical library module that converts Comma Separated Values (CSV) to XML called csv-lib.xqy. Let's suppose it has a function called convert. We might test that with files like the following:
- suites/csv-lib/suite-setup.xqy
- suites/csv-lib/convert.xqy
- suites/csv-lib/suite-teardown.xqy
- suites/csv-lib/test-data/td.xqy
Why put test data into a separate module and not into suite-setup.xqy? Because this way, setup, teardown and the test(s) can all refer to the same data source, making it easier to update the tests.
The testing component has a helper library that provides several assert functions:
- assert-true($supposed-truths as xs:boolean*)
- assert-true($supposed-truths as xs:boolean*, $msg as item()*)
- assert-false($supposed-falsehoods as xs:boolean*)
- assert-equal($expected as item()*, $actual as item()*)
- assert-not-equal($expected as item()*, $actual as item()*)
- assert-exists($item as item()*)
- assert-all-exist($count as xs:unsignedInt, $item as item()*)
- assert-not-exists($item as item()*)
- assert-at-least-one-equal($expected as item()*, $actual as item()*)
- assert-same-values($expected as item()*, $actual as item()*) - Return true if and only if the two sequences have the same values, regardless of order.
- assert-meets-minimum-threshold($expected as xs:decimal, $actual as xs:decimal+)
- assert-meets-maximum-threshold($expected as xs:decimal, $actual as xs:decimal+)
- assert-throws-error($function as xdmp:function)
- assert-throws-error($function as xdmp:function, $error-code as xs:string?)
- assert-throws-error($function as xdmp:function, $params as item()*, $error-code as xs:string?)
- assert-http-get-status($url as xs:string, $options as element(xdmp-http:options), $status-code)
It is good practice to use a specific assert function. So rather than:
test:assert-equal(fn:true(), $actual)
use this instead:
test:assert-true($actual)
Using specific asserts makes your intentions more clear to developers who read your test code.