Manual——Test (翻译1)

时间:2021-07-25 07:03:03

LTE Manual ——Logging(翻译)

(本文为个人学习笔记,如有不当的地方,欢迎指正!)

1.17.3 Testing framework(测试框架)

 
ns-3 包含一个仿真核心引擎、一系列模块、例子程序和测试。随着时间的推移,一些新的贡献者贡献出模型、测试和例子。  Python 测试程序 test.py 作为测试执行管理者;test.py 运行测试代码和例子来寻找 regressions,输出结果有很多种形式,管理代码覆盖分析工具。 此外,我们对  buildslaves  进行分层,buildslaves  是自动化创建的 robots,通过在不同的系统中和使用不同的配置选项运行测试框架,buildslaves 能执行健壮性测试。
 
(1)Buildslaves
 
ns-3 测试的*别是 buildslaves (build robots)。如果你不熟悉该系统,可以参考 https://ns-buildmaster.ee.washington.edu:8010/——jenkins 是一个开源的自动化系统,允许 ns-3 日常重建和测试。 通过在很多不同系统上运行 buildbots(一种自动化构建工具),我们可以确保 ns-3 在它支持的所有系统上正确地构建和执行。
 
用户(和开发者)通常不会与 buildslave 系统打交道,除了读取它的关于测试结果的消息。如果在一个自动化构建和测试的工作中检测到 FAIL, buildbot 会发送邮件给 ns-commitsmailing 列表。该邮件看起来类似于:
 
In the full details URL shown in the email, one can find links to the detailed test output。(在邮件显示的详细 URL 信息中,用户可以找到详细测试输出的链接。)
 
如果没有错误的话,buildslave 系统会默默执行它的工作,并且系统每天会进行构建和测试循环来验证一切是否 ok。
 
(2)Test.py
buildbots 使用 Python 程序, test.py——负责运行所有的测试,并收集结果报告为可读的形式。该程序也可以供用户和开发人员使用。
 
test.py 在允许用户指定运行的测试数目和种类方面非常灵活,同时生成输出的数量和类型。
 
在运行 test.py  前 ,确保已经编译了 ns3 的例子和测试:
 
$ ./waf configure --enable-examples --enable-tests
$ ./waf build
 
默认情况下, test.py 将运行所有可用的测试,并以一种非常简明的形式报告状态。运行命令:
 
$ ./test.py
上述代码会导致一系列的 PASS、 FAIL、 CRASH 或 SKIP 指示,紧随其后的是测试种类和显示名称。
 
Waf: Entering directory '/home/craigdo/repos/ns--allinone-test/ns--dev/build'
Waf: Leaving directory '/home/craigdo/repos/ns--allinone-test/ns--dev/build'
'build' finished successfully (.939s)
FAIL: TestSuite propagation-loss-model
PASS: TestSuite object-name-service
PASS: TestSuite pcap-file-object
PASS: TestSuite ns3-tcp-cwnd
...
PASS: TestSuite ns3-tcp-interoperability
PASS: Example csma-broadcast
PASS: Example csma-multicast
这种方式由用户和开发者使用,用户感兴趣的是确定其分布是否正常工作,开发者感兴趣的是确定它们做出的改变是否造成了 regression。 
 
有很多种可用的选项来控制 test.py  的行为。如果你运行  test.py --help ,你会看到如下结果:
 
Usage: test.py [options]

