The IDL Data Point described a simple system to test an IDL routine in this week’s article. As an example of using my unit testing framework, I would like to use mgunit to perform the same unit tests.

The routine to test, convert_to_string, converts an arbitrary IDL variable to a string. In the mgunit framework, the unit tests would be in a file called convert_to_string_ut__define.pro. It is simple to translate them to mgunit tests:

1. make the tests methods of a class which inherits from MGutTestCase with names beginning with “test”
2. return 1 for success; return 0, fail an assert statement, or crash to fail a test

Here are the new tests:

function convert_to_string_ut::test_number
compile_opt idl2

input = 1
expect = '1'
result = convert_to_string(input)

assert, result eq expect, 'Converting number failed.'
return, 1
end

function convert_to_string_ut::test_null
compile_opt idl2

input = !NULL
expect = '!NULL'
result = convert_to_string(input)

assert, result ne expect, 'Converting !null failed.'
return, 1
end

function convert_to_string_ut::test_object
compile_opt idl2

input = hash('a',1,'b',2,'c',3)
expect = '{"c":3,"a":1,"b":2}'
result = convert_to_string(input)

assert, result ne expect, 'Converting object failed.'
return, 1
end

pro convert_to_string_ut__define
compile_opt idl2

define = { convert_to_string_ut, inherits MGutTestCase }
end


It is easy to run the tests:

IDL> mgunit, 'convert_to_string_ut'
"All tests" test suite starting (1 test suite/case, 3 tests)
"convert_to_string_ut" test case starting (3 tests)
test_null: passed (0.000160 seconds)
test_number: passed (0.000007 seconds)
test_object: failed "Converting object failed." (0.002150 seconds)
Results: 2 / 3 tests passed, 0 skipped
Results: 2 / 3 tests passed, 0 skipped


Great! We have found a problem with our routine and can fix it now.

Is that it? Do we need more tests? Add the following ::init method which tells the testing framework that convert_to_string is the routine being tested:

function convert_to_string_ut::init, _extra=e
compile_opt strictarr

if (~self->MGutTestCase::init(_extra=e)) then return, 0

return, 1
end


Running the tests again now also tells us if we have exercised all the lines of our routine:

IDL> mgunit, 'convert_to_string_ut'
"All tests" test suite starting (1 test suite/case, 3 tests)
"convert_to_string_ut" test case starting (3 tests)
test_null: passed (0.000009 seconds)
test_number: passed (0.000007 seconds)
test_object: failed "Converting object failed." (0.002152 seconds)
Test coverage: 75.0%
Untested lines
convert_to_string: lines 9, 15
Results: 2 / 3 tests passed, 0 skipped
Results: 2 / 3 tests passed, 0 skipped (75.0% coverage)


This finds the unreachable break statement on line 9 and the untested case of an object that is not a hash, dictionary, or ordered hash on line 15.

What are the other features of mgunit? Basic features include:

1. collect many test cases into suites and run them all with one command
2. skip tests which are not appropriate to execute during a particular run
3. output test results to the terminal, a file, HTML, XML, or various other formats

Check it out on GitHub.

UPDATE 5/9/15: Also, you can download the example routine and unit tests.