If you have a simple form with only a few fields, and little or no scripting, it is reasonably practicable to test it by hand, by doing all the things that the user would use the form for. But if the form is more complicated, particularly if there is a significant amount of scripting, then this becomes more problematic. This really rears its ugly head when you subsequently make a change to the form: has anything been broken as a result of the change?
Unit testing is a testing methodology based on isolating each part of a program or application, and providing tests that verify the functionality of each part. Tests are typically grouped together into test suites, in which the tests are run and from which errors are reported.
Starting with version 2.4.3, Rekall provides some basic support for testing along the lines of unit testing. It is not strictly unit testing, since there is nothing to support isolation of the Rekall application into separate parts. However, it is related in the sense that it provides tests, test suites and error reporting.
By default, tests and test suites are disabled. To enable then, go to the advanced tab of the database connection dialog, and set the Show tests/test suites option. You can turn testing off; enable test (and their associated test menus); or enable tests and test suites. The reason for the intermediate setting is that you can use tests to provide context menus.
TestsIn Rekall a test is effectively an event that is attached to an object. Tests are accessed from the object property dialogs, in the Events section. Double clicking the Tests entry will show a list of tests (in the same way as the list of slots). From here you can add, edit and drop tests.
A rather trivial test is show below, which simply verifies that the button to which the test is attached displays the text Click Me. This would be saved with a name. With the test set up and the form in data view, right clicking on the button will show a popup menu of tests, from which the test can be run. If the button text is Click Me when nothing will happen. If not then a warning will appear indicating that a test has failed, containing the location of the failure (which is not very interesting in this case, since you know which test you have run!).
def eventFunc (button) : RekallTest.test (button.text == "Click Me")
The RekallTest.test function takes an optional second argument, which is an error message. The function returns a boolean result which is the same as value passed as the first argument, ie., the validation expression.
def eventFunc (button) : RekallTest.test (button.text == "Click Me", "OOPS!"")
As noted above, you could use tests to provide context menus, although there is no way at present to change the title that appears on the popup menu.
Test SuitesTest suites provide a method to run a set of one or more tests, and to report any errors that were detected by the tests. When run this way, errors detected by calls to RekallTest.test() will not display error popups. Instead they will be noted and presented when the test suite has completed.
Test suites are set up from the form (document) properties dialog, in the Other section. Like test setup, the property dialog shows a list of current tests suites, from which that can be added, edited or dropped. Clicking add or edit brings up a dialog as shown below. The test suite name is set at the top; below this is a list of a tests in the suite. The lower section is an expandable tree of form objects and tests; this is trimmed to reduce the number of entries (specifically, it only shows objects that have child objects or tests). Tests are added and removed by selecting the appropriate test and clicking the Add or Remove buttons (or by double-clicking in the lower section); tests can be ordered using the Up and Down buttons.
If enabled, test suites appear as a submenu on the form's File menu. When the test has been run, the results of all RekallTest.test() calls are shown in a dialog as below. This shows where the test call was made, the scripting language (the same syntax applies to javascript scripting as well as python), whether the test succeeded or failed, and the message, if any. Failing tests are highlighted in red. In this example, two out of three tests failed - not good!
Note that there is a difference in behaviour when running a test as part of a test suite. When run directly from a context menu, calls to RekallTest.test() which pass a false value as their first argument will return, so if you want to exit the test code at that point, you should check the result code:
def eventFunc (button) : if not RekallTest.test (button.text == "Click Me", "OOPS!"") : return # More tests follow ... #
However, when run as part of a test suite, such a test throws an exception and the remainder of the script is not executed. The exception is trapped, and the test suite moves immediately to the next test. So, at most one failed call to RekallTest.test() will be reported for each test.