This appendix gathers all examples that are either too long for the main text or are referenced (but not defined in) the main text.
function unit_init(verbosity, global_vars) ## Initialize the global structure unittest_results, which is needed ## in all functions of the *unittest module. Debugging information ## is printed if verbosity==1. global_vars is a cell array of the ## names of the global variables used in the tests. ## ## e.g. unit_init(1, {"g", "a", "x"}) global unittest_results; unittest_results.verbose = 0; unittest_results.eval_globals = {}; if (nargin > 0) if (!isscalar(verbosity) || verbosity < 0 || verbosity > 1) warning("unit_init: verbose must be 0 or 1"); else unittest_results.verbose = verbosity; endif if (nargin == 2 && iscell(global_vars)) for i = 1:length(global_vars) unittest_results.eval_globals{i} = strcat("global ", global_vars{i}, ";"); endfor else error("global_vars must be a cell array"); endif if (nargin > 2) usage("expecting 2 arguments only"); end endif unittest_results.total = 0; # number of testcases attempted unittest_results.pass = 0; # number of expected passed unittest_results.fail = 0; # number of unexpected failures unittest_results.upass = 0; # number of unexpected passes unittest_results.xfail = 0; # number of expected failures unittest_results.unresolved = 0; # number of unresolved testcases default_eval_print_flag = 0; endfunction
function result = unit_test(test_title, expect_pass, actual_result) ## Function unittest compares the ACTUAL_RESULT of running ## a test (either 0 for failure, or 1 for success) with the ## expected outcome of the test EXPECT_PASS (either 0 for expecting ## a failure, or 1 for expecting pass). TEST_TITLE is the name of ## the test. All test results will be accompanied by the test's ## title. ## ## The result of unittest is on of the following: UNRESOLVED: The ## test did neither return 0 nor 1. PASS: expected pass, got pass. ## FAIL: expected pass, got fail. UPASS: expected fail, got pass. ## XFAIL: expected fail, got fail. ## ## A call to unittest typically looks like this: ## ## unittest("scalar integer addition", 1, eval("1 + 1 == 2;")); global unittest_results; ## Sanity check input parameters if ( nargin < 3 | nargin > 4 ) error("Function run_rest expects 3 or 4 parameters."); endif if (!isstr(test_title)) error("Expecting TEST_TITLE (arg 1) to be a string."); endif if (expect_pass != 0 & expect_pass != 1) error("Expecting EXPECT_PASS (arg 2) to be 0 or 1."); endif unittest_results.total++; ## Take actions depending on what test result we expect ## (expect_pass), and what we actually got (actual_result). if (actual_result != 0 & actual_result != 1) result = "UNRESOLVED"; unittest_results.unresolved++; if (actual_result == 2) printf("SYNTAX ERROR: %s\n", test_title); endif return; endif if (expect_pass == 1 & actual_result == 1) result = "PASS"; if (unittest_results.verbose != 0) printf("PASS: %s\n", test_title); else printf('.'); endif unittest_results.pass++; elseif (expect_pass == 1 & actual_result == 0) result = "FAIL"; printf("FAIL: %s\n\n", test_title); unittest_results.fail++; elseif (expect_pass == 0 & actual_result == 0) result = "XFAIL"; printf("XFAIL: %s\n", test_title); unittest_results.xfail++; elseif (expect_pass == 0 & actual_result == 1) result = "UPASS"; printf("UPASS: %s\n", test_title); unittest_results.upass++; endif endfunction
function unit_test_equals(test_title, result_A, result_B) unit_test(test_title, 1, all(all(result_A == result_B))); endfunction
function unit_test_err(test_title, expected_error_prefix, evaluated_string) unit_test(test_title, 1, erreval(expected_error_prefix, evaluated_string)); endfunction
function e = errcheck(error_prefix) e = 1; if (index(__error_text__, error_prefix) != 1) e = 0; printf("\nUNEXPECTED ERROR: %s", __error_text__); endif end
function rv = erreval(error_prefix, try_str, catch_str) ## erreval() extends the built-in function eval(). Return 0 if ## try_str does not raise the error of type error_prefix, return 1 ## otherwise. global unittest_results; for k = 1:length(unittest_results.eval_globals) eval(unittest_results.eval_globals{k}); end rv = 0; try eval(try_str); catch rv = errcheck(error_prefix); end endfunction
function unit_results() ## Print the results from previous unittest calls in pretty format. global unittest_results; printf("\n"); printf("# of testcases attempted %d\n", unittest_results.total); printf("# of expected passes %d\n", unittest_results.pass); printf("# of expected failures %d\n", unittest_results.xfail); printf("# of unexpected passes %d\n", unittest_results.upass); printf("# of unexpected failures %d\n", unittest_results.fail); printf("# of unresolved testcases %d\n", unittest_results.unresolved); printf("\n"); if (unittest_results.total == unittest_results.pass + unittest_results.xfail) printf("Unit testing completed successfully!\n"); else printf("One or more tests failed!\n"); endif endfunction