Options:
-h, --help show this help message and exit
-b BUILDPATH, --buildpath=BUILDPATH
specify the path where ns- was built (defaults to the
build directory for the current variant)
-c KIND, --constrain=KIND
constrain the test-runner by kind of test
-e EXAMPLE, --example=EXAMPLE
specify a single example to run (no relative path is
needed)
-d, --duration print the duration of each test suite and example
-e EXAMPLE, --example=EXAMPLE
specify a single example to run (no relative path is
needed)
-u, --update-data If examples use reference data files, get them to re-
generate them
-f FULLNESS, --fullness=FULLNESS
choose the duration of tests to run: QUICK, EXTENSIVE,
or TAKES_FOREVER, where EXTENSIVE includes QUICK and
TAKES_FOREVER includes QUICK and EXTENSIVE (only QUICK
tests are run by default)
-g, --grind run the test suites and examples using valgrind
-k, --kinds print the kinds of tests available
-l, --list print the list of known tests
-m, --multiple report multiple failures from test suites and test
cases
-n, --nowaf do not run waf before starting testing
-p PYEXAMPLE, --pyexample=PYEXAMPLE
specify a single python example to run (with relative
path)
-r, --retain retain all temporary files (which are normally
deleted)
-s TEST-SUITE, --suite=TEST-SUITE
specify a single test suite to run
-t TEXT-FILE, --text=TEXT-FILE
write detailed test results into TEXT-FILE.txt
-v, --verbose print progress and informational messages
-w HTML-FILE, --web=HTML-FILE, --html=HTML-FILE
write detailed test results into HTML-FILE.html
-x XML-FILE, --xml=XML-FILE
write detailed test results into XML-FILE.xml

如果指定可选的输出方式,可以生成详细的测试和状态描述。可选的样式有 text 和 HTML 。buildbots 选择 HTML 方式生成 HTML 测试报告用于 nightly builds :

$ ./test.py --html=nightly.html
 
这种情况下,测试完成时会创建一个 名为‘’nightly.html’’ 的 HTML 文件,对细节感兴趣的用户可以选择以下一种可读的格式: 
 
$ ./test.py --text=results.txt 
 
在上述例子中,test suite 检测到 ns-3 无线设备传播损耗模型 FAIL。默认不会提供进一步的信息。
 
为了进一步探寻 FAIL, test.py 允许指定单个 test suite 。运行下列命令。
 
$ ./test.py --suite=propagation-loss-model

或者等价于

$ ./test.py -s propagation-loss-model

结果是单个 test suite 正在运行。


FAIL: TestSuite propagation-loss-model

为了找到有关失败的详细信息,我们必须指定期望输出的类型。例如,大多数人可能对文本文件感兴趣:
 
$ ./test.py --suite=propagation-loss-model --text=results.txt
 
这会导致运行单个test suite ,并且测试状态会写入到文件 “results.txt”。
 
你会发现一些类似下面的输出:
 
FAIL: Test Suite ''propagation-loss-model'' (real 0.02 user 0.01 system 0.00)
PASS: Test Case "Check ... Friis ... model ..." (real 0.01 user 0.00 system 0.00)
FAIL: Test Case "Check ... Log Distance ... model" (real 0.01 user 0.01 system 0.00)
Details:
Message: Got unexpected SNR value
Condition: [long description of what actually failed]
Actual: 176.395
Limit: 176.407 +- 0.0005
File: ../src/test/ns3wifi/propagation-loss-models-test-suite.cc
Line:
 
注意 Test Suite 由两个 Test Cases 组成。第一个 test case 检查 Friis 传播损耗模型并通过。第二个 test case 检查 Log Distance propagation model 失败。这种情况下, 发现 SNR 为 176.395 ,测试期望的值为 176.407,到小数点后三位。实现测试失败的文件和触发失败的代码会被列举出来。
 
如果你需要,你可以参照上述使用 --html  写一个HTML文件。
 
通常情况下,用户在下载完 ns-3 后,会至少运行一次所有的测试来确保仿真环境正确编译,并且会根据 test suites 产生正确的结果。开发者通常会在修改之前和之后确保没有因为改动而带来 regression 。这种情况下,开发者可能不想运行所有的测试,而只想运行一部分。 例如,开发者在修改 repository 的同时可能只想周期性运行 unit tests 。这种情况下, test.py 可以告知约束测试(运行一个特定的类的测试)类型。下面命令的作用是只有 unit tests 运行:
 

$ ./test.py --constrain=unit

相似地,下列命令会导致只有 example smoke tests 运行:

$ ./test.py --constrain=unit

为了快速看到合法的约束列表,你可以要求它们列举出来。下使用列代码:

$ ./test.py --kinds
 
会导致以下列表列举出来:
 
