Software testing: Difference between revisions

Jump to navigation Jump to search
m
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}}


982

edits

Navigation menu