|
| 1 | +--- |
| 2 | +layout: default |
| 3 | +title: Debugging tests |
| 4 | +nav_order: 5 |
| 5 | +permalink: /docs/debugging |
| 6 | +--- |
| 7 | + |
| 8 | +Like all unit testing frameworks, marklogic-unit-test is intended to speed up the cycle of developing, testing, and |
| 9 | +fixing code. A critical aspect of that is understanding why a test failed and how to fix it. This page provides |
| 10 | +guidance on how you can write your tests to ensure they can be easily debugged by any member of your development |
| 11 | +team. |
| 12 | + |
| 13 | +## Development setup |
| 14 | + |
| 15 | +Before looking at how to write tests, you should ensure that you can change your application code and test the |
| 16 | +changes as quickly as possible. As mentioned in the [Getting started guide](/docs), ml-gradle supports |
| 17 | +[watching for module changes](https://github.com/marklogic/ml-gradle/wiki/Watching-for-module-changes) so that when |
| 18 | +you modify either an application module file or test module file, the file will be immediately loaded into your |
| 19 | +application's modules database. This allows you to test your changes as quickly as possible. |
| 20 | + |
| 21 | +To enable this, simply run the following Gradle task in its own terminal window: |
| 22 | + |
| 23 | + ./gradlew -i mlWatch |
| 24 | + |
| 25 | +The Gradle "-i" flag - for info-level logging - results in each modified file being logged when it is loaded into |
| 26 | +MarkLogic. |
| 27 | + |
| 28 | +## Test assertion messages |
| 29 | + |
| 30 | +Each [assertion function](/docs/assertions) in marklogic-unit-test supports an assertion message as its final argument. |
| 31 | +These are recommended for when the intent of an assertion is not readily apparent from the two values being compared. |
| 32 | + |
| 33 | +For example, consider the following assertion: |
| 34 | + |
| 35 | + const actual = someLib.something(); |
| 36 | + test.assertEqual(3, actual); |
| 37 | + |
| 38 | +If that assertion fails because "actual" has a value of 2, marklogic-unit-test will throw the following error: |
| 39 | + |
| 40 | + expected: 3 actual: 2 (ASSERT-EQUAL-FAILED) |
| 41 | + |
| 42 | +However, this doesn't explain why "3" is the expected value. The optional 3rd argument in `test.assertEqual` |
| 43 | +provides a test developer with a chance to explain why the value is expected - e.g.: |
| 44 | + |
| 45 | + const actual = someLib.something(); |
| 46 | + test.assertEqual(3, actual, "Due to such-and-such reason, 3 should be returned"); |
| 47 | + |
| 48 | +The "such-and-such reason" would of course be replaced with a meaningful explanation in your test. |
| 49 | +marklogic-unit-test will then include this message in the failure message: |
| 50 | + |
| 51 | + Due to such-and-such reason, 3 should be returned; expected: 3 actual: 2 (ASSERT-EQUAL-FAILED) |
| 52 | + |
| 53 | +## Using log statements |
| 54 | + |
| 55 | +While tools such as [mlxprs](https://github.com/marklogic/mlxprs) exist to leverage the debugging capabilities within |
| 56 | +MarkLogic, you may often find it helpful to include log statements both in your application module and in your test |
| 57 | +module. These can log the value of certain variables that are not returned by the function being tested but whose |
| 58 | +values provide insight into how the application code is behaving. |
| 59 | + |
| 60 | +For JavaScript code, use the following: |
| 61 | + |
| 62 | + const value = someLib.something(); |
| 63 | + console.log("The value", value); |
| 64 | + |
| 65 | +And for XQuery code, use the following: |
| 66 | + |
| 67 | + let $value := someLib:something() |
| 68 | + let $_ := xdmp:log(("The value", $value)) |
| 69 | + |
| 70 | +You can add these statements to your tests as well. |
| 71 | + |
| 72 | +Log messages will then appear in the MarkLogic log file named "PORT_ErrorLog.txt", where "PORT" is the port number |
| 73 | +of the MarkLogic app server that you are running the tests against. |
| 74 | + |
| 75 | +## Examining the Gradle test report |
| 76 | + |
| 77 | +When running tests via Gradle - either via `./gradlew test` or `./gradlew mlUnitTest` - one or more test failures will |
| 78 | +result in the task failing with the location of the test report being logged. The test report allows you to see details |
| 79 | +on each test, including the failed assertion message and stacktrace for each failed test. |
| 80 | + |
| 81 | +When running `./gradlew test`, the test report will be available at "build/reports/tests/tests/index.html". You can |
| 82 | +open this file in a web browser to see the results; it is recommended to keep that window open and simply refresh it |
| 83 | +after re-running the Gradle `test` task. |
| 84 | + |
| 85 | +When running `./gradlew mlUnitTest`, the test report is a set of JUnit-formatted XML files available at |
| 86 | +"build/test-results/marklogic-unit-test". This approach does not result in an HTML web page that can be viewed in a web |
| 87 | +browser, but each XML file will contain the results for the tests in a particular suite, including the failed assertion |
| 88 | +messages and stacktrace for each failed test. |
| 89 | + |
0 commit comments