Wednesday, September 22, 2010

Test-Driven Development with Dexterity

Often, when speaking to Visual Studio developers I am introduced to some new (or not so new) software engineering technique available via the slur of tools provided by Team Foundation Server (TFS). One of such tools is the ability to write/implement in-line test cases along with the rest of your code. This is known in Software Engineering as Test-Driven development or is sometimes referred to as self-testing code.

Dexterity also has these capabilities, believe it or not. Sufficient to say, that the Dexterity development environment and the sanScript language were conceived by Software Engineering and Compiler purists who were way ahead of their time back in the 80s when the mid market ERP was racing towards identifying a clear leader -- see Microsoft Dynamics GP Architectural Foundations Series - featuring Microsoft's Tim Brookins.

To address this issue, the SanScript language implements assertions. See A Historical Perspective on Runtime Assertion Checking in Software Engineering. An assertion is a claim about the state of computation at the time the assertion is evaluated. Assertions are always written as statements the programmer believes to be true. You can make your code self-testing by adding assertions at different stages. When the assertion fails there may be a potential problem with the script you are writing.

In Dexterity, the assert statement is primarily used to implement these claims. When an assert statement is found, the Dex compiler will evaluate the boolean condition associated with the statement. If the condition turns out to be false, the compiler will display a message related to the assertion. As such, the assert statement is implemented as follows:

assert boolean_expression {, message}

The following code illustrates the implementation of an assertion:

In this case, our assertion or primary assumption is that the selling price of the item be greater than the item cost itself. If we attempt to execute this code with the values shown on the image, the following error will be produced.

Note that an assertion will not prevent the values entered from being saved, but Dexterity will provide the option of aborting the script execution, ignoring the assertion, or debugging the current code to examine other alternatives. For the example above, the developer can choose to implement additional code that will prevent the saving of a record if indeed the selling price must be always greater than the item cost.

The assert statement should be seen as a development and testing tool. The dialog box indicating an assertion failed should not be displayed to the users of your application. By default, the runtime engine will not display the dialog box, even though an assertion failed. To allow testing with the runtime engine, add the RuntimeAsserts=TRUE setting to the defaults file, DEX.INI. This forces the runtime engine to display the dialog box for any assertions that fail.

Since assertion dialogs should not be seen by users, and some overhead is involved in evaluating them, it is strongly recommended that you don’t compile assert statements for the final version of your product. To prevent assert statements from being compiled, don’t compile your application with debug information.

These compilation options can be found in Dexterity Utilities.

Until next post!

Mariano Gomez, MVP
Maximum Global Business, LLC


Anonymous said...

Assertions have their place, I suppose, but they're a long way from unit testing and light-years away from Test-Driven Development. Drawing this equivalency is such a stretch that it only serves to highlight how far Dexterity actually is from anything like useful testing practices. The very fact that it is runtime assertion checking (as opposed to being able to run in its own testing harness) highlights how little it has to do with TDD.

Mariano Gomez said...


Thanks for the input. By no stretch of the imagination am I saying that assertions are the panacea for testing or that they are representative of all the elements of TDD, but they sure allow developers to build other contingencies in their code for that very same purpose and fit within the paraments of what's considered self-testing code.

Mariano Gomez, MVP

Anonymous said...

I agree that the ability to add asserts is a useful element and can aid in developer (and/or QA) testing. But I disagree that this has anything to do with "self-testing". It's not self-testing when those scripts still have to be driven, by a user, for those asserts to be tripped. At best, they're an aid in debugging.

Mariano Gomez said...


Thanks very much for the input. Point taken!

Please keep up the readership and the dialog.

Best regards,

Mariano Gomez, MVP

Mak said...

To add to what you're saying about using asserts to do TDD you can use Dex Test Mode + asserts to create unit tests.

Here's what I do:
1. Create a form called Testing

2. For each function you want to test, create a button, and do a bunch of different calls, using asserts just as you would in Visual Studio unit tests.

3. In Dex Test Mode, pop the Testing form up, and run each test.