Changes

Jump to navigation Jump to search

Tests

234 bytes added, 06:15, 18 March 2018
→‎Shared functions: "between" is only for two
Having a thorough [httphttps://en.wikipedia.org/wiki/Test_suite test suite] issomething very important which is usually overlooked. It is an incrediblehelp in preventing regression bugs and quickly assess the status of old code. For example, many packages in Octave Forge become deprecated after losingtheir maintainer simply because they have no test suite.
GNU Octave has multiple tools that help in creating a comprehensive testsuite, accessible to both developers and end-users, as detailed on the[http://www.gnu.org/software/octave/doc/interpreter/Test-Functions.html Octave manual]. Basically, test blocks are {{codeline|%!test}} comment blocks, typically at theend of a source file, which are ignored by the Octave interpreter and onlyread by the {{codelinemanual|test}} function.
== Running tests ==
To run all the tests of a specific function, simply use the {{codelinemanual|test}}command at the Octave prompt. For example, to run the tests inof the Octave function {{codelinemanual|mean()}}type:
octave-cli-3.8.2>> test mean
PASSES 17 out of 17 tests
These tests are written in the Octave language at the bottom of the[http://hg.savannah.gnu.org/hgweb/octave/file/6443693a176f/scripts/statistics/base/mean.m#l130 at the bottom of <code>mean.m file</code>]which defines the {{codelinemanual|mean()}}function. It is important that these tests arealso available for the end users so they can test the status of theirinstallation. The whole Octave test suite can be ran run with:
octave-cli-3.8.2>> __run_test_suite__
Integrated test scripts:
See the file test/fntests.log for additional details.
To run tests in a specific file, one can simply specify the path instead ofa function name:
test /full/path/to/file.ccm
== Writing tests ==
 
Tests appear as <code>%!</code> blocks at the bottom of the source file, together with <code>%!demo</code> blocks. A typical m function file, will have the following structure:
 
<syntaxhighlight lang="Octave">
## Copyright
##
## A block with the copyright notice
## -*- texinfo -*-#### A block with the help text function [x, y, z] == Writing tests ==foo (bar) ## some amazing codeendfunction
Tests appear as {{codeline|%!}} blocks at the bottom of the source fileassert (foo (1))%!assert (foo (1:10))%!assert (foo ("on"),"off")together with {{codeline|%!demo}} blockserror <must be positive integer> foo (-1)%!error <must be positive integer> foo (1. A typical m function file, willhave the following structure:5)
## Copyright ## ## A block with the copyright notice ## -*- texinfo -*- ## ## A block with the help text function [x, y, z] = foo (bar) ## here's some amazing code endfunction %!assert (foo (1)) %!assert (foo (1:10)) %!assert (foo ("on"), "off") %!error <must be positive integer> foo (-1) %!error <must be positive integer> foo (1.5) %!demo %! ## see how cool foo() is: %! foo([1:100])</syntaxhighlight>
Tests can be added to oct functions in the C++ sources just as easily, see
following structure:
<syntaxhighlight lang="c++">// Copyright // // A block with the copyright notice
DEFUN_DLD (foo, args, , "-*- texinfo -*-\n\ A block with the help text") { \\ here's // some amazing code } function [x, y, z] = foo (bar) ## here's some amazing code endfunction
/* %!assert (foo (1)) %!assert (foo (1:10)) %!assert (foo ("on"), "off") %!error <must be positive integer> foo (-1) %!error <must be positive integer> foo (1.5) */</syntaxhighlight>
=== Assert ===
{{codeline|%!assert}} lines are the simplest tests to write and also the most
common:
<syntaxhighlight lang="Octave">%!assert (foo (bar)) # test fails if "foo (bar)" returns false %!assert (foo (bar), qux) # test fails if "foo (bar)" is different from "qux"</syntaxhighlight>
These are actually a shorthand version of
{{codeline|%!test assert (foo (bar))}}, and {{codeline|assert}} is simply
an Octave function that throws errors an error when two arguments fail to compare.
=== Test ===
While single line {{codeline|%!assert}}s lines are the most common test usedtests,{{codeline|%!test}} blocks are the ultimate, most useful, offer more features and flexibleflexibility. The code within such block {{codeline|%!test}} blocks is simply processed through the Octave interpreterand if . If the code generates an error, then the test is said to fail. Theseoften Often {{codeline|%!test}} blocks end with a call to {{codeline|assert}}:
<syntaxhighlight lang="Octave">%!test %! a = [0 1 0 0 3 0 0 5 0 2 1]; %! b = [2 5 8 10 11]; %! for i = 1:5 %! assert (find (a, i), b(1:i)) %! endfor</syntaxhighlight>
==== Test for no failure ====
simply with:
<syntaxhighlight lang="Octave">%!test foo (bar)</syntaxhighlight>
=== Error / Warning ===
{{codeline|error}} (or {{codeline|warning}}) blocks:
<syntaxhighlight lang="Octave">%!error foo () # test that causes any error %!error <BAR must be a positive integer> foo (-1.5) # test that throws specific error message %!error id=Octave:invalid-fun-call foo () # test that throws specific error id
%!warning foo () # test that causes any warning %!warning <negative values might give inaccurate results> foo (-1.5) # test that triggers a specific warning message %!warning id=BAR:possibly-inaccurate-result foo (-1.5) # test that triggers a specific warning id</syntaxhighlight>
=== Shared functions ===
It is often useful to share a function between among multiple testtests. Sometimes
these are only small helper functions, but more often these are just simpler
low performance implementations of the function being tested. These are
created in {{codeline|%!function}} blocks:
<syntaxhighlight lang="Octave">
%!function x = slow_foo (bar)
%! ## a simple implementation of foo, definitely correct, but
%! ## unfortunately too slow for anything other than tests.
%!endfunction
%!function x = slow_foo (bar) %! ## a simple implementation of foo, definitely correct, but %! ## unfortunately too slow for anything other than tests. %!endfunction %!assert (foo (bar), slow_foo (bar)) %!test %! for i = -100:100 %! bar = qux (i); %! assert (foo (bar), slow_foo (bar)) %! endfor 
%!test%! for i =-100:100%! bar = Code coverage ==qux (i);%! assert (foo (bar), slow_foo (bar))%! endfor</syntaxhighlight>
[[Category:Testing]]
[[Category:Development]]
Anonymous user

Navigation menu