-
Notifications
You must be signed in to change notification settings - Fork 393
Unit Testing
Unit testing has been added to EnergyPlus with tests located in the tst/EnergyPlus/unit subdirectory. A small set of "starter" tests has been committed to demonstrate some of the key usage.
We are using Googletest, also known as gtest. It offers a lot of nice capabilities and a low burden on developers to add new tests. Some of the features are:
- New tests are added by just putting the test file in the unit test directory (and adding the file to the CMakeLists.txt if building with CMake -- until we automate that)
- "Death" tests to check that exceptions or assertions should fire with certain inputs
- Tolerant equality checks for floating point values
- Simple setup/teardown support for tests with dependencies
- Filtering so that only certain tests are run (good while trying to correct test failures)
- Nice colored reports
Googletest documentation can be found here.
Writing tests is simple:
- Add a file (if it doesn't exist) with a name of the form MyClass.unit.cc or MyFunction.unit.cc
- Copying an existing file is a quick way to get the boilerplate structure
- Add the file name to the test_src list in CMakeLists.txt in the unit directory
- Include the necessary headers for the code being tested
- Add using declarations to simplify the names you must type
- Add tests, where each test can include as few or as many checks as you want
The body of the simplest kind of test looks like this:
TEST( TestCaseName, TestName )
{
... // Test body goes here
}
Each test in a file should have the same ''TestCaseName'' and a different ''TestName''. CamelCase without underscores is suggested to avoid internal gtest problems at macro expansion time.
Tests may include some application object declarations, operations, and function calls interspersed with some gtest check statements, such as EXPECT_EQ( a, b );
, which says that a
and b
should be equal. If the check fails then the test fails and gtest will report the test and line number where the failure occurred.
There are a bunch of different checks beyond EXPECT_EQ
. Some of other ones are EXPECT_NE
, EXPECT_LT
, EXPECT_GT
, EXPECT_LE
, EXPECT_GE
, EXPECT_TRUE
, and EXPECT_FALSE
. There are checks that are tolerant for floating point values such as EXPECT_DOUBLE_EQ
to allow for some roundoff and since precision can vary across platforms/compilers/builds.
To run tests on components that need some external state set up the tests use a class where the setup normally happens in the constructor and the teardown (to restore the prior state) happens in the destructor. The DataPlant.unit.cc file has an example of setup/teardown. Note that TEST_F
is then used for the tests instead of TEST
.
Some strategies for growing the unit testing coverage of EnergyPlus:
- Tackle the easy code first:
- Code with fewer dependencies, esp. on global data
- Simple functions with clearly defined inputs, outputs, and actions
- Add unit tests for any new classes and functions
- Most EnergyPlus classes are just containers at this point so there isn't much to test but as functions are brought into the classes tests should be added
- For code that is too hard to unit test currently at least use assertions to verify pre and post conditions
- As you work on code think about refactoring it to make it unit test friendly