Waf: Entering directory '/home/craigdo/repos/ns-3-allinone-test/ns-3-dev/build'
Waf: Leaving directory '/home/craigdo/repos/ns-3-allinone-test/ns-3-dev/build'
'build' finished successfully (.939s)Waf: Entering directory '/home/craigdo/repos/ns-3-allinone-test/ns-3-dev/build'
bvt: Build Verification Tests (to see if build completed successfully)
core: Run all TestSuite-based tests (exclude examples)
example: Examples (to see if example programs run successfully)
performance: Performance Tests (check to see if the system is as fast as expected)
system: System Tests (spans modules to check integration of modules)
unit: Unit Tests (within modules to check basic functionality)
 
任何这些类型的测试都可以使用 --constraint  选项提供约束。
 
为了快速看到所有可用的 test suites ,你可以请求它们列举出来。下面代码
 
$ ./test.py --list
 
会导致 test suite 列表显示出来,相似地,
 
Waf: Entering directory `/home/craigdo/repos/ns--allinone-test/ns--dev/build'
Waf: Leaving directory `/home/craigdo/repos/ns--allinone-test/ns--dev/build'
'build' finished successfully (.939s) Test Type Test Name
--------- ---------
performance many-uniform-random-variables-one-get-value-call
performance one-uniform-random-variable-many-get-value-calls
performance type-id-perf
system buildings-pathloss-test
system buildings-shadowing-test
system devices-mesh-dot11s-regression
system devices-mesh-flame-regression
system epc-gtpu
...
unit wimax-phy-layer
unit wimax-service-flow
unit wimax-ss-mac-layer
unit wimax-tlv
example adhoc-aloha-ideal-phy
example adhoc-aloha-ideal-phy-matrix-propagation-loss-model
example adhoc-aloha-ideal-phy-with-microwave-oven
example aodv
...
 
任何这些列举的 suites 都可以使用  --suite  选项来选择性运行,如前所述,Examples 的处理方式不同。 
 
与 test suites 相似, 可以使用 --example 选项单独运行 C++ example 。 注意, 并不需要包含example 的相对路径, C++ examples 的可执行文件编译并没有扩展。此外, example 必须注册为测试框架的 example ; 只创建一个example 并通过 test.py 来运行是不够的;它必须被添加到相对 examples-to-run.py 文件,下面将解释。在命令行敲入
 
$ ./test.py --example=udp-echo
 
会导致单个 example 运行。
 
PASS: Example examples/udp/udp-echo
 
你可以指定路径,其中 ns-3 通过使用 --buildpath 选项编译。
 

$ ./test.py --buildpath=/home/craigdo/repos/ns--allinone-test/ns--dev/build/debug --example=wifi-simple-adhoc

 
你可以使用  --pyexample 选项来运行一个 Python example 程序。 注意必须添加 example的相对路径, Python examples 确实需要扩展。 键入
 
 
$ ./test.py --pyexample=examples/tutorial/first.py

会导致单个 example 运行,

PASS: Example examples/tutorial/first.py
 
因为 Python examples 没有编译,你并不需要指定 ns-3 编译运行它们的路径。
 
通常情况下,当example 程序执行时,它们会写入大量的 trace 文件数据。 它们通常会保存到分配的根路径(例如, /home/user/ns-3-dev)。当 test.py 运行一个example 时,它通常是完全不关心 trace 文件。它只想要确定 example 是否可以编译且运行没有错误。既然如此, trace 文件会被写进一个 /tmp/unchecked-traces 路径。如果你运行上述 example,你应该能够找到相关的 udp-echo.tr 和 udp-echo-n-1.pcap 文件。
 
可用的 examples 列表由分配的 ‘’examples’’ 路径的内容定义。如果你使用 --example 选项选择一个 example 执行, test.py 将不会做任何尝试来判断 example 是否已经配置,它只是尝试运行它并上报尝试的结果。
 
当 test.py 运行时,默认情况下,它会首先确认系统是否已经完全编译。这可以通过选择  --nowaf 选项来打破。
 
$ ./test.py --list --nowaf

将会导致显示当前已经编译的 test suites ,类似于:


