// WSDG Chapter Setup [[ChapterTests]] == Wireshark Tests The Wireshark sources include a collection of Python scripts that test the features of Wireshark, TShark, Dumpcap, and other programs that accompany Wireshark. The command line options of Wireshark and its companion command line tools are numerous. These tests help to ensure that we don't introduce bugs as Wireshark grows and evolves. === Quick Start Before running any tests you should build the “test-programs” target. It is required for the “utittests” suite. The main testing script is `test.py`. It will attempt to test as much as possible by default, including packet capture. This means that you will probably either have to supply a capture interface (`--capture-interface `) or disable capture tests (`--disable-capture`). To run all tests from CMake do the following: * Pass `-DTEST_EXTRA_ARGS=--disable-capture` or `-DTEST_EXTRA_ARGS=--capture-interface=` as needed for your system. * Build the “test” target or run ctest, e.g. `ctest --force-new-ctest-process -j 4 --verbose`. On Windows, “ctest” requires a build configuration parameter, e.g. `ctest -C RelWithDebInfo --force-new-ctest-process -j 4 --verbose`. To run all tests directly, run `test.py -p /path/to/wireshark-build/run-directory `. To see a list of all options, run `test.py -h` or `test.py --help`. To see a list of all tests, run `test.py -l`. === Test Coverage And Availability The testing framework can run programs and check their stdout, stderr, and exit codes. It cannot interact with the Wireshark UI. Tests cover capture, command line options, decryption, file format support and conversion, Lua scripting, and other functionality. Available tests depend on the libraries with which Wireshark was built. For example, some decryption tests depend on a minimum version of Libgcrypt and Lua tests depend on Lua. Capture tests depend on the permissions of the user running the test script. We assume that the test user has capture permissions on Windows and macOS and capture tests are enabled by default on those platforms. === Suites, Cases, and Tests The `test.py` script uses Python's “unittest” module. Our tests are patterned after it, and individual tests are organized according to suites, cases, and individual tests. Suites correspond to python modules that match the pattern “suite_*.py”. Cases correspond to one or more classes in each module, and case class methods matching the pattern ”test_*” correspond to individual tests. For example, the invalid capture filter test in the TShark capture command line options test case in the command line options suite has the ID “suite_clopts.case_tshark_capture_clopts.test_tshark_invalid_capfilter”. === Listing And Running Tests Tests can be run via the `test.py` Python script. To run all tests, either run `test.py` in the directory that contains the Wireshark executables (`wireshark`, `tshark`, etc.), or pass the the executable path via the `-p` flag: [source,sh] ---- $ python test.py -p /path/to/wireshark-build/run ---- You can list tests by passing one or more complete or partial names to `tshark.py`. The `-l` flag lists tests. By default all tests are shown. [source,sh] ---- # List all tests $ python test.py -l $ python test.py -l all $ python test.py --list $ python test.py --list all # List only tests containing "dumpcap" $ python test.py -l dumpcap # List all suites $ python test.py --list-suites # List all suites and cases $ python test.py --list-cases ---- If one of the listing flags is not present, tests are run. If no names or `all` is supplied, all tests are run. Otherwise tests that match are run. [source,sh] ---- # Run all tests $ python test.py $ python test.py all # Only run tests containing "dumpcap" $ python test.py -l dumpcap # Run the "clopts" suite $ python test.py suite_clopts ---- === Adding Or Modifying Tests Tests must be in a Python module whose name matches “suite_*.py”. The module must contain one or more subclasses of “SubprocessTestCase” or “unittest.TestCase”. “SubprocessTestCase” is recommended since it contains several convenience methods for running processes, checking output, and displaying error information. Each test case method whose name starts with “test_” constitutes an individual test. Success or failure conditions can be signalled using the “unittest.assertXXX()” or “subprocesstest.assertXXX()” methods. The “config” module contains common configuration information which has been derived from the current environment or specified on the command line. The “subprocesstest” class contains the following methods for running processes. Stdout and stderr is written to “.log”: startProcess:: Start a process without waiting for it to finish. runProcess:: Start a process and wait for it to finish. assertRun:: Start a process, wait for it to finish, and check its exit code. All of the current tests run one or more of Wireshark's suite of executables and either checks their return code or their output. A simple example is “suite_clopts.case_basic_clopts.test_existing_file”, which reads a capture file using TShark and checks its exit code. [source,python] ---- import config import subprocesstest class case_basic_clopts(subprocesstest.SubprocessTestCase): def test_existing_file(self): cap_file = os.path.join(self.capture_dir, 'dhcp.pcap') self.assertRun((config.cmd_tshark, '-r', cap_file)) ---- Program output can be checked using “subprocesstest.grepOutput” or “subprocesstest.countOutput”: [source,python] ---- import config import subprocesstest class case_decrypt_80211(subprocesstest.SubprocessTestCase): def test_80211_wpa_psk(self): capture_file = os.path.join(config.capture_dir, 'wpa-Induction.pcap.gz') self.runProcess((config.cmd_tshark, '-o', 'wlan.enable_decryption: TRUE', '-Tfields', '-e', 'http.request.uri', '-r', capture_file, '-Y', 'http', ), env=config.test_env) self.assertTrue(self.grepOutput('favicon.ico')) ---- Tests can be run in parallel. This means that any files you create must be unique for each test. “subprocesstest.filename_from_id” can be used to generate a filename based on the current test name. It also ensures that the file will be automatically removed after the test has run.