class: center, middle, inverse, title-slide # Test fixtures: Reusing test data configuration between tests ### Bai Li
National Stock Assessment Program Modeling Team
Contractor with ECS in support of NOAA Fisheries
Office of Science and Technology
bai.li@noaa.gov
### Nov 17, 2022
FIMS C++ office hour
Updated on 2022-11-17 --- layout: true .footnote[U.S. Department of Commerce | National Oceanic and Atmospheric Administration | National Marine Fisheries Service] --- # Test fixture definition - An object the test runs against*<sup>1</sup>* - can be a regular dependency: an argument to be passed, data in the database, or a file on the hard disk - remain in a known and fixed state to produce the same results before executing tests - Help set up **custom initialization work** for multiple tests*<sup>2</sup>* - preconditions - data - cleanup procedures .footnote[ [1]Khorikov V. 2020. Unit testing: principles, practices, and patterns. Shelter Island, NY: Manning.<br> [2]GoogleTest Users' guide: [http://google.github.io/googletest/primer.html#same-data-multiple-tests](http://google.github.io/googletest/primer.html#same-data-multiple-tests) <br> ] --- **Use test fixture when you find you are repeating yourself** ```c++ TEST(PopulationModuleTest, CalculateMortality_works) { fims::Population<double> population; population.nyears = 30; population.nages = 12; int year = 2; int age = 7; int index_ya = year * population.nages + age; population.CalculateMortality(index_ya, year, age); EXPECT_EQ(population.mortality_F[index_ya], 3.5); } ``` ```c++ TEST(PopulationModuleTest, CalculateNumbersAA_works) { fims::Population<double> population; population.nyears = 30; population.nages = 12; int year = 4; int age = 6; int index_ya = year * population.nages + age; int index_ya2 = (year - 1) * population.nages + age - 1; population.CalculateNumbersAA(index_ya, index_ya2); EXPECT_EQ(population.numbers_at_age[index_ya], 1234); } ``` --- # Google Test template .pull-left[ - Simple test ```c++ TEST(TestSuiteName, TestName1){ ...test body... } TEST(TestSuiteName, TestName2){ ...test body... } ``` ] .pull-right[ - Fixture test ```c++ TEST_F(TestFixtureName, TestName1){ ...test body... } TEST_F(TestFixtureName, TestName2){ ...test body... } ``` ] --- # Steps to create a Google Test fixture class*<sup>1</sup>* - Derive a class from `::testing::Test` - Start its body with `protected:` - Declare any objects you plan to use inside the class - Write a default constructor or `SetUp()` function to prepare the objects - Write a destructor or `TearDown()` function to release any resources that are allocated in `SetUp()`. - Define subroutines for your tests to share ```c++ class TestFixtureName : public ::testing::Test{ protected: void SetUp() override{ ...SetUp body... } void TearDown() override { ...TearDown body... } ...Other subroutines... } ``` .footnote[ [1]GoogleTest Users' guide: [http://google.github.io/googletest/primer.html#same-data-multiple-tests](http://google.github.io/googletest/primer.html#same-data-multiple-tests) <br> ] --- # FIMS test fixture files (WIP) - [<u>FIMS/tests/gtest/test_population_test_fixture.hpp</u>](https://github.com/NOAA-FIMS/FIMS/blob/9469d42eeb6193a149762bcbdb462c3d5c45c148/tests/gtest/test_population_test_fixture.hpp) - [<u>FIMS/tests/gtest/test_population_dynamics_population_initialize_prepare.cpp</u>](https://github.com/NOAA-FIMS/FIMS/blob/9469d42eeb6193a149762bcbdb462c3d5c45c148/tests/gtest/test_population_dynamics_population_initialize_prepare.cpp) - [<u>FIMS/tests/gtest/test_population_NumbersAtAge.cpp</u>](https://github.com/NOAA-FIMS/FIMS/blob/9469d42eeb6193a149762bcbdb462c3d5c45c148/tests/gtest/test_population_NumbersAtAge.cpp) - [<u>FIMS/tests/gtest/test_population_Li.cpp</u>](https://github.com/NOAA-FIMS/FIMS/blob/9469d42eeb6193a149762bcbdb462c3d5c45c148/tests/gtest/test_population_Li.cpp) - [<u>FIMS/tests/gtest/test_population_MaturityAtAge.cpp</u>](https://github.com/NOAA-FIMS/FIMS/blob/9469d42eeb6193a149762bcbdb462c3d5c45c148/tests/gtest/test_population_MaturityAtAge.cpp) --- # FIMS test files diagram
--- # PopulationInitializeTestFixture - `PopulationInitializeTestFixture` derives from the fixture base class `::testing::Test` - Members of the test fixture class (e.g., population object, `id_g`, `nyears`, `nseasons`, `nages`, and `nfleets` will be set - Population `id_g`, `nyears`, `nseasons`, `nages`, `nfleets`, and `fleet` from the `SetUp()` will be called **before** all tests using the fixture - `TearDown()` will be called **after** all tests using the fixture are run --- # PopulationPrepareTestFixture - `population.Initialize()` and `population.Prepare()` functions will be called **before** all tests using the fixture - `population.log_naa`, `population.log_M`, `population.log_Fmort` pseudo-random numbers will be generated using `std::default_random_engine` class **before** all tests using the fixture - Make shared pointers to `selectivity`, `fleet`, and `maturity` to set up `population.fleets` and `population.maturity` --- # Thanks! bai.li@noaa.gov