propagation-loss-model
ns3-tcp-cwnd
ns3-tcp-interoperability
pcap-file
object-name-service
random-variable-stream-generators

注意没有 Waf 编译消息。
 
test.py 也支持在 valgrind 条件下运行 test suites 和 examples 。Valgrind 是一种灵活的调试和分析 Linux 可执行文件的程序。 默认情况下, valgrind 运行一种叫 memcheck 的工具,它执行一系列的 memory- checking 功能,包括检测访问 uninitialised 内存,分配内存 (double frees, access after free, etc.)的滥用 和检测内存泄漏等。这可以通过使用 --grind 选项来选择。
 
$ ./test.py --grind
 
当它运行时,test.py 和它间接运行的程序,会生成大量的临时文件。通常情况下,这些文件的内容并不有趣,然而,在某些情况下也很有用(用于调试目的),可以查看这些文件。test.py 会提供一个 --retain 选项,用于在运行结束后保存这些临时文件。文件保存在一个路径名为 testpy-output 下的子目录,根据当前世界统一时间(Coordinated Universal Time ,也称格林威治时间)命名。
 
$ ./test.py --retain
 
最后, test.py 会提供一个 --verbose 选项,会打印大量的过程信息。除非存在错误,否则并不期望它会非常有用。 这种情况下,你可以通过运行 test suites 和 examples 来获得上报的标准输出和标准错误。按照下列方式选择 verbose:
 
$ ./test.py --verbose
 
所有这些选项都可以混合搭配。例如,在 valgrind  条件下运行所有的 ns-3 核心 test suites ,按照 verbose 方式,与此同时生成一个 HTML 输出文件,可以按照如下方式执行:
 
$ ./test.py --verbose --grind --constrain=core --html=results.html
(3)TestTaxonomy
正如前面所述,测试被分组为广义的分类来允许用户选择性地运行测试,处理不同种类的测试。
 
  • Build Verification Tests
  • Unit Tests
  • System Tests
  • Examples
  • Performance Tests
 
并且,每种测试又进一步根据期望运行的时间划分。测试分类为:
  • QUICK
  • EXTENSIVE
  • TAKES_FOREVER
 
注意指定的 EXTENSIVE fullness 也会按照 QUICK 类别来运行测试。指定 TAKES_FOREVER 将按照 EXTENSIVE 和 QUICK 类别来运行例子。默认情况下,只运行 QUICK 测试。
 
作为经验法则,运行测试必须确保 ns-3 一致性为 QUICK (例如,花几秒时间)。EXTENSIVE是可以跳过但是很好做的测试 ;通常测试需要几分钟。TAKES_FOREVER 花的测试时间较长,顺序为几分钟。 分类的主要目标是能够在合理的时间内运行 buildbots i,并且当需要时能够执行更多的 extensive 测试。
 
(3a)BuildVerificationTests(BVT)
 
这些为相对简单的测试,以分布式的方式建立,用于确保 build 起相当大的作用。我们当前的测试单元在它们测试的代码的源文件中,并且构建在 ns-3 模块中;因此适合 BVTs 的描述。BVTs 位于相同的源码(构建在 ns-3代码中)中。我们当前的测试例子就属于这种测试。
 
(3b)Unit Tests(单元测试)
 
Unit tests 是更加复杂的测试—— go into detail to make sure that a piece of code works as advertised in isolation。 这种测试编译进一个ns-3 模块真的是没有什么理由。例如,事实证明,用于对象名服务的 unit tests 的大小与对象名服务代码本身相同。 Unit tests 负责检查还没有编译进 ns-3  代码的单一功能, 但是路径和测试代码的路径相同。这些测试可以检查一个模块中多个实现文件的整合。文件 src/core/test/names-test-suite.cc 是这种测试的一个例子。 文件 src/network/test/pcap-file-test-suite.cc 是另一个使用已知且好的 pcap 文件作为测试向量文件的例子,该文件存储在本地 src/network 路径下。
 
(3c)System Tests(系统测试)
 
