Difference between revisions of "Testing"

From Medusa: Coordinate Free Mehless Method implementation
Jump to: navigation, search
Line 57: Line 57:
 
Even if it seems obvious the code is correct, remember that you are writing tests also for the future.
 
Even if it seems obvious the code is correct, remember that you are writing tests also for the future.
 
If tests have a bug, it is much harder to debug!</b>
 
If tests have a bug, it is much harder to debug!</b>
 +
 +
See our examples in [http://www-e6.ijs.si/ParallelAndDistributedSystems/MeshlessMachine/technical_docs/html/examples.html techincal documentation].
  
 
==Running unit tests==
 
==Running unit tests==

Revision as of 18:54, 10 November 2016

Output of successfull ./run_tests.sh script run.
Figure 1: Output of successfull ./run_tests.sh script run.

We have 4 different kind of tests in this library:

  • unit tests
  • style checks
  • docs check
  • system configuration check

The ./run_tests.sh script controlls all tests

Usage: ./run_tests.sh
Options:
  -c   run only configuration test
  -t   run only unit tests
  -s   run only stylechecks
  -d   run only docs check
  -h   print this help
Example:
 ./run_tests.sh -sd

Before pushing run ./run_tests.sh. This script makes and executes all <util_name>_test.cpp test files, checks coding style and documentation. If anything is wrong you will get pretty little red error, but if you see green, like in Figure 1, you're good to go.

Unit tests

All library code is tested by means of unit tests. Unit tests provide verification, are good examples and prevent regressions. For any newly added functionality, a unit test testing that functionality must be added.

Writing unit tests

Every new functionality (eg. added class, function or method) should have a unit test. Unit tests

  • assure that code compiles
  • assure that code executes without crashes
  • assure that code produces expected results
  • define observable behaviour of the method, class, ...
  • prevent future modifications of this code to change this behaviour accidentally

Unit tests should tests observable behaviour, eg. if function gets 1 and 3 as input, output should be 6. They should test for edge cases and most common cases, as well as for expected death cases.

We are using Google Test framework for our unit tests. See their introduction to unit testing for more details.

The basic structure is

TEST(Group, Name) {
    EXPECT_EQ(a, b);
}

Each header file should be accompanied by a <util_name>_test.cpp with unit tests.

When writing unit tests, always write them thoroughly and slowly, take your time. Never copy your own code's ouput to the test; rather produce it by hand or with another trusted tool. Even if it seems obvious the code is correct, remember that you are writing tests also for the future. If tests have a bug, it is much harder to debug!

See our examples in techincal documentation.

Running unit tests

Tests can be run all at once via make run_all_tests or individually via eg. make basisfunc_run_tests.

Compiled binary supports running only specified test. Use ./all_tests --gtest_filter=Domain* for filtering and ./all_tests --help for more options.

Fixing bugs

When you find a bug in the normal code, fix it and write a test for it. The test should fail before the fix, and pass after the it.

Style check

Before commiting, a linter cpplint.py is ran on all the source and test files to make sure that the code follows the style guide. The linter is not perfect, so if any errors are unjust, feel free to comment appropriate lines in the linter out and commit the change.

Docs check

Every function, class or method should also have documentation as einforced by doxygen in the header where they are defined. In the comment block, all parameters, and return value should be meaningully described. It can also containg a short example.

Example:

/**
 * Computes the force that point a inflicts on point b.
 *
 * @param a The index of the first point.
 * @param b The index of the second point
 * @return The size of the force vector from a to b.
 */
double f (int a, int b);

Any longer discussions about the method used or long examples belog to this wiki, but can be linked from the docs.

Configuration testing

The script scripts/configure.sh checks the computer has appropriate packages and that very basic code examples (hdf5, sfml) compile. It currently support arch like and ubuntu like distros.

If you find yourself making modification to .gitlab-ci.yml then maybe you should update this check as well, as well as some documentation in the how to build page but this should not happen very often.