|
|
| Line 111: |
Line 111: |
| === Structure of a CPPUnit test === | | === Structure of a CPPUnit test === |
|
| |
|
| You're going to create a new test, by
| | ==== Definitions ==== |
| * Naming a few things
| |
| * Creating a class in .cxx and .hxx files. In the .hxx file the format is class TestObjective {};
| |
| * Include some CPPUNIT boilerplate code, common to all the tests
| |
| * Modifying CMakeLists.txt files to ensure your new class is built
| |
| * Adding a registration entry for your new class in the chosen directory's TestSuite.cxx file.
| |
|
| |
|
| These are the test group directories
| | =====Test Case===== - A single assertion about one or two variable values that is testable. |
| | =====Test Fixture===== - In CppUnit, a group of tests is called a TestFixture. A TestFixture provides a common environment for multiple test cases. |
| | =====App Component Category=====- Major parts of the application, usually corresponding to folders in flightgear/src or simgear/simgear |
| | =====Test Category===== - The type of testing: unit, system and simgear (library) tests |
| | =====Test Suite=====- All the tests. |
|
| |
|
| * flightgear/test_suite/fgdata_tests
| |
| * flightgear/test_suite/gui_tests
| |
| * flightgear/test_suite/simgear_tests
| |
| * flightgear/test_suite/system_tests
| |
| * flightgear/test_suite/unit_tests
| |
|
| |
|
| Under each of these directories, are topic directory
| |
| For example, under flightgear/test_suite/unit_tests, you'll find directory names (topics) that roughly correspond to the directories under flightgear/src.
| |
|
| |
|
| └── unit_tests
| | Take a look at the '''flightgear/test_suite''' folder in a file browser preferably one that allows you to see the folders on multiple levels such as a code editor like VsCode. Start in the top level of flightgear's repo sources look for a directory named '''test_suite'''. Note that test_suite is not part of '''flightgear/src'''. |
| ├── Add-ons
| |
| ├── AI
| |
| ├── Airports
| |
| ├── Autopilot
| |
| ├── CMakeLists.txt
| |
| ├── FDM
| |
| ├── general
| |
| ├── Input
| |
| ├── Instrumentation
| |
| ├── Main
| |
| ├── Navaids
| |
| ├── Network
| |
| └── Scripting
| |
| For this example we'll look at the steps taken to add the httpd tests under test_suite/Network.
| |
|
| |
|
| Steps:
| | ====flightgear/test_suite folder==== |
| * Choose where you are placing your tests. Choose a group and topic within the group. in our case it was test_suite/unit_tests/Network. Unit tests is the group and Network is the Topic
| |
| * Name what you are testing in general, I was testing httpd.cxx/hxx format for the class name: HttpdTests
| |
| * Name the specific things covered. If only one, use the general wording,but in the format: testHttpd
| |
| * place the following boilerplate a file named test_httpd.hxx
| |
|
| |
|
| syntaxhighlight lang="C++" line start="" highlight="" inline>
| | '''flightgear/test_suite''' contains two kinds of testing resources. |
| /*
| |
| * SPDX-FileCopyrightText: (C) '''2024 Patrick Callahan <pat.callahan5@gmail.com>'''
| |
| * SPDX-License-Identifier: GPL-2.0-or-later
| |
| */
| |
|
| |
|
| #pragma once
| | * Programs and data used in tests |
| | * Groups of CPPUnit tests |
|
| |
|
| #include <cppunit/TestFixture.h>
| | =====Programs and data used in test modules===== |
| #include <cppunit/extensions/HelperMacros.h>
| |
| #define private public
| |
| class '''HttpdTest''' : public CppUnit::TestFixture
| |
| {
| |
| // Set up the test suite.
| |
| CPPUNIT_TEST_SUITE('''HttpdTest''');
| |
| CPPUNIT_TEST('''testHttpd''');
| |
| CPPUNIT_TEST_SUITE_END();
| |
|
| |
|
| public:
| | * individual files directly under test_suite |
| // Set up function for each test.
| | * test_data folder |
| void setUp();
| | * FGTestApi folder |
| | * Groups of CPPUnit tests |
|
| |
|
| // Clean up after each test.
| | =====Test Categories===== |
| void tearDown();
| |
|
| |
|
| // Test
| | * fgdata_tests - placeholder |
| void '''testHttpd'''();
| | * gui_tests - placeholder |
| };
| | * simgear_tests |
| | * system_tests |
| | * unit_tests |
|
| |
|
| | Each of the last three test_suite/*_tests folders contain sub-folders covering some part of Flightgear's code. They may roughly correspond to the folders under flightgear/src, but that is not a requirement. Some areas may be covered in more than one *_tests folder. FDM for example in unit_tests and system_tests. |
|
| |
|
| </syntaxhighlight>
| | ==== Folder Levels ==== |
|
| |
|
| | Note at this point that the maximum Folder depth is 3: |
|
| |
|
| * modify the SPDX-FileCopyrightText, changing the date, name and e-mail to your own.
| | # flightgear/test_suite Folder. |
| * modify the name of the class
| | # Test-category folders ex: unit_tests, system_tests, simgear_tests |
| * modify the name of the test function testHttpd
| | # App Component folders ex: FDM, Network, canvas. These roughly correspond to specific flightgear/src folders, |
|
| |
|
| * Add the following boilerplate to test_httpd.cxx
| | Expand the '''unit_tests''' test category folder |
| syntaxhighlight lang="C++" line start="" highlight="" inline>
| | Expand the '''Network''' app component folder |
| /*
| |
| * SPDX-FileCopyrightText: (C) '''2022 Lars Toenning <dev@ltoenning.de>'''
| |
| * SPDX-License-Identifier: GPL-2.0-or-later
| |
| */
| |
|
| |
|
| #include "test_httpd.hxx"
| | CPPUNIT test fixtures are implemented in test_*.cxx and test_*.hhx files int the Component category folders. |
|
| |
|
| #include "test_suite/FGTestApi/testGlobals.hxx"
| | ==== CMakeLists.txt, testSuite.cxx and TestSuite.cxx files ==== |
| #define private public
| |
| #include "Network/http/httpd.hxx"
| |
| #include <Main/fg_props.hxx>
| |
|
| |
|
| void HttpdTest::setUp()
| | CMakeLists.txt files exist at every level |
| {
| | TestSuite.cxx files are in each application component folders (bottom level) |
| FGTestApi::setUp::initTestGlobals("httpd");
| | testSuite.cxx is only at the top level |
|
| |
|
| | # '''test_suite/CMakeLists.txt''' & test_suite/testSuite.cxx |
| | # '''test_suite/[test-category]/CMakeLists.txt''' |
| | # '''test_suite/[test-category]/[app-component]/CMakeLists.txt''' and '''Test_suite.cxx''' |
|
| |
|
| // Setup properties
| |
| fgSetBool("/sim/freeze/master", true);
| |
| fgSetDouble("/position/latitude-deg", 50.12);
| |
| fgSetDouble("/position/longitude-deg", 6.3);
| |
| fgSetDouble("/position/altitude-ft", 12000.0);
| |
| fgSetDouble("/position/altitude-agl-ft", 1020.0);
| |
| fgSetDouble("/velocities/groundspeed-kt", 242.0);
| |
| fgSetDouble("/orientation/pitch-deg", 3.0);
| |
| fgSetDouble("/orientation/roll-deg", 1.0);
| |
| fgSetDouble("/orientation/heading-deg", 230.0);
| |
| fgSetBool("/gear/gear/wow", false);
| |
| fgSetDouble("/instrumentation/comm/frequencies/selected-mhz", 122.8);
| |
| fgSetDouble("/instrumentation/comm/frequencies/standby-mhz", 135.65);
| |
| fgSetDouble("/instrumentation/comm[1]/frequencies/selected-mhz", 121.5);
| |
| fgSetDouble("/instrumentation/comm[1]/frequencies/standby-mhz", 118.3);
| |
| fgSetInt("/instrumentation/transponder/id-code", 1234);
| |
| fgSetInt("/instrumentation/transponder/inputs/knob-mode", 1);
| |
| fgSetBool("/instrumentation/transponder/ident", true);
| |
| fgSetBool("/controls/lighting/beacon", true);
| |
| fgSetBool("/controls/lighting/landing-lights", false);
| |
| fgSetBool("/controls/lighting/nav-lights", true);
| |
| fgSetBool("/controls/lighting/strobe", true);
| |
| fgSetBool("/controls/lighting/taxi-light", false);
| |
| fgSetBool("/instrumentation/altimeter/serviceable", true);
| |
| fgSetDouble("/instrumentation/altimeter/pressure-alt-ft", 24000.0);
| |
| fgSetDouble("/surface-positions/flap-pos-norm", 0.0);
| |
| fgSetDouble("/gear/gear/position-norm", 0.7);
| |
| fgSetDouble("/surface-positions/speedbrake-pos-norm", 0.4);
| |
| fgSetString("/sim/aircraft", "glider");
| |
| fgSetDouble("/position/ground-elev-m", 778.0);
| |
| fgSetDouble("/velocities/speed-east-fps", 20.0);
| |
| fgSetDouble("/velocities/speed-down-fps", -30.0);
| |
| fgSetDouble("/velocities/speed-north-fps", -10.2);
| |
| fgSetDouble("/orientation/roll-rate-degps", 1.0);
| |
| fgSetDouble("/orientation/pitch-rate-degps", 0.0);
| |
| fgSetDouble("/orientation/yaw-rate-degps", -2.0);
| |
| fgSetDouble("/instrumentation/comm/volume", 42.0);
| |
| fgSetDouble("/instrumentation/comm[1]/volume", 100.0);
| |
| fgSetString("/sim/http/options/document-root", "Phi");
| |
| fgSetString("/sim/http/options/enable-directory-listing", "yes");
| |
| fgSetString("/sim/http/options/extra-mime-types", ".appcache=text/cache-manifest");
| |
| fgSetString("/sim/http/options/idle-timeout-ms", "30000");
| |
| fgSetString("/sim/http/options/index-files", "index.html");
| |
| fgSetString("/sim/http/options/url-rewrites", "/fonts=Fonts/");
| |
| fgSetString("/sim/http/options/listening-port", "5321");
| |
| }
| |
|
| |
|
| void HttpdTest::tearDown()
| |
| {
| |
| FGTestApi::tearDown::shutdownTestGlobals();
| |
| }
| |
|
| |
|
| void HttpdTest::testHttpd()
| |
| {
| |
| SGPropertyNode* config_node = fgGetNode("/sim/http", true);
| |
| flightgear::http::MongooseHttpd * httpd = static_cast<flightgear::http::MongooseHttpd *>(flightgear::http::FGHttpd::createInstance(config_node));
| |
| httpd->init();
| |
| CPPUNIT_ASSERT_EQUAL(static_cast<string>("Phi"), httpd->docRoot);
| |
|
| |
| // ToDo: Implement a client that can go after properties, among other things.
| |
|
| |
| // // CPPUNIT_ASSERT(httpd.isPaused());
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getLatitude(), 50.12, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getLongitude(), 6.3, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getAltitudeMSL(), 12000.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getHeightAGL(), 1020.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGroundSpeed(), 242.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPitch(), 3.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getRoll(), 1.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getTrueHeading(), 230.0, 0.1);
| |
| // CPPUNIT_ASSERT(!httpd.getAllWheelsOnGround());
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Active(), 122800);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Standby(), 135650);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Active(), 121500);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Standby(), 118300);
| |
|
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderCode(), 1234);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderMode(), 1);
| |
| // CPPUNIT_ASSERT(httpd.getTransponderIdent());
| |
| // CPPUNIT_ASSERT(httpd.getBeaconLightsOn());
| |
| // CPPUNIT_ASSERT(!httpd.getLandingLightsOn());
| |
| // CPPUNIT_ASSERT(httpd.getNavLightsOn());
| |
| // CPPUNIT_ASSERT(httpd.getStrobeLightsOn());
| |
| // CPPUNIT_ASSERT(!httpd.getTaxiLightsOn());
| |
|
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getFlapsDeployRatio(), 0.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGearDeployRatio(), 0.7, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getSpeedBrakeRatio(), 0.4, 0.1);
| |
|
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getAircraftName(), std::string("glider"));
| |
|
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getGroundElevation(), 778.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityX(), 20.0 * SG_FEET_TO_METER, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityY(), -30.0 * SG_FEET_TO_METER * -1, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getVelocityZ(), -10.2 * SG_FEET_TO_METER, 0.1);
| |
|
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getRollRate(), 1.0 * SG_DEGREES_TO_RADIANS, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPitchRate(), 0.0 * SG_DEGREES_TO_RADIANS, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getYawRate(), -2.0 * SG_DEGREES_TO_RADIANS, 0.1);
| |
|
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getCom1Volume(), 42.0, 0.1);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getCom2Volume(), 100.0, 0.1);
| |
|
| |
|
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPressAlt(), 24000.0, 0.1);
| |
| // fgSetBool("/instrumentation/altimeter/serviceable", false);
| |
| // // Fallback if altimeter is not serviceable
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(httpd.getPressAlt(), httpd.getAltitudeMSL(), 0.1);
| |
|
| |
| // // Test setter
| |
| // httpd.setCom1Active(128550);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Active(), 128550);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble("/instrumentation/comm/frequencies/selected-mhz"), 128.550, 0.1);
| |
|
| |
| // httpd.setCom1Standby(128650);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom1Standby(), 128650);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble("/instrumentation/comm/frequencies/standby-mhz"), 128.650, 0.1);
| |
|
| |
|
| |
| // httpd.setCom2Active(121900);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Active(), 121900);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble("/instrumentation/comm[1]/frequencies/selected-mhz"), 121.900, 0.1);
| |
|
| |
| // httpd.setCom2Standby(121600);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getCom2Standby(), 121600);
| |
| // CPPUNIT_ASSERT_DOUBLES_EQUAL(fgGetDouble("/instrumentation/comm[1]/frequencies/standby-mhz"), 121.600, 0.1);
| |
|
| |
| // httpd.setTransponderCode(2000);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderCode(), 2000);
| |
| // CPPUNIT_ASSERT_EQUAL(fgGetInt("/instrumentation/transponder/id-code"), 2000);
| |
|
| |
|
| |
| // httpd.setTransponderMode(0);
| |
| // CPPUNIT_ASSERT_EQUAL(httpd.getTransponderMode(), 0);
| |
| // CPPUNIT_ASSERT_EQUAL(fgGetInt("/instrumentation/transponder/inputs/knob-mode"), 0);
| |
| }
| |
| </syntaxhighlight>
| |
| More to follow {{WIP}} | | More to follow {{WIP}} |
|
| |
|