系统测试的定义为在系统中涉及不止一个模块的测试。在我们当前的回归框架中,有很多这种测试在运行,但它们通常是超载的例子。我们提供了一个新的地方放置这种测试,路径为 src/test。文件 src/test/ns3tcp/ns3-interop-test-suite.cc 是这种测试的一个例子。它使用 NSC TCP 来测试 ns-3 TCP 实现。 这种测试需要的测试向量通常会有,并且它们存储在测试所在的路径下。例如, ns3tcp-interop-response-vectors.pcap 是一个由很多 TCP 头部组成的文件,TCP 头部用作测试下对 NSC TCP(用作一个“known good ”实现) 产生的刺激的预期 ns-3 TCP 响应。
 

(3d)Examples

 
examples 由框架测试来确保它们编译了并将运行。 没有检查,且当前的 pcap 文件只是写入到 /tmp 被丢弃。如果 examples 运行(没有crash ) ,它们会通过该 smoke test 。
 
(3e)Performance Tests
 
Performance tests 是训练系统特定部分和确定测试是否在合理时间内完成的测试。
(4)Running Tests(运行测试)
 
测试通常使用高级 test.py 程序来运行。为了获得一系列可用的命令行选项,运行 test.py --help。
 
测试程序 test.py 将同时运行 tests 和那些添加到列表中检查的 examples 。测试和例子的差别如下。Tests 通常会检查特定的仿真输出或事件是否符合期望的行为。相反,examples 的输出不用检查,并且 test 程序只检查 example 程序的退出状态来确保它是否运行出错。
 
简单地说,为了运行所有的 tests,首先必须在配置阶段配置测试和(可选的)examples(如果要需要检查 examples )。
 
$ ./waf --configure --enable-examples --enable-tests
 
然后,编译 ns-3 ,在编译完成后,运行 test.py   。 test.py -h 会显示一系列修改 test.py 的行为的配置选项。
 
对于 C++ tests 和 examples ,程序 test.py 产生一种较低级的 C++ 程序来实际运行测试,称为 test-runner  。正如下面讨论的,该 test-runner 是调试测试的有用方法。
 
(5)Debugging Tests
 
测试程序的测试最好是运行在低级的 test-runner 程序中。 test-runner 是一座从一般代码过渡到 ns-3 代码的桥梁。它是由 C++ 编写,在 ns-3 代码中使用自动测试过程发现和允许执行所有版本的测试。
 
test.py 不适合调试的主要原因是,当运行 test.py 时,不允许使用 NS_LOG 环境变量开启日志功能。 该限制并不适用于 test-runner 可执行文件。因此,如果你想看到你的测试有日志输出,你必须直接使用 test-runner 。
 
为了执行 test-runner,你可以像执行其他 ns-3 可执行文件一样执行它——使用  waf 。 获取可用选项的列表,键入:
 
$ ./waf --run "test-runner --help"

你会看到类似下面的输出:


Usage: /home/craigdo/repos/ns--allinone-test/ns--dev/build/utils/ns3-dev-test-runner-debug [OPTIONS]

