======= Testing ======= .. Modified: 2018-10-23/05:38-0400 btiffin .. Copyright 2016 Brian Tiffin .. GPL 3.0+ :ref:`license` .. This file is part of the Unicon Programming documentation. .. image:: images/unicon.png :align: center .. only:: html :ref:`genindex` :floatright:`Unicon` .. index:: testing .. _testing: Testing Unicon ============== Unit testing is an important part of software development. The more tests, the better. These can be ad-hoc, and that ad-hoc form of testing is probably still the most prevalent form of testing. In this case, *ad-hoc* meaning that a developer writes some code, then runs the program to see if the new feature functions as expected. This is important to mentally ensure that the current work being done is acceptable, catches typos and the like, but is not very reproducible and ends up being a linear time burden. Each testing pass takes time, or more explicitly, the programmer has to devote some time to testing. Wisdom dictates that it might be smarter to automate some of the testing burden. Spend a little bit of extra time during development to create reproducible test cases. Written once, these tests can be evaluated many times, building up a level of continual confidence in the software and retesting older work to ensure new work does not break previous assumptions or expectations. -------- .. index:: unit testing .. _unit testing: Unit testing ------------ There are a few de facto standard unit testing frameworks. TAP, xUnit, to name two. There are orders of magnitude more engines that run tests and produce an output compatible with these frameworks. cUnit, check, jUnit, to name just a few from the long list. Some programming languages have unit testing baked into the design of the syntax; the ``D`` programming language for instance. .. sourcecode:: d class Sum { int add(int x, int y) { return x + y; } unittest { Sum sum = new Sum; assert(sum.add(3,4) == 7); assert(sum.add(-2,0) == -2); } } The D compilers support a ``-unittest`` command option that set up special compiles for running the ``unittest`` blocks. .. index:: unitest .. _unitest: unitest ------- Now, Unicon gets `unitest`, an engine that can assist with Unicon unit testing. Note the one *t*, uni-test. Yet another unit testing engine. ``unitest`` follows the xUnit framework specification by default\ [#xunit]_. .. literalinclude:: programs/unitest/unitest.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unitest/unitest.icn` This is currently a work in progress. Support for other framework integrations and extended capabilities are in the work plan. ``unitest`` can be used in two ways. In source, which requires a couple of Unicon preprocessor lines to define two different ``main`` functions depending on a compile time define. Or it can be used to :ref:`load` one or more secondary program in the Unicon multi-tasking virtual machine space and act as a monitoring command and control utility. .. todo:: monitoring test mode not yet ready for prime time. Nor is xUnit compatibility actually finished for that matter. In both of these modes, unit testing can be by on the fly expression compiles, given strings, or more conventional :ref:`procedure` testing of the module under test. .. [#xunit] Fibbing, release 0.6 of unitest.icn is not yet xUnit compatible. Character escapes ................. Any expression strings passed to ``test`` include a burden of backslash escaping on the part of the test writer. To test: .. sourcecode:: unicon generator(arg)\1 the string needs to be passed as: .. sourcecode:: unicon test("generator(arg)\\1") That is due to Unicon string compilation, certain characters need to be protected when inside string literals. For the most part test writers will need to protect:: ' quote " double quote \ backslash An example of *in source test expressions*: .. literalinclude:: programs/unitest/tested.icn :language: unicon :start-after: ##+ .. only:: html .. rst-class:: rightalign :download:`programs/unitest/tested.icn` Example testing pass: .. command-output:: unicon -s -c unitest.icn :cwd: programs/unitest .. command-output:: unicon -s tested.icn -x :cwd: programs/unitest .. command-output:: unicon -s -DUNITEST tested.icn -x :cwd: programs/unitest Test Assisted Development ......................... The author of ``unitest`` is not actually a practitioner of the more formal *Test Driven Development*, ``TDD`` method, but follows a slightly looser model of *test assisted development*, ``TAD``. The order of write a test first, then the code, is not a modus operandi in test assisted development. The goal is to write code and then verify it works with various test cases. Let the implementation occur during coding, not as a side effect of how it will pass or fail various tests. Using ``unitest`` does not preclude ``TDD``, but it is not a strict requirement or expectation. .. only:: html .. -------- :ref:`genindex` | Previous: :doc:`documentation` | Next: :doc:`debugging` |