Version 1 (modified by Philip Taylor, 15 years ago) ( diff )

basic test information

We use the CxxTest framework for tests. See the CxxTest user guide for an introduction and general reference.

Tests are highly recommended for new code, and for bug fixes to old code, because they provide some assurances of quality and help detect regressions and portability issues. Sometimes code might need to be redesigned a bit so that it's more easily testable, which is fine.

There are a few issues specific to our game:

Test locations

The tests for file foo/bar/Baz.{cpp,h} usually go into foo/bar/tests/test_Baz.h, and have the following form:

/* Copyright (C) 2009 Wildfire Games.
 * This file is part of 0 A.D.
 *
 * 0 A.D. is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 0 A.D. is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "lib/self_test.h"

#include "foo/bar/Baz.h"

class TestBaz : public CxxTest::TestSuite 
{
public:
    void test_whatever()
    {
        ...
    }
};

New assertion macros

TS_ASSERT_OK(expr) -- assert expr == INFO::OK.

TS_ASSERT_STR_EQUALS(str1, str2) -- assert std::string(str1) == std::string(str2).

TS_ASSERT_WSTR_EQUALS(str1, str2) -- assert std::wstring(str1) == std::wstring(str2).

TS_ASSERT_STR_CONTAINS(str1, str2) -- assert str2 is contained somewhere within str1.

TS_ASSERT_VECTOR_EQUALS_ARRAY(vec1, array) -- assert a std::vector is equal to a constant-sized array.

Mocks

Particularly for testing code that relies on global system functions (time, getcwd, etc), it can be useful to replace the functions with mock objects that return special values or do special checks on their arguments. The CxxTest guide describes how to do that. We use the following specifics:

  • To mock functions from foo.h, create the file mocks/foo.h saying:
    #include <foo.h>
    #include <cxxtest/Mock.h>
    CXXTEST_MOCK_GLOBAL(...)
    CXXTEST_MOCK_GLOBAL(... etc, as in the CxxTest guide ...)
    
  • Update mocks/mocks_real.cpp to add the line #include "mocks/foo.h"
  • Update mocks/mocks_test.cpp to add the line #include "mocks/foo.h" and, if you want to default to calling the real function (instead of an empty dummy function) in tests that don't override it then add DEFAULT(foo);
  • In any source file that should use the mocks, do a #include "mocks/foo.h" (instead of the original #include <foo.h>), and use T::func() instead of func().

Running tests

To run a single test suite instead of all tests, add the command-line argument -test TestSuitename. To run a single test, do -test TestSuitename::test_case_name (using the class/method names from the test code).

Note: See TracWiki for help on using the wiki.