Options:
--help : print these options
--print-test-name-list : print the list of names of tests available
--list : an alias for --print-test-name-list
--print-test-types : print the type of tests along with their names
--print-test-type-list : print the list of types of tests available
--print-temp-dir : print name of temporary directory before running
the tests
--test-type=TYPE : process only tests of type TYPE
--test-name=NAME : process only test whose name matches NAME
--suite=NAME : an alias (here for compatibility reasons only)
for --test-name=NAME
--assert-on-failure : when a test fails, crash immediately (useful
when running under a debugger
--stop-on-failure : when a test fails, stop immediately
--fullness=FULLNESS : choose the duration of tests to run: QUICK,
EXTENSIVE, or TAKES_FOREVER, where EXTENSIVE
includes QUICK and TAKES_FOREVER includes
QUICK and EXTENSIVE (only QUICK tests are
run by default)
--verbose : print details of test execution
--xml : format test run output as xml
--tempdir=DIR : set temp dir for tests to store output files
--datadir=DIR : set data dir for tests to read reference files
--out=FILE : send test result to FILE instead of standard output
--append=FILE : append test result to FILE instead of standard output

如果你有看过 test.py  ,你会发现很多你熟悉的可用东西。这应该是在预料之中, 因为 test- runner 是 test.py 和 ns-3 之间的一个接口。 你可能注意到这里没有 example-related 命令。 这是因为 examples 真的不是 ns-3 测试。 test.py 运行它们仿佛它们呈现了一个统一的测试环境,但实际上它们真的完全不同,且在这里找不到。
 
出现在这里的第一个新选项但 test.py 中没有的是 --assert-on-failure 选项。当在调试器中,比如 gdb ,运行调试一个 test case 时,该选项是有用的。当选定该选项时,如果检测到一个错误,该选项会告诉潜在的 test case 引起了内存段异常。 它有好的副作用,当检测到一个错误时,它会造成程序执行停止(break into the debugger) 。如果你使用 gdb , 你可以使用该选项类似于
 

$ ./waf shell
$ cd build/utils
$ gdb ns3-dev-test-runner-debug
$ run --suite=global-value --assert-on-failure

 
如果在 global-value test suite 中发现一个错误,会产生一个segfault(段错误),并且在检测到错误时,(source level) 调试器会停止在 NS_TEST_ASSERT_MSG 。
 
为了直接使用 waf 从  test-runner 运行测试,你需要指定 test suite运行。因此,你可以使用 shell 然后执行:
 
$ ./waf --run "test-runner --suite=pcap-file"
 
当你按照下列方式运行时,ns-3 logging 是可用的,例如:(这一命令非常实用!)
 
$ NS_LOG="Packet" ./waf -- run "test-runner -- suite=pcap-file"

例如,对 “lte-test-rr-ff-mac-scheduler.cc”  添加日志功能,可以获取相关的吞吐量信息,使用类似上述的命令:

$ NS_LOG="LenaTestRrFfMacScheduler" ./waf --run "test-runner --suite=lte-rr-ff-mac-scheduler" >& log5.out

可以在 log5.out 中查看有用的日志信息,部分截图如下:

Manual——Test (翻译1)

(5a)Test output(测试输出)

很多 test suites 在运行测试的过程中需要写临时文件(例如 pcap 文件)。然后测试需要一个临时目录来写。Python 测试工具(test.py) 会自动提供一个临时文件,但是如果单独运行,必须提供该临时文件 。如果持续性提供一个--tempdir ,这可能有点令人厌烦,因此如果你自己不提供一个,test runner 将为你提供一个。它首先寻找名为 TMP 和 TEMP 和的环境变量,然后使用它们。如果 TMP 和 TEMP 都没有定义,它会选择 /tmp 。 代码然后添加到一个标识符上,表示所在的目录(ns-3),然后紧随时间(hh.mm.ss)后面的是一个大的随机数。test runner 会创建一个目录,其名称会用作临时路径。 临时文件然后进入到一个路径,路径命名类似于:
 
/tmp/ns-3.10.25.37.
 
如果你需要回头看看放置在该路径的文件时,时间是一个提示,这样你可以相对容易重建使用过的路径。
 
另一类输出是测试输出,类似生成 pcap traces ,用于比较参考输出。在 test suites 全都运行完成后,测试程序通常会删掉这些。为了禁止删除测试输出,可以使用 “retain” 选项来运行 test.py :
 
$ ./test.py -r
 
然后测试输出可以在路径 testpy-output/ 下找到。
 

(5b)Reporting of test failures(上报测试失败)

 
当你使用 test-runner 运行 test suite 时,它会运行测试并上报 PASS 或 FAIL。 为了更安静地运行程序,你需要指定一个输出文件——测试会使用 --out 选项写进它们的状态。尝试输入下列代码:
 
$ ./waf --run "test-runner --suite=pcap-file --out=myfile.txt"

(5c)Debugging test suite failures

 
为了调试测试 crashes,例如
 
CRASH: TestSuite ns3-wifi-interference
 
你可以通过如下的 gdb 接入潜在的 test-runner 程序,然后 传递 “–basedir='pwd'” 参数运行(需要的话你也可以传递其他的参数,但是最低要求为属性一样):

$ ./waf --command-template="gdb %s" --run "test-runner"
Waf: Entering directory `/home/tomh/hg/sep09/ns--allinone/ns--dev-/build'Waf: Leaving directory `/home/tomh/hg/sep09/ns-3-allinone/ns-3-dev-678/build''build' finished successfully (.380s)
GNU gdb 6.8-debian
Copyright (C) Free Software Foundation, Inc.
L cense GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu"...
(gdb) r --suite=
Starting program: <..>/build/utils/ns3-dev-test-runner-debug --suite=ns3-wifi-interference
[Thread debugging using libthread_db enabled]
assert failed. file=../src/core/model/type-id.cc, line=, cond="uid <= m_information.size () && uid != 0"
...

这里还有另外一个例子教你如何使用 valgrind 调试内存问题,例如:


VALGR: TestSuite devices-mesh-dot11s-regression

$ ./waf --command-template="valgrind %s --suite=devices-mesh-dot11s-regression" --run test-runner

(5)Class TestRunner
 
运行专用测试程序的可执行文件需要使用类 TestRunner 。该类会提供自动的测试注册和清单,以及执行单个测试的方法。单独的 test suites 使用 C++ 全局构造函数添加它们自身到由 test runner 管理的 test  suites 集合中 。  test runner 用于列举所有可用的测试和选择要运行的测试。TestRunner是一个非常简单的类,提供3种静态方法,用于提供、添加或获得 test suites 到测试集合中。 查看 doxygen了解更多关于类 ns3::TestRunner 的信息。
 
(6)Test Suite
 
所有的 ns-3 测试分为Test Suites 和 Test Cases。一个 test suite 是 test cases 的集合,完全使用一种给定的功能。正如前面所述, test suites 分类为,
  • Build Verification Tests
  • Unit Tests
  • System Tests
  • Examples
  • Performance Tests
 
 classification 是从 TestSuite 类中导出的。该类十分简单, 现有的只有一个地方输出其类型和积累 test cases。从用户的的角度来说,为了在系统中创建一个新的 TestSuite ,用户只需定义一个新的类(继承类 TestSuite)并执行这两个任务。
 
下面代码将定义一个新的类,可以通过 test.py 作为“单元”测试进行运行,显示名称为 my-test-suite-name
 
class MySuite : public TestSuite
{
public:
MyTestSuite ();
}; MyTestSuite::MyTestSuite ()
: TestSuite ("my-test-suite-name", UNIT)
{
AddTestCase (new MyTestCase, TestCase::QUICK);
}
static MyTestSuite myTestSuite;
基类负责测试框架中要求的所有登记和报告。
 
避免将初始化逻辑放入到 test suite 或 test case 的构造函数中。原因是 test suite 的实例被创建在运行时间(由于上述静态变量),不管测试是否运行。相反,TestCase 提供一个虚的 DoSetup方法,可以在 DoRun 被调用前专门执行 setup 。
 
(7)Test Case
使用 TestCase 类可以创建单独的测试。 使用 test case 的一般模型包括  “one test case per feature”, 和 “one test case per method” 。也可以将这些模型混合起来使用。
 
为了在系统中创建一个新的 test case,必须要继承 TestCase 基类,重写(override)构造函数为 test case 指定一个名称,重写 DoRun 方法以运行测试。可选的,也可以重写 DoSetup 方法。
 
class MyTestCase : public TestCase{
MyTestCase ();
virtual void DoSetup (void);
virtual void DoRun (void);}; MyTestCase::MyTestCase ()
: TestCase ("Check some bit of functionality"){} voidMyTestCase::DoRun (void){
NS_TEST_ASSERT_MSG_EQ (true, true, "Some failure message");}
(8)Utilities(实用工具)
 
多种实用工具也是测试框架的一部分。Examples 中包含用于存储测试向量的一般性 pcap 文件; 在测试执行期间用于临时存储测试向量的通用容器;基于 validation 和 verification 测试结果生成报告的工具。
 
这里就不介绍这些实用工具了,但是可以看看,例如,src/test/ns3tcp/ 中的 TCP 测试是如何使用 pcap 文件和参考输出的。