Part 1
요약·해설
Twister의 local·CI 실행, board metadata와 testcase.yaml 전체 key, harness·filter grammar, timeout, custom emulator, 단일·다중 실기기와 hardware map, fixture·quarantine·test level·Robot Framework를 설명합니다.
board · scenario · filter
emulator · hardware · map
fixture · level · quarantine
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
E309215D176272B6FAFFD9D5486736CE8F26DE6CB0573F89F621FF80E2F15274
.. _twister_script:
Test Runner (Twister)
#####################
Twister scans for the set of test applications in the git repository
and attempts to execute them. By default, it tries to build each test
application on boards marked as default in the board definition file.
The default options will build the majority of the test applications on a
defined set of boards and will run in an emulated environment if available for
the architecture or configuration being tested.
Because of the limited test execution coverage, twister
cannot guarantee local changes will succeed in the full build
environment, but it does sufficient testing by building samples and
tests for different boards and different configurations to help keep the
complete code tree buildable.
When using (at least) one ``-v`` option, twister's console output
shows for every test application how the test is run (qemu, native_sim, etc.) or
whether the binary was just built. There are a few reasons why twister
only builds a test and doesn't run it:
- The test is marked as ``build_only: true`` in its ``.yaml``
configuration file.
- The test configuration has defined a ``harness`` but you don't have
it or haven't set it up.
- The target device is not connected and not available for flashing
- You or some higher level automation invoked twister with
``--build-only``.
To run the script in the local tree, follow the steps below:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
$ source zephyr-env.sh
$ ./scripts/twister
.. group-tab:: Windows
.. code-block:: bat
zephyr-env.cmd
python .\scripts\twister
If you have a system with a large number of cores and plenty of free storage space,
you can build and run all possible tests using the following options:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
$ ./scripts/twister --all --enable-slow
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --all --enable-slow
This will build for all available boards and run all applicable tests in
a simulated (for example QEMU) environment.
If you want to run tests on one or more specific platforms, you can use
the ``--platform`` option, it is a platform filter for testing, with this
option, test suites will only be built/run on the platforms specified.
This option also supports different revisions of one same board,
you can use ``--platform board@revision`` to test on a specific revision.
The list of command line options supported by twister can be viewed using:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
$ ./scripts/twister --help
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --help
Board Configuration
*******************
To build tests for a specific board and to execute some of the tests on real
hardware or in an emulation environment such as QEMU a board configuration file
is required which is generic enough to be used for other tasks that require a
board inventory with details about the board and its configuration that is only
available during build time otherwise.
The board metadata file is located in the board directory and is structured
using the YAML markup language. The example below shows a board with a data
required for best test coverage for this specific board:
.. code-block:: yaml
identifier: frdm_k64f
name: NXP FRDM-K64F
type: mcu
arch: arm
toolchain:
- zephyr
- gnuarmemb
- xtools
supported:
- arduino_gpio
- arduino_i2c
- netif:eth
- adc
- i2c
- nvs
- spi
- gpio
- usb_device
- watchdog
- can
- pwm
testing:
default: true
identifier:
A string that matches how the board is defined in the build system. This same
string is used when building, for example when calling ``west build`` or
``cmake``:
.. code-block:: console
# with west
west build -b reel_board
# with cmake
cmake -DBOARD=reel_board ..
name:
The actual name of the board as it appears in marketing material.
type:
Type of the board or configuration, currently we support 2 types: mcu, qemu
simulation:
Simulator used to simulate the platform, e.g. qemu.
arch:
Architecture of the board
toolchain:
The list of supported toolchains that can build this board. This should match
one of the values used for :envvar:`ZEPHYR_TOOLCHAIN_VARIANT` when building on the command line
ram:
Available RAM on the board (specified in KB). This is used to match test scenario
requirements. If not specified we default to 128KB.
flash:
Available FLASH on the board (specified in KB). This is used to match test scenario
requirements. If not specified we default to 512KB.
supported:
A list of features this board supports. This can be specified as a single word
feature or as a variant of a feature class. For example:
.. code-block:: yaml
supported:
- pci
This indicates the board does support PCI. You can make a test scenario build or
run only on such boards, or:
.. code-block:: yaml
supported:
- netif:eth
- sensor:bmi16
A test scenario can depend on 'eth' to only test ethernet or on 'netif' to run
on any board with a networking interface.
testing:
testing relating keywords to provide best coverage for the features of this
board.
default: [True|False]:
This is a default board, it will tested with the highest priority and is
covered when invoking the simplified twister without any additional
arguments.
ignore_tags:
Do not attempt to build (and therefore run) tests marked with this list of
tags.
only_tags:
Only execute tests with this list of tags on a specific platform.
.. _twister_board_timeout_multiplier:
timeout_multiplier: <float> (default 1)
Multiply each test scenario timeout by specified ratio. This option allows to tune timeouts only
for required platform. It can be useful in case naturally slow platform I.e.: HW board with
power-efficient but slow CPU or simulation platform which can perform instruction accurate
simulation but does it slowly.
env:
A list of environment variables. Twister will check if all these environment variables are set,
and otherwise skip this platform. This allows the user to define a platform which should be
used, for example, only if some required software or hardware is present, and to signal that
presence to twister using these environment variables.
Tests
******
Tests are detected by the presence of a ``testcase.yaml`` or a ``sample.yaml``
files in the application's project directory. This test application
configuration file may contain one or more entries in the tests section each
identifying a test scenario.
.. _twister_test_project_diagram:
.. figure:: ../../../../develop/test/figures/twister_test_project.svg
:alt: Twister and a Test applications' project.
:figclass: align-center
Twister and a Test applications' project.
Test application configurations are written using the YAML syntax and share the
same structure as samples.
A test scenario is a set of conditions or variables, defined in test scenario
entry, under which a set of test suites will be executed. Can be used
interchangeably with test scenario entry.
A test suite is a collection of test cases that are intended to be used to test
a software program to ensure it meets certain requirements. The test cases in a
test suite are often related or meant to be executed together.
The name of each test scenario needs to be unique in the context of the overall
test application and has to follow basic rules:
#. The format of the test scenario identifier shall be a string without any spaces or
special characters (allowed characters: alphanumeric and [\_=]) consisting
of multiple sections delimited with a dot (.).
#. Each test scenario identifier shall start with a section followed by a
subsection separated by a dot. For example, a test scenario that covers
semaphores in the kernel shall start with ``kernel.semaphore``.
#. All test scenario identifiers within a ``testcase.yaml`` file need to be unique. For
example a ``testcase.yaml`` file covering semaphores in the kernel can have:
* ``kernel.semaphore``: For general semaphore tests
* ``kernel.semaphore.stress``: Stress testing semaphores in the kernel.
#. Depending on the nature of the test, an identifier can consist of at least
two sections:
* Ztest tests: The individual test cases in the ztest testsuite will be
concatenated by dot (`.`) to the identifier in the ``testcase.yaml`` file
generating unique identifiers for every test case in the suite.
* Standalone tests and samples: This type of test should at least have 3
sections concatnated by dot (`.`) in the test scenario identifier in the
``testcase.yaml`` (or ``sample.yaml``) file.
The last section of the name shall signify the test case itself.
The following is an example test configuration with a few options that are
explained in this document.
.. code-block:: yaml
tests:
bluetooth.gatt:
build_only: true
platform_allow: qemu_cortex_m3 qemu_x86
tags: bluetooth
bluetooth.gatt.br:
build_only: true
extra_args: CONF_FILE="prj_br.conf"
filter: not CONFIG_DEBUG
platform_exclude: up_squared
platform_allow: qemu_cortex_m3 qemu_x86
tags: bluetooth
A sample with tests will have the same structure with additional information
related to the sample and what is being demonstrated:
.. code-block:: yaml
sample:
name: hello world
description: Hello World sample, the simplest Zephyr application
tests:
sample.basic.hello_world:
build_only: true
tags: tests
min_ram: 16
sample.basic.hello_world.singlethread:
build_only: true
extra_args: CONF_FILE=prj_single.conf
filter: not CONFIG_BT
tags: tests
min_ram: 16
The full canonical name for each test scenario is:``<path to test application>/<test scenario identifier>``
A test scenario entry is a a block or entry starting with test scenario
identifier in the YAML files.
Each test scenario entry in the test application configuration can define the
following key/value pairs:
tags: <list of tags> (required)
A set of string tags for the test scenario. Usually pertains to
functional domains but can be anything. Command line invocations
of this script can filter the set of tests to run based on tag.
skip: <True|False> (default False)
skip test scenario unconditionally. This can be used for broken tests for
example.
slow: <True|False> (default False)
Don't run this test scenario unless ``--enable-slow`` or ``--enable-slow-only`` was
passed in on the command line. Intended for time-consuming test scenarios that
are only run under certain circumstances, like daily builds. These test
scenarios are still compiled.
extra_args: <list of extra arguments>
Extra arguments to pass to build tool when building or running the
test scenario.
extra_configs: <list of extra configurations>
Extra configuration options to be merged with a main prj.conf
when building or running the test scenario. For example:
.. code-block:: yaml
common:
tags: drivers adc
tests:
test:
depends_on: adc
test_async:
extra_configs:
- CONFIG_ADC_ASYNC=y
Using namespacing, it is possible to apply a configuration only to some
hardware. Currently both architectures and platforms are supported:
.. code-block:: yaml
common:
tags: drivers adc
tests:
test:
depends_on: adc
test_async:
extra_configs:
- arch:x86:CONFIG_ADC_ASYNC=y
- platform:qemu_x86:CONFIG_DEBUG=y
build_only: <True|False> (default False)
If true, twister will not try to run the test even if the test is runnable
on the platform.
This keyword is reserved for tests that are used to test if some code
actually builds. A ``build_only`` test is not designed to be run in any
environment and should not be testing any functionality, it only verifies
that the code builds.
This option is often used to test drivers and the fact that they are correctly
enabled in Zephyr and that the code builds, for example sensor drivers. Such
test shall not be used to verify the functionality of the driver.
build_on_all: <True|False> (default False)
If true, attempt to build test scenario on all available platforms. This is mostly
used in CI for increased coverage. Do not use this flag in new tests.
depends_on: <list of features>
A board or platform can announce what features it supports, this option
will enable the test only those platforms that provide this feature.
levels: <list of levels>
Test levels this test should be part of. If a level is present, this
test will be selectable using the command line option ``--level <level name>``
min_ram: <integer>
minimum amount of RAM in KB needed for this test to build and run. This is
compared with information provided by the board metadata.
min_flash: <integer>
minimum amount of ROM in KB needed for this test to build and run. This is
compared with information provided by the board metadata.
.. _twister_test_case_timeout:
timeout: <number of seconds>
Length of time to run test before automatically killing it.
Default to 60 seconds.
arch_allow: <list of arches, such as x86, arm, arc>
Set of architectures that this test scenario should only be run for.
arch_exclude: <list of arches, such as x86, arm, arc>
Set of architectures that this test scenario should not run on.
platform_allow: <list of platforms>
Set of platforms that this test scenario should only be run for. Do not use
this option to limit testing or building in CI due to time or resource
constraints, this option should only be used if the test or sample can
only be run on the allowed platform and nothing else.
integration_platforms: <YML list of platforms/boards>
This option limits the scope to the listed platforms when twister is
invoked with the ``--integration`` option. Use this instead of
platform_allow if the goal is to limit scope due to timing or
resource constraints.
platform_exclude: <list of platforms>
Set of platforms that this test scenario should not run on.
extra_sections: <list of extra binary sections>
When computing sizes, twister will report errors if it finds
extra, unexpected sections in the Zephyr binary unless they are named
here. They will not be included in the size calculation.
sysbuild: <True|False> (default False)
Build the project using sysbuild infrastructure. Only the main project's
generated devicetree and Kconfig will be used for filtering tests.
on device testing must use the hardware map, or west flash to load
the images onto the target. The ``--erase`` option of west flash is
not supported with this option. Usage of unsupported options will result
in tests requiring sysbuild support being skipped.
harness: <string>
A harness keyword in the ``testcase.yaml`` file identifies a Twister
harness needed to run a test successfully. A harness is a feature of
Twister and implemented by Twister, some harnesses are defined as
placeholders and have no implementation yet.
A harness can be seen as the handler that needs to be implemented in
Twister to be able to evaluate if a test passes criteria. For example, a
keyboard harness is set on tests that require keyboard interaction to reach
verdict on whether a test has passed or failed, however, Twister lack this
harness implementation at the moment.
Supported harnesses:
- ztest
- test
- console
- pytest
- gtest
- robot
Harnesses ``ztest``, ``gtest`` and ``console`` are based on parsing of the
output and matching certain phrases. ``ztest`` and ``gtest`` harnesses look
for pass/fail/etc. frames defined in those frameworks. Use ``gtest``
harness if you've already got tests written in the gTest framework and do
not wish to update them to zTest. The ``console`` harness tells Twister to
parse a test's text output for a regex defined in the test's YAML file.
The ``robot`` harness is used to execute Robot Framework test suites
in the Renode simulation framework.
Some widely used harnesses that are not supported yet:
- keyboard
- net
- bluetooth
Harness ``bsim`` is implemented in limited way - it helps only to copy the
final executable (``zephyr.exe``) from build directory to BabbleSim's
``bin`` directory (``${BSIM_OUT_PATH}/bin``). This action is useful to allow
BabbleSim's tests to directly run after. By default, the executable file
name is (with dots and slashes replaced by underscores):
``bs_<platform_name>_<test_path>_<test_scenario_name>``.
This name can be overridden with the ``bsim_exe_name`` option in
``harness_config`` section.
platform_key: <list of platform attributes>
Often a test needs to only be built and run once to qualify as passing.
Imagine a library of code that depends on the platform architecture where
passing the test on a single platform for each arch is enough to qualify the
tests and code as passing. The platform_key attribute enables doing just
that.
For example to key on (arch, simulation) to ensure a test is run once
per arch and simulation (as would be most common):
.. code-block:: yaml
platform_key:
- arch
- simulation
Adding platform (board) attributes to include things such as soc name,
soc family, and perhaps sets of IP blocks implementing each peripheral
interface would enable other interesting uses. For example, this could enable
building and running SPI tests once for each unique IP block.
harness_config: <harness configuration options>
Extra harness configuration options to be used to select a board and/or
for handling generic Console with regex matching. Config can announce
what features it supports. This option will enable the test to run on
only those platforms that fulfill this external dependency.
The following options are currently supported:
type: <one_line|multi_line> (required)
Depends on the regex string to be matched
regex: <list of regular expressions> (required)
Strings with regular expressions to match with the test's output
to confirm the test runs as expected.
ordered: <True|False> (default False)
Check the regular expression strings in orderly or randomly fashion
record: <recording options> (optional)
regex: <regular expression> (required)
The regular expression with named subgroups to match data fields
at the test's output lines where the test provides some custom data
for further analysis. These records will be written into the build
directory ``recording.csv`` file as well as ``recording`` property
of the test suite object in ``twister.json``.
For example, to extract three data fields ``metric``, ``cycles``,
``nanoseconds``:
.. code-block:: yaml
record:
regex: "(?P<metric>.*):(?P<cycles>.*) cycles, (?P<nanoseconds>.*) ns"
as_json: <list of regex subgroup names> (optional)
Data fields, extracted by the regular expression into named subgroups,
which will be additionally parsed as JSON encoded strings and written
into ``twister.json`` as nested ``recording`` object properties.
The corresponding ``recording.csv`` columns will contain strings as-is.
Using this option, a test log can convey layered data structures
passed from the test image for further analysis with summary results,
traces, statistics, etc.
For example, this configuration:
.. code-block:: yaml
record:
regex: "RECORD:(?P<type>.*):DATA:(?P<metrics>.*)"
as_json: [metrics]
when matched to a test log string:
.. code-block:: none
RECORD:jitter_drift:DATA:{"rollovers":0, "mean_us":1000.0}
will be reported in ``twister.json`` as:
.. code-block:: json
"recording":[
{
"type":"jitter_drift",
"metrics":{
"rollovers":0,
"mean_us":1000.0
}
}
]
fixture: <expression>
Specify a test scenario dependency on an external device(e.g., sensor),
and identify setups that fulfill this dependency. It depends on
specific test setup and board selection logic to pick the particular
board(s) out of multiple boards that fulfill the dependency in an
automation setup based on ``fixture`` keyword. Some sample fixture names
are i2c_hts221, i2c_bme280, i2c_FRAM, ble_fw and gpio_loop.
Only one fixture can be defined per test scenario and the fixture name has to
be unique across all tests in the test suite.
.. _pytest_root:
pytest_root: <list of pytest testpaths> (default pytest)
Specify a list of pytest directories, files or subtests that need to be
executed when a test scenario begins to run. The default pytest directory is
``pytest``. After the pytest run is finished, Twister will check if
the test scenario passed or failed according to the pytest report.
As an example, a list of valid pytest roots is presented below:
.. code-block:: yaml
harness_config:
pytest_root:
- "pytest/test_shell_help.py"
- "../shell/pytest/test_shell.py"
- "/tmp/test_shell.py"
- "~/tmp/test_shell.py"
- "$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py"
- "pytest/test_shell_help.py::test_shell2_sample" # select pytest subtest
- "pytest/test_shell_help.py::test_shell2_sample[param_a]" # select pytest parametrized subtest
.. _pytest_args:
pytest_args: <list of arguments> (default empty)
Specify a list of additional arguments to pass to ``pytest`` e.g.:
``pytest_args: [‘-k=test_method’, ‘--log-level=DEBUG’]``. Note that
``--pytest-args`` can be passed multiple times to pass several arguments
to the pytest.
.. _pytest_dut_scope:
pytest_dut_scope: <function|class|module|package|session> (default function)
The scope for which ``dut`` and ``shell`` pytest fixtures are shared.
If the scope is set to ``function``, DUT is launched for every test case
in python script. For ``session`` scope, DUT is launched only once.
robot_testsuite: <robot file path> (default empty)
Specify one or more paths to a file containing a Robot Framework test suite to be run.
robot_option: <robot option> (default empty)
One or more options to be send to robotframework.
bsim_exe_name: <string>
If provided, the executable filename when copying to BabbleSim's bin
directory, will be ``bs_<platform_name>_<bsim_exe_name>`` instead of the
default based on the test path and scenario name.
The following is an example yaml file with a few harness_config options.
.. code-block:: yaml
sample:
name: HTS221 Temperature and Humidity Monitor
common:
tags: sensor
harness: console
harness_config:
type: multi_line
ordered: false
regex:
- "Temperature:(.*)C"
- "Relative Humidity:(.*)%"
fixture: i2c_hts221
tests:
test:
tags: sensors
depends_on: i2c
The following is an example yaml file with pytest harness_config options,
default pytest_root name "pytest" will be used if pytest_root not specified.
please refer the examples in samples/subsys/testsuite/pytest/.
.. code-block:: yaml
common:
harness: pytest
tests:
pytest.example.directories:
harness_config:
pytest_root:
- pytest_dir1
- $ENV_VAR/samples/test/pytest_dir2
pytest.example.files_and_subtests:
harness_config:
pytest_root:
- pytest/test_file_1.py
- test_file_2.py::test_A
- test_file_2.py::test_B[param_a]
The following is an example yaml file with robot harness_config options.
.. code-block:: yaml
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite: [robot file path]
It can be more than one test suite using a list.
.. code-block:: yaml
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite:
- [robot file path 1]
- [robot file path 2]
- [robot file path n]
One or more options can be passed to robotframework.
.. code-block:: yaml
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite: [robot file path]
robot_option:
- --exclude tag
- --stop-on-error
filter: <expression>
Filter whether the test scenario should be run by evaluating an expression
against an environment containing the following values:
.. code-block:: none
{ ARCH : <architecture>,
PLATFORM : <platform>,
<all CONFIG_* key/value pairs in the test's generated defconfig>,
*<env>: any environment variable available
}
Twister will first evaluate the expression to find if a "limited" cmake call, i.e. using package_helper cmake script,
can be done. Existence of "dt_*" entries indicates devicetree is needed.
Existence of "CONFIG*" entries indicates kconfig is needed.
If there are no other types of entries in the expression a filtration can be done without creating a complete build system.
If there are entries of other types a full cmake is required.
The grammar for the expression language is as follows:
.. code-block:: antlr
expression : expression 'and' expression
| expression 'or' expression
| 'not' expression
| '(' expression ')'
| symbol '==' constant
| symbol '!=' constant
| symbol '<' NUMBER
| symbol '>' NUMBER
| symbol '>=' NUMBER
| symbol '<=' NUMBER
| symbol 'in' list
| symbol ':' STRING
| symbol
;
list : '[' list_contents ']';
list_contents : constant (',' constant)*;
constant : NUMBER | STRING;
For the case where ``expression ::= symbol``, it evaluates to ``true``
if the symbol is defined to a non-empty string.
Operator precedence, starting from lowest to highest:
* or (left associative)
* and (left associative)
* not (right associative)
* all comparison operators (non-associative)
``arch_allow``, ``arch_exclude``, ``platform_allow``, ``platform_exclude``
are all syntactic sugar for these expressions. For instance:
.. code-block:: none
arch_exclude = x86 arc
Is the same as:
.. code-block:: none
filter = not ARCH in ["x86", "arc"]
The ``:`` operator compiles the string argument as a regular expression,
and then returns a true value only if the symbol's value in the environment
matches. For example, if ``CONFIG_SOC="stm32f107xc"`` then
.. code-block:: none
filter = CONFIG_SOC : "stm.*"
Would match it.
required_snippets: <list of needed snippets>
:ref:`Snippets <snippets>` are supported in twister for test scenarios that
require them. As with normal applications, twister supports using the base
zephyr snippet directory and test application directory for finding
snippets. Listed snippets will filter supported tests for boards (snippets
must be compatible with a board for the test to run on them, they are not
optional).
The following is an example yaml file with 2 required snippets.
.. code-block:: yaml
tests:
snippet.example:
required_snippets:
- cdc-acm-console
- user-snippet-example
The set of test scenarios that actually run depends on directives in the test scenario
filed and options passed in on the command line. If there is any confusion,
running with ``-v`` or examining the discard report
(:file:`twister_discard.csv`) can help show why particular test scenarios were
skipped.
Metrics (such as pass/fail state and binary size) for the last code
release are stored in ``scripts/release/twister_last_release.csv``.
To update this, pass the ``--all --release`` options.
To load arguments from a file, add ``+`` before the file name, e.g.,
``+file_name``. File content must be one or more valid arguments separated by
line break instead of white spaces.
Most everyday users will run with no arguments.
Managing tests timeouts
***********************
There are several parameters which control tests timeouts on various levels:
* ``timeout`` option in each test scenario. See :ref:`here <twister_test_case_timeout>` for more
details.
* ``timeout_multiplier`` option in board configuration. See
:ref:`here <twister_board_timeout_multiplier>` for more details.
* ``--timeout-multiplier`` twister option which can be used to adjust timeouts in exact twister run.
It can be useful in case of simulation platform as simulation time may depend on the host
speed & load or we may select different simulation method (i.e. cycle accurate but slower
one), etc...
Overall test scenario timeout is a multiplication of these three parameters.
Running in Integration Mode
***************************
This mode is used in continuous integration (CI) and other automated
environments used to give developers fast feedback on changes. The mode can
be activated using the ``--integration`` option of twister and narrows down
the scope of builds and tests if applicable to platforms defined under the
integration keyword in the test configuration file (``testcase.yaml`` and
``sample.yaml``).
Running tests on custom emulator
********************************
Apart from the already supported QEMU and other simulated environments, Twister
supports running any out-of-tree custom emulator defined in the board's :file:`board.cmake`.
To use this type of simulation, add the following properties to
:file:`custom_board/custom_board.yaml`:
.. code-block:: yaml
simulation: custom
simulation_exec: <name_of_emu_binary>
This tells Twister that the board is using a custom emulator called ``<name_of_emu_binary>``,
make sure this binary exists in the PATH.
Then, in :file:`custom_board/board.cmake`, set the supported emulation platforms to ``custom``:
.. code-block:: cmake
set(SUPPORTED_EMU_PLATFORMS custom)
Finally, implement the ``run_custom`` target in :file:`custom_board/board.cmake`.
It should look something like this:
.. code-block:: cmake
add_custom_target(run_custom
COMMAND
<name_of_emu_binary to invoke during 'run'>
<any args to be passed to the command, i.e. ${BOARD}, ${APPLICATION_BINARY_DIR}/zephyr/zephyr.elf>
WORKING_DIRECTORY ${APPLICATION_BINARY_DIR}
DEPENDS ${logical_target_for_zephyr_elf}
USES_TERMINAL
)
Running Tests on Hardware
*************************
Beside being able to run tests in QEMU and other simulated environments,
twister supports running most of the tests on real devices and produces
reports for each run with detailed FAIL/PASS results.
Executing tests on a single device
===================================
To use this feature on a single connected device, run twister with
the following new options:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
scripts/twister --device-testing --device-serial /dev/ttyACM0 \
--device-serial-baud 115200 -p frdm_k64f -T tests/kernel
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --device-testing --device-serial COM1 \
--device-serial-baud 115200 -p frdm_k64f -T tests/kernel
The ``--device-serial`` option denotes the serial device the board is connected to.
This needs to be accessible by the user running twister. You can run this on
only one board at a time, specified using the ``--platform`` option.
The ``--device-serial-baud`` option is only needed if your device does not run at
115200 baud.
To support devices without a physical serial port, use the ``--device-serial-pty``
option. In this cases, log messages are captured for example using a script.
In this case you can run twister with the following options:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
scripts/twister --device-testing --device-serial-pty "script.py" \
-p intel_adsp/cavs25 -T tests/kernel
.. group-tab:: Windows
.. note::
Not supported on Windows OS
The script is user-defined and handles delivering the messages which can be
used by twister to determine the test execution status.
The ``--device-flash-timeout`` option allows to set explicit timeout on the
device flash operation, for example when device flashing takes significantly
large time.
The ``--device-flash-with-test`` option indicates that on the platform
the flash operation also executes a test scenario, so the flash timeout is
increased by a test scenario timeout.
Executing tests on multiple devices
===================================
To build and execute tests on multiple devices connected to the host PC, a
hardware map needs to be created with all connected devices and their
details such as the serial device, baud and their IDs if available.
Run the following command to produce the hardware map:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
./scripts/twister --generate-hardware-map map.yml
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --generate-hardware-map map.yml
The generated hardware map file (map.yml) will have the list of connected
devices, for example:
.. tabs::
.. group-tab:: Linux
.. code-block:: yaml
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: unknown
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/cu.usbmodem146114202
- connected: true
id: 000683759358
platform: unknown
product: J-Link
runner: unknown
serial: /dev/cu.usbmodem0006837593581
.. group-tab:: Windows
.. code-block:: yaml
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: unknown
product: unknown
runner: unknown
serial: COM1
- connected: true
id: 000683759358
platform: unknown
product: unknown
runner: unknown
serial: COM2
Any options marked as ``unknown`` need to be changed and set with the correct
values, in the above example the platform names, the products and the runners need
to be replaced with the correct values corresponding to the connected hardware.
In this example we are using a reel_board and an nrf52840dk/nrf52840:
.. tabs::
.. group-tab:: Linux
.. code-block:: yaml
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: reel_board
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/cu.usbmodem146114202
baud: 9600
- connected: true
id: 000683759358
platform: nrf52840dk/nrf52840
product: J-Link
runner: nrfjprog
serial: /dev/cu.usbmodem0006837593581
baud: 9600
.. group-tab:: Windows
.. code-block:: yaml
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: reel_board
product: DAPLink CMSIS-DAP
runner: pyocd
serial: COM1
baud: 9600
- connected: true
id: 000683759358
platform: nrf52840dk/nrf52840
product: J-Link
runner: nrfjprog
serial: COM2
baud: 9600
The baud entry is only needed if not running at 115200.
If the map file already exists, then new entries are added and existing entries
will be updated. This way you can use one single master hardware map and update
it for every run to get the correct serial devices and status of the devices.
With the hardware map ready, you can run any tests by pointing to the map
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
./scripts/twister --device-testing --hardware-map map.yml -T samples/hello_world/
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --device-testing --hardware-map map.yml -T samples\hello_world
The above command will result in twister building tests for the platforms
defined in the hardware map and subsequently flashing and running the tests
on those platforms.
.. note::
Currently only boards with support for pyocd, nrfjprog, jlink, openocd, or dediprog
are supported with the hardware map features. Boards that require other runners to flash the
Zephyr binary are still work in progress.
Hardware map allows to set ``--device-flash-timeout`` and ``--device-flash-with-test``
command line options as ``flash-timeout`` and ``flash-with-test`` fields respectively.
These hardware map values override command line options for the particular platform.
Serial PTY support using ``--device-serial-pty`` can also be used in the
hardware map:
.. code-block:: yaml
- connected: true
id: None
platform: intel_adsp/cavs25
product: None
runner: intel_adsp
serial_pty: path/to/script.py
runner_params:
- --remote-host=remote_host_ip_addr
- --key=/path/to/key.pem
The runner_params field indicates the parameters you want to pass to the
west runner. For some boards the west runner needs some extra parameters to
work. It is equivalent to following west and twister commands.
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
west flash --remote-host remote_host_ip_addr --key /path/to/key.pem
twister -p intel_adsp/cavs25 --device-testing --device-serial-pty script.py
--west-flash="--remote-host=remote_host_ip_addr,--key=/path/to/key.pem"
.. group-tab:: Windows
.. note::
Not supported on Windows OS
.. note::
For serial PTY, the "--generate-hardware-map" option cannot scan it out
and generate a correct hardware map automatically. You have to edit it
manually according to above example. This is because the serial port
of the PTY is not fixed and being allocated in the system at runtime.
Fixtures
+++++++++
Some tests require additional setup or special wiring specific to the test.
Running the tests without this setup or test fixture may fail. A test scenario can
specify the fixture it needs which can then be matched with hardware capability
of a board and the fixtures it supports via the command line or using the hardware
map file.
Fixtures are defined in the hardware map file as a list:
.. code-block:: yaml
- connected: true
fixtures:
- gpio_loopback
id: 0240000026334e450015400f5e0e000b4eb1000097969900
platform: frdm_k64f
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/ttyACM9
When running ``twister`` with ``--device-testing``, the configured fixture
in the hardware map file will be matched to test scenarios requesting the same fixtures
and these tests will be executed on the boards that provide this fixture.
.. figure:: ../../../../develop/test/figures/fixtures.svg
:figclass: align-center
Fixtures can also be provided via twister command option ``--fixture``, this option
can be used multiple times and all given fixtures will be appended as a list. And the
given fixtures will be assigned to all boards, this means that all boards set by
current twister command can run those test scenarios which request the same fixtures.
Some fixtures allow for configuration strings to be appended, separated from the
fixture name by a ``:``. Only the fixture name is matched against the fixtures
requested by test scenarios.
Notes
+++++
It may be useful to annotate board descriptions in the hardware map file
with additional information. Use the ``notes`` keyword to do this. For
example:
.. code-block:: yaml
- connected: false
fixtures:
- gpio_loopback
id: 000683290670
notes: An nrf5340dk/nrf5340 is detected as an nrf52840dk/nrf52840 with no serial
port, and three serial ports with an unknown platform. The board id of the serial
ports is not the same as the board id of the development kit. If you regenerate
this file you will need to update serial to reference the third port, and platform
to nrf5340dk/nrf5340/cpuapp or another supported board target.
platform: nrf52840dk/nrf52840
product: J-Link
runner: jlink
serial: null
Overriding Board Identifier
+++++++++++++++++++++++++++
When (re-)generated the hardware map file will contain an ``id`` keyword
that serves as the argument to ``--board-id`` when flashing. In some
cases the detected ID is not the correct one to use, for example when
using an external J-Link probe. The ``probe_id`` keyword overrides the
``id`` keyword for this purpose. For example:
.. code-block:: yaml
- connected: false
id: 0229000005d9ebc600000000000000000000000097969905
platform: mimxrt1060_evk
probe_id: 000609301751
product: DAPLink CMSIS-DAP
runner: jlink
serial: null
Quarantine
++++++++++
Twister allows user to provide configuration files defining a list of tests or
platforms to be put under quarantine. Such tests will be skipped and marked
accordingly in the output reports. This feature is especially useful when
running larger test suits, where a failure of one test can affect the execution
of other tests (e.g. putting the physical board in a corrupted state).
To use the quarantine feature one has to add the argument
``--quarantine-list <PATH_TO_QUARANTINE_YAML>`` to a twister call.
Multiple quarantine files can be used.
The current status of tests on the quarantine list can also be verified by adding
``--quarantine-verify`` to the above argument. This will make twister skip all tests
which are not on the given list.
A quarantine yaml has to be a sequence of dictionaries. Each dictionary has to have
``scenarios`` and ``platforms`` entries listing combinations of scenarios and platforms
to put under quarantine. In addition, an optional entry ``comment`` can be used, where
some more details can be given (e.g. link to a reported issue). These comments will also
be added to the output reports.
When quarantining a class of tests or many scenarios in a single testsuite or
when dealing with multiple issues within a subsystem, it is possible to use
regular expressions, for example, **kernel.*** would quarantine
all kernel tests.
An example of entries in a quarantine yaml:
.. code-block:: yaml
- scenarios:
- sample.basic.helloworld
comment: "Link to the issue: https://github.com/zephyrproject-rtos/zephyr/pull/33287"
- scenarios:
- kernel.common
- kernel.common.(misra|tls)
- kernel.common.nano64
platforms:
- .*_cortex_.*
- native_sim
To exclude a platform, use the following syntax:
.. code-block:: yaml
- platforms:
- qemu_x86
comment: "broken qemu"
Additionally you can quarantine entire architectures or a specific simulator for executing tests.
Test Configuration
******************
A test configuration can be used to customize various aspects of twister
and the default enabled options and features. This allows tweaking the filtering
capabilities depending on the environment and makes it possible to adapt and
improve coverage when targeting different sets of platforms.
The test configuration also adds support for test levels and the ability to
assign a specific test to one or more levels. Using command line options of
twister it is then possible to select a level and just execute the tests
included in this level.
Additionally, the test configuration allows defining level
dependencies and additional inclusion of tests into a specific level if
the test itself does not have this information already.
In the configuration file you can include complete components using
regular expressions and you can specify which test level to import from
the same file, making management of levels easier.
To help with testing outside of upstream CI infrastructure, additional
options are available in the configuration file, which can be hosted
locally. As of now, those options are available:
- Ability to ignore default platforms as defined in board definitions
(Those are mostly emulation platforms used to run tests in upstream
CI)
- Option to specify your own list of default platforms overriding what
upstream defines.
- Ability to override `build_on_all` options used in some test scenarios.
This will treat tests or sample as any other just build for default
platforms you specify in the configuration file or on the command line.
- Ignore some logic in twister to expand platform coverage in cases where
default platforms are not in scope.
Platform Configuration
======================
The following options control platform filtering in twister:
- `override_default_platforms`: override default key a platform sets in board
configuration and instead use the list of platforms provided in the
configuration file as the list of default platforms. This option is set to
False by default.
- `increased_platform_scope`: This option is set to True by default, when
disabled, twister will not increase platform coverage automatically and will
only build and run tests on the specified platforms.
- `default_platforms`: A list of additional default platforms to add. This list
can either be used to replace the existing default platforms or can extend it
depending on the value of `override_default_platforms`.
And example platforms configuration:
.. code-block:: yaml
platforms:
override_default_platforms: true
increased_platform_scope: false
default_platforms:
- qemu_x86
Test Level Configuration
========================
The test configuration allows defining test levels, level dependencies and
additional inclusion of tests into a specific test level if the test itself
does not have this information already.
In the configuration file you can include complete components using
regular expressions and you can specify which test level to import from
the same file, making management of levels simple.
And example test level configuration:
.. code-block:: yaml
levels:
- name: my-test-level
description: >
my custom test level
adds:
- kernel.threads.*
- kernel.timer.behavior
- arch.interrupt
- boards.*
Combined configuration
======================
To mix the Platform and level configuration, you can take an example as below:
An example platforms plus level configuration:
.. code-block:: yaml
platforms:
override_default_platforms: true
default_platforms:
- frdm_k64f
levels:
- name: smoke
description: >
A plan to be used verifying basic zephyr features.
- name: unit
description: >
A plan to be used verifying unit test.
- name: integration
description: >
A plan to be used verifying integration.
- name: acceptance
description: >
A plan to be used verifying acceptance.
- name: system
description: >
A plan to be used verifying system.
- name: regression
description: >
A plan to be used verifying regression.
To run with above test_config.yaml file, only default_platforms with given test level
test scenarios will run.
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
scripts/twister --test-config=<path to>/test_config.yaml
-T tests --level="smoke"
Running in Tests in Random Order
********************************
Enable ZTEST framework's :kconfig:option:`CONFIG_ZTEST_SHUFFLE` config option to
run your tests in random order. This can be beneficial for identifying
dependencies between test cases. For native_sim platforms, you can provide
the seed to the random number generator by providing ``-seed=value`` as an
argument to twister. See :ref:`Shuffling Test Sequence <ztest_shuffle>` for more
details.
Robot Framework Tests
*********************
Zephyr supports `Robot Framework <https://robotframework.org/>`_ as one of solutions for automated testing.
Robot files allow you to express interactive test scenarios in human-readable text format and execute them in simulation or against hardware.
At this moment Zephyr integration supports running Robot tests in the `Renode <https://renode.io/>`_ simulation framework.
To execute a Robot test suite with twister, run the following command:
.. tabs::
.. group-tab:: Linux
.. code-block:: bash
$ ./scripts/twister --platform hifive1 --test samples/subsys/shell/shell_module/sample.shell.shell_module.robot
.. group-tab:: Windows
.. code-block:: bat
python .\scripts\twister --platform hifive1 --test samples/subsys/shell/shell_module/sample.shell.shell_module.robot
Writing Robot tests
===================
For the list of keywords provided by the Robot Framework itself, refer to `the official Robot documentation <https://robotframework.org/robotframework/>`_.
Information on writing and running Robot Framework tests in Renode can be found in `the testing section <https://renode.readthedocs.io/en/latest/introduction/testing.html>`_ of Renode documentation.
It provides a list of the most commonly used keywords together with links to the source code where those are defined.
It's possible to extend the framework by adding new keywords expressed directly in Robot test suite files, as an external Python library or, like Renode does it, dynamically via XML-RPC.
For details see the `extending Robot Framework <https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#extending-robot-framework>`_ section in the official Robot documentation.
Running a single testsuite
==========================
To run a single testsuite instead of a whole group of test you can run:
.. code-block:: bash
$ twister -p qemu_riscv32 -s tests/kernel/interrupt/arch.shared_interrupt
Part 3
한국어 전문 번역
Test Runner(Twister)
Twister는 Git repository에서 test application 집합을 scan하고 실행을 시도합니다. 기본값에서는 board definition에서 default로 표시된 board마다 각 test application을 build합니다.
기본 option은 정해진 board 집합에서 대부분의 test application을 build하고, 대상 architecture 또는 configuration에 emulator가 있으면 그 환경에서 실행합니다.
Local test의 실행 coverage에는 한계가 있어 전체 build environment의 성공을 보장할 수는 없습니다. 그래도 여러 board와 configuration에서 sample·test를 build해 전체 code tree가 계속 build 가능한 상태를 유지하는 데 필요한 검사를 제공합니다.
-v를 하나 이상 주면 각 test application이 QEMU, native_sim 등 어떤 방식으로 실행되는지 또는 binary만 build됐는지 console에 표시됩니다.
Twister가 실행하지 않고 build만 하는 이유는 다음과 같습니다.
- YAML configuration에서
build_only: true로 표시됨 - Test configuration이 요구하는 harness가 없거나 설정되지 않음
- Target device가 연결되지 않아 flash할 수 없음
- 사용자 또는 상위 automation이
--build-only로 Twister를 호출함
Local source tree에서 Linux로 실행합니다.
$ source zephyr-env.sh
$ ./scripts/twisterWindows에서 실행합니다.
zephyr-env.cmd
python .\scripts\twisterCPU core와 여유 storage가 충분한 system에서 가능한 모든 test를 build하고 slow test까지 실행하려면 다음 option을 사용합니다.
$ ./scripts/twister --all --enable-slowpython .\scripts\twister --all --enable-slow모든 사용 가능한 board에 build하고 적용 가능한 test를 QEMU 같은 simulation 환경에서 실행합니다.
--platform은 특정 platform만 build·실행하는 filter입니다. 여러 번 지정할 수 있고 board@revision 형식으로 board revision도 선택할 수 있습니다.
지원 command-line option을 확인합니다.
$ ./scripts/twister --helppython .\scripts\twister --helpBoard configuration
특정 board에 test를 build하고 실제 hardware 또는 QEMU 같은 emulator에서 실행하려면 board configuration file이 필요합니다. 이 inventory는 build time에만 알 수 있는 board 세부 정보를 다른 작업에서도 재사용할 수 있게 합니다.
Board metadata는 board directory의 YAML file입니다. 다음 예제는 FRDM-K64F에서 좋은 test coverage를 얻는 데 필요한 data를 보여 줍니다.
identifier: frdm_k64f
name: NXP FRDM-K64F
type: mcu
arch: arm
toolchain:
- zephyr
- gnuarmemb
- xtools
supported:
- arduino_gpio
- arduino_i2c
- netif:eth
- adc
- i2c
- nvs
- spi
- gpio
- usb_device
- watchdog
- can
- pwm
testing:
default: true| Key | 의미와 선택 기준 |
|---|---|
identifier | Build system에서 board를 지정할 때 쓰는 문자열입니다. west build -b 또는 CMake BOARD 값과 같아야 합니다. |
name | Marketing 자료에 표시되는 실제 board 이름입니다. |
type | mcu 또는 qemu 중 현재 지원되는 board/configuration type입니다. |
simulation | Platform을 simulation하는 simulator 이름입니다. 예: QEMU. |
arch | Board architecture입니다. |
toolchain | ZEPHYR_TOOLCHAIN_VARIANT로 선택할 수 있는 지원 toolchain 목록입니다. |
ram | 사용 가능한 RAM(KB)입니다. Test scenario 요구량과 비교하며 생략하면 128KB입니다. |
flash | 사용 가능한 flash/ROM(KB)입니다. Test scenario 요구량과 비교하며 생략하면 512KB입니다. |
supported | pci 같은 단일 feature 또는 netif:eth, sensor:bmi16 같은 feature class와 variant 목록입니다. |
testing.default | 추가 argument 없이 단순 실행할 때 최우선으로 test하는 기본 board인지 정합니다. |
testing.ignore_tags | 이 platform에서 build·실행하지 않을 tag 목록입니다. |
testing.only_tags | 이 platform에서 실행을 허용할 tag 목록입니다. |
testing.timeout_multiplier | 각 test scenario timeout에 곱할 platform 전용 배율입니다. 느린 저전력 hardware나 cycle-accurate simulator에 유용합니다. 기본값은 1입니다. |
env | 필수 environment variable 목록입니다. 하나라도 설정되지 않았으면 Twister가 이 platform을 건너뜁니다. |
identifier가 build command에서 쓰이는 예:
# with west
west build -b reel_board
# with cmake
cmake -DBOARD=reel_board ..supported에 단일 feature를 선언하는 예:
supported:
- pciFeature class와 variant를 선언하면 test가 eth variant만 요구하거나 netif class 전체를 요구할 수 있습니다.
supported:
- netif:eth
- sensor:bmi16Test
testcase.yaml 또는 sample.yaml이 application project directory에 있으면 test를 발견합니다. tests section에는 하나 이상의 test scenario entry가 들어갑니다.
Test application configuration은 sample과 같은 YAML 구조를 사용합니다. Test scenario는 한 test suite 집합을 실행할 조건·variable의 집합이며 scenario entry와 같은 뜻으로 사용할 수 있습니다. Test suite는 software 요구 사항을 검증하기 위해 함께 실행할 관련 testcase 모음입니다.
각 test scenario 이름은 전체 test application 안에서 유일해야 하며 다음 규칙을 따릅니다.
- Space나 특수 문자를 제외한 alphanumeric과
_·=만 사용하고, 여러 section을 dot으로 구분합니다. - Section과 subsection으로 시작해야 합니다. Kernel semaphore test라면
kernel.semaphore로 시작합니다. testcase.yaml안에서 모든 scenario identifier가 유일해야 합니다. 예:kernel.semaphore,kernel.semaphore.stress.- Ztest는 YAML identifier 뒤에 개별 testcase 이름을 dot으로 이어 고유 이름을 만듭니다. Standalone test와 sample은 적어도 세 section을 사용하고 마지막 section이 testcase 자체를 나타내야 합니다.
여러 option을 포함한 test configuration 예:
tests:
bluetooth.gatt:
build_only: true
platform_allow: qemu_cortex_m3 qemu_x86
tags: bluetooth
bluetooth.gatt.br:
build_only: true
extra_args: CONF_FILE="prj_br.conf"
filter: not CONFIG_DEBUG
platform_exclude: up_squared
platform_allow: qemu_cortex_m3 qemu_x86
tags: bluetoothSample은 같은 test 구조에 sample 설명을 더합니다.
sample:
name: hello world
description: Hello World sample, the simplest Zephyr application
tests:
sample.basic.hello_world:
build_only: true
tags: tests
min_ram: 16
sample.basic.hello_world.singlethread:
build_only: true
extra_args: CONF_FILE=prj_single.conf
filter: not CONFIG_BT
tags: tests
min_ram: 16각 scenario의 canonical name은 <test application path>/<test scenario identifier>입니다. YAML에서 scenario identifier로 시작하는 block 하나가 test scenario entry입니다.
| Test scenario key | 동작 |
|---|---|
tags | 필수 문자열 tag 집합입니다. Functional domain 등을 표시하고 command-line tag filter가 사용합니다. |
skip | True이면 조건 없이 건너뜁니다. 기본값은 False이며 깨진 test를 임시 제외할 때 쓸 수 있습니다. |
slow | --enable-slow 또는 --enable-slow-only를 주지 않으면 실행하지 않지만 compile은 합니다. Daily build 같은 장시간 test용입니다. |
extra_args | Test를 build하거나 실행할 때 build tool에 전달할 추가 argument 목록입니다. |
extra_configs | prj.conf에 merge할 추가 configuration입니다. arch:x86: 또는 platform:qemu_x86: namespace로 적용 hardware를 제한할 수 있습니다. |
build_only | True이면 실행 가능 platform에서도 실행하지 않고 build 성공만 검증합니다. Driver 기능 검증이 아니라 code가 올바르게 활성화되고 compile되는지만 확인하는 test에 사용합니다. |
build_on_all | 가능한 모든 platform에 build해 CI coverage를 넓히는 legacy option입니다. 새 test에는 사용하지 마십시오. |
depends_on | Board metadata가 지원한다고 선언한 feature 목록입니다. 모두 제공하는 platform에서만 test를 활성화합니다. |
levels | --level <name>으로 선택할 수 있도록 test가 속하는 test level을 지정합니다. |
min_ram | Build·실행에 필요한 최소 RAM(KB)이며 board metadata와 비교합니다. |
min_flash | Build·실행에 필요한 최소 ROM/flash(KB)이며 board metadata와 비교합니다. |
timeout | Test를 자동 종료하기 전 실행 시간(초)입니다. 기본값은 60초입니다. |
arch_allow | 실행을 허용할 architecture 목록입니다. |
arch_exclude | 실행에서 제외할 architecture 목록입니다. |
platform_allow | 본질적으로 해당 platform에서만 실행 가능한 경우의 허용 목록입니다. CI 시간·resource 절약 목적으로 범위를 줄일 때는 사용하면 안 됩니다. |
integration_platforms | --integration 실행 때만 scope를 제한할 platform/board YAML 목록입니다. 시간·resource 때문에 integration 범위를 줄이는 목적이면 platform_allow 대신 사용합니다. |
platform_exclude | 실행하지 않을 platform 목록입니다. |
extra_sections | Binary size 계산에서 예상 밖 section 오류를 피하도록 허용할 추가 section입니다. 이 section은 크기 계산에서는 제외됩니다. |
sysbuild | Sysbuild infrastructure로 project를 build합니다. Filter에는 main project의 devicetree와 Kconfig만 사용합니다. 실기기 test는 hardware map 또는 west flash가 필요하고 west flash --erase는 지원하지 않습니다. |
harness | Test 출력을 평가하거나 외부 framework를 실행해 pass/fail을 판정하는 Twister handler를 지정합니다. |
platform_key | Platform attribute 조합마다 test를 한 번만 build·실행하도록 중복을 제거합니다. Architecture와 simulation 조합이나 SoC/IP block별 대표 coverage에 사용할 수 있습니다. |
harness_config | 선택한 harness의 regex, fixture, Pytest, Robot, BabbleSim 세부 동작을 지정합니다. |
filter | Architecture, platform, Kconfig, devicetree와 environment 값을 expression grammar로 평가해 실행 여부를 결정합니다. |
required_snippets | Test에 필요한 snippet 목록입니다. Zephyr 기본·test application snippet directory에서 찾으며 board와 호환되지 않으면 test를 filter합니다. |
extra_configs를 공통 configuration과 함께 쓰는 예:
common:
tags: drivers adc
tests:
test:
depends_on: adc
test_async:
extra_configs:
- CONFIG_ADC_ASYNC=yNamespace를 붙이면 특정 architecture나 platform에만 configuration을 적용합니다.
common:
tags: drivers adc
tests:
test:
depends_on: adc
test_async:
extra_configs:
- arch:x86:CONFIG_ADC_ASYNC=y
- platform:qemu_x86:CONFIG_DEBUG=yharness가 지원하는 handler:
ztesttestconsolepytestgtestrobot
ztest, gtest, console은 output phrase 또는 regex를 parsing합니다. 기존 gTest test에는 gtest harness를 쓸 수 있고 console은 YAML regex를 맞춥니다. Robot harness는 Renode에서 Robot Framework suite를 실행합니다.
아직 지원하지 않는 널리 쓰이는 placeholder harness:
keyboardnetbluetooth
bsim harness는 제한적으로 구현되어 최종 zephyr.exe를 ${BSIM_OUT_PATH}/bin에 복사합니다. 기본 이름은 dot과 slash를 underscore로 바꾼 bs_<platform_name>_<test_path>_<test_scenario_name>이며 harness_config.bsim_exe_name으로 덮어쓸 수 있습니다.
platform_key로 architecture와 simulation 조합마다 한 번만 실행하는 예:
platform_key:
- arch
- simulation| Harness configuration | 동작 |
|---|---|
type: one_line|multi_line | Console regex를 한 줄 또는 여러 줄에서 맞출지 지정하는 필수 값입니다. |
regex | Test output에서 찾아 정상 실행을 확인할 정규식 목록입니다. |
ordered | 정규식을 지정한 순서대로 검사할지 정합니다. 기본값은 False입니다. |
record.regex | Named subgroup으로 custom metric을 추출해 build directory의 recording.csv와 twister.json test suite recording property에 기록합니다. |
record.as_json | 지정 subgroup 값을 JSON string으로 추가 parsing해 twister.json에 중첩 object로 기록합니다. CSV에는 원래 string을 그대로 둡니다. |
fixture | Sensor나 loopback wiring 같은 외부 dependency를 하나 지정합니다. Automation이 같은 fixture를 제공하는 board를 선택하며 suite 전체에서 이름이 유일해야 합니다. |
pytest_root | 실행할 Pytest directory, file 또는 subtest 목록입니다. 기본 directory는 pytest이며 절대·상대·home·environment path와 parametrized subtest를 지원합니다. |
pytest_args | Pytest에 전달할 추가 argument 목록입니다. Twister --pytest-args도 여러 번 사용할 수 있습니다. |
pytest_dut_scope | function|class|module|package|session 중 dut·shell fixture 공유 scope입니다. Function이면 testcase마다 DUT를 실행하고 session이면 한 번만 실행합니다. |
robot_testsuite | 실행할 Robot Framework test suite file path 하나 이상입니다. |
robot_option | Robot Framework에 전달할 option 하나 이상입니다. |
bsim_exe_name | BabbleSim bin에 복사할 executable 이름을 기본 path/scenario 기반 대신 bs_<platform_name>_<bsim_exe_name>으로 정합니다. |
Custom record에서 세 data field를 추출합니다.
record:
regex: "(?P<metric>.*):(?P<cycles>.*) cycles, (?P<nanoseconds>.*) ns"JSON으로 encoding된 metric을 nested object로 parsing하는 configuration:
record:
regex: "RECORD:(?P<type>.*):DATA:(?P<metrics>.*)"
as_json: [metrics]이 test log와 일치하면:
RECORD:jitter_drift:DATA:{"rollovers":0, "mean_us":1000.0}twister.json에는 다음과 같이 기록됩니다.
"recording":[
{
"type":"jitter_drift",
"metrics":{
"rollovers":0,
"mean_us":1000.0
}
}
]Pytest root는 여러 형태의 path와 subtest를 받을 수 있습니다.
harness_config:
pytest_root:
- "pytest/test_shell_help.py"
- "../shell/pytest/test_shell.py"
- "/tmp/test_shell.py"
- "~/tmp/test_shell.py"
- "$ZEPHYR_BASE/samples/subsys/testsuite/pytest/shell/pytest/test_shell.py"
- "pytest/test_shell_help.py::test_shell2_sample" # select pytest subtest
- "pytest/test_shell_help.py::test_shell2_sample[param_a]" # select pytest parametrized subtestConsole harness configuration 전체 예:
sample:
name: HTS221 Temperature and Humidity Monitor
common:
tags: sensor
harness: console
harness_config:
type: multi_line
ordered: false
regex:
- "Temperature:(.*)C"
- "Relative Humidity:(.*)%"
fixture: i2c_hts221
tests:
test:
tags: sensors
depends_on: i2cPytest harness에서 directory, file, 일반·parameter subtest를 지정하는 예:
common:
harness: pytest
tests:
pytest.example.directories:
harness_config:
pytest_root:
- pytest_dir1
- $ENV_VAR/samples/test/pytest_dir2
pytest.example.files_and_subtests:
harness_config:
pytest_root:
- pytest/test_file_1.py
- test_file_2.py::test_A
- test_file_2.py::test_B[param_a]Robot suite path 하나를 지정합니다.
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite: [robot file path]여러 Robot suite를 list로 지정합니다.
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite:
- [robot file path 1]
- [robot file path 2]
- [robot file path n]Robot Framework option도 전달할 수 있습니다.
tests:
robot.example:
harness: robot
harness_config:
robot_testsuite: [robot file path]
robot_option:
- --exclude tag
- --stop-on-errorfilter expression은 다음 environment를 평가합니다.
{ ARCH : <architecture>,
PLATFORM : <platform>,
<all CONFIG_* key/value pairs in the test's generated defconfig>,
*<env>: any environment variable available
}Expression에 dt_* entry가 있으면 devicetree가, CONFIG* entry가 있으면 Kconfig가 필요합니다. 이 종류만 있으면 package helper의 제한된 CMake 호출로 filter할 수 있지만 다른 종류가 있으면 full CMake가 필요합니다.
Filter expression grammar:
expression : expression 'and' expression
| expression 'or' expression
| 'not' expression
| '(' expression ')'
| symbol '==' constant
| symbol '!=' constant
| symbol '<' NUMBER
| symbol '>' NUMBER
| symbol '>=' NUMBER
| symbol '<=' NUMBER
| symbol 'in' list
| symbol ':' STRING
| symbol
;
list : '[' list_contents ']';
list_contents : constant (',' constant)*;
constant : NUMBER | STRING;Symbol 하나만 있는 expression은 symbol이 정의되어 있고 빈 string이 아니면 true입니다. Operator precedence는 낮은 순서부터 다음과 같습니다.
or- left associativeand- left associativenot- right associative- 모든 comparison operator - non-associative
arch_allow, arch_exclude, platform_allow, platform_exclude는 이 expression의 간편 표기입니다.
arch_exclude = x86 arc위 설정은 다음 filter와 같습니다.
filter = not ARCH in ["x86", "arc"]: operator는 string argument를 정규식으로 compile하고 environment symbol 값이 일치할 때만 true입니다. CONFIG_SOC="stm32f107xc"일 때 다음 expression은 일치합니다.
filter = CONFIG_SOC : "stm.*"Snippet을 요구하는 test는 Zephyr base와 test application directory에서 snippet을 찾습니다. Listed snippet은 선택 사항이 아니므로 board와 호환되지 않으면 test를 실행하지 않습니다.
tests:
snippet.example:
required_snippets:
- cdc-acm-console
- user-snippet-example실제로 실행할 scenario는 YAML directive와 command-line option의 조합으로 정해집니다. 이유가 불분명하면 -v output 또는 twister_discard.csv를 확인하십시오.
직전 release의 pass/fail·binary size metric은 scripts/release/twister_last_release.csv에 있습니다. --all --release로 갱신합니다.
File에서 argument를 읽으려면 이름 앞에 +를 붙입니다. File에는 whitespace가 아니라 줄바꿈으로 구분된 유효 argument를 넣습니다. 일상적인 사용자는 대체로 argument 없이 실행합니다.
Test timeout 관리
Timeout은 세 계층의 parameter로 결정됩니다.
testcase.yaml각 scenario의timeout- Board configuration의
testing.timeout_multiplier - 해당 Twister 실행에서 조정하는
--timeout-multiplier
최종 test scenario timeout은 이 세 값을 모두 곱한 결과입니다. 느린 host의 simulator나 cycle-accurate simulation처럼 실행 속도가 달라지는 환경에서 배율을 조정합니다.
Integration mode 실행
--integration은 CI와 자동화 환경에서 변경에 빠른 feedback을 줄 때 사용합니다. testcase.yaml·sample.yaml의 integration_platforms에 정의된 platform을 적용해 가능하면 build·test scope를 좁힙니다.
Custom emulator에서 test 실행
QEMU 등 내장 simulation 외에도 board board.cmake에 정의한 out-of-tree custom emulator를 실행할 수 있습니다. custom_board/custom_board.yaml에 simulator type과 executable을 지정합니다.
simulation: custom
simulation_exec: <name_of_emu_binary><name_of_emu_binary>가 system PATH에 있어야 합니다. 이어서 custom_board/board.cmake의 지원 emulator를 custom으로 설정합니다.
set(SUPPORTED_EMU_PLATFORMS custom)마지막으로 같은 board.cmake에 run_custom target을 구현합니다.
add_custom_target(run_custom
COMMAND
<name_of_emu_binary to invoke during 'run'>
<any args to be passed to the command, i.e. ${BOARD}, ${APPLICATION_BINARY_DIR}/zephyr/zephyr.elf>
WORKING_DIRECTORY ${APPLICATION_BINARY_DIR}
DEPENDS ${logical_target_for_zephyr_elf}
USES_TERMINAL
)Hardware에서 test 실행
Twister는 QEMU와 simulator뿐 아니라 대부분의 test를 실제 device에서 실행하고 각 run의 상세 FAIL/PASS report를 생성할 수 있습니다.
Device 하나에서 test 실행
연결된 device 하나를 Linux에서 실행합니다.
scripts/twister --device-testing --device-serial /dev/ttyACM0 \
--device-serial-baud 115200 -p frdm_k64f -T tests/kernelWindows에서 실행합니다.
python .\scripts\twister --device-testing --device-serial COM1 \
--device-serial-baud 115200 -p frdm_k64f -T tests/kernel--device-serial은 board가 연결된 serial device이며 Twister 실행 사용자가 접근할 수 있어야 합니다. --platform으로 한 번에 board 하나를 지정합니다. Device baud가 115200이 아닐 때만 --device-serial-baud가 필요합니다.
물리 serial port가 없는 device는 user-defined script가 log message를 전달하는 pseudo terminal을 사용합니다.
scripts/twister --device-testing --device-serial-pty "script.py" \
-p intel_adsp/cavs25 -T tests/kernel--device-flash-timeout은 오래 걸리는 flash operation의 timeout을 명시합니다. --device-flash-with-test는 flash operation 자체가 test scenario도 실행하는 platform임을 표시해 flash timeout에 scenario timeout을 더합니다.
여러 device에서 test 실행
Host PC에 연결된 여러 device에서 build·실행하려면 serial device, baud, ID 등의 정보를 가진 hardware map이 필요합니다. Map을 생성합니다.
./scripts/twister --generate-hardware-map map.ymlpython .\scripts\twister --generate-hardware-map map.yml생성된 map.yml의 Linux 예:
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: unknown
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/cu.usbmodem146114202
- connected: true
id: 000683759358
platform: unknown
product: J-Link
runner: unknown
serial: /dev/cu.usbmodem0006837593581Windows 예:
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: unknown
product: unknown
runner: unknown
serial: COM1
- connected: true
id: 000683759358
platform: unknown
product: unknown
runner: unknown
serial: COM2unknown으로 표시된 platform, product, runner를 실제 연결 hardware에 맞게 고칩니다. Reel board와 nRF52840 DK를 설정한 Linux map:
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: reel_board
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/cu.usbmodem146114202
baud: 9600
- connected: true
id: 000683759358
platform: nrf52840dk/nrf52840
product: J-Link
runner: nrfjprog
serial: /dev/cu.usbmodem0006837593581
baud: 9600같은 map의 Windows 형태:
- connected: true
id: OSHW000032254e4500128002ab98002784d1000097969900
platform: reel_board
product: DAPLink CMSIS-DAP
runner: pyocd
serial: COM1
baud: 9600
- connected: true
id: 000683759358
platform: nrf52840dk/nrf52840
product: J-Link
runner: nrfjprog
serial: COM2
baud: 9600Baud가 115200이 아닐 때만 baud entry가 필요합니다. 기존 map을 다시 생성하면 새 entry를 추가하고 기존 entry를 갱신하므로 master hardware map 하나를 run마다 최신 serial device와 상태로 유지할 수 있습니다.
준비한 map으로 Linux와 Windows에서 test를 실행합니다.
./scripts/twister --device-testing --hardware-map map.yml -T samples/hello_world/python .\scripts\twister --device-testing --hardware-map map.yml -T samples\hello_worldTwister는 map에 정의된 platform용 test를 build한 뒤 각 device에 flash하고 실행합니다.
Hardware map의 flash-timeout과 flash-with-test field는 command-line --device-flash-timeout과 --device-flash-with-test에 대응하며 해당 platform에서는 map 값이 command-line 값을 덮습니다.
Serial PTY도 hardware map에 넣을 수 있습니다.
- connected: true
id: None
platform: intel_adsp/cavs25
product: None
runner: intel_adsp
serial_pty: path/to/script.py
runner_params:
- --remote-host=remote_host_ip_addr
- --key=/path/to/key.pemrunner_params는 west runner에 전달할 추가 parameter입니다. 다음 west와 Twister command와 같은 의미입니다.
west flash --remote-host remote_host_ip_addr --key /path/to/key.pem
twister -p intel_adsp/cavs25 --device-testing --device-serial-pty script.py
--west-flash="--remote-host=remote_host_ip_addr,--key=/path/to/key.pem"Fixture
일부 test에는 추가 setup이나 특별 wiring이 필요합니다. Scenario가 요구하는 fixture를 hardware map 또는 command line의 board capability와 맞춰 준비되지 않은 board에서 실행되는 것을 막습니다.
Hardware map에 fixture list를 선언합니다.
- connected: true
fixtures:
- gpio_loopback
id: 0240000026334e450015400f5e0e000b4eb1000097969900
platform: frdm_k64f
product: DAPLink CMSIS-DAP
runner: pyocd
serial: /dev/ttyACM9--device-testing 실행 시 Twister가 scenario가 요구한 fixture와 map의 fixture를 맞추고 제공 가능한 board에서 test를 실행합니다.
--fixture option을 여러 번 사용해 모든 선택 board에 fixture list를 공통 배정할 수도 있습니다. : 뒤에 configuration string이 붙는 fixture도 있지만 matching에는 fixture 이름만 사용합니다.
Note
notes keyword로 hardware map board 설명에 추가 정보를 기록할 수 있습니다.
- connected: false
fixtures:
- gpio_loopback
id: 000683290670
notes: An nrf5340dk/nrf5340 is detected as an nrf52840dk/nrf52840 with no serial
port, and three serial ports with an unknown platform. The board id of the serial
ports is not the same as the board id of the development kit. If you regenerate
this file you will need to update serial to reference the third port, and platform
to nrf5340dk/nrf5340/cpuapp or another supported board target.
platform: nrf52840dk/nrf52840
product: J-Link
runner: jlink
serial: nullBoard identifier 덮어쓰기
Hardware map을 생성하면 id가 flash --board-id argument로 쓰입니다. External J-Link probe처럼 감지한 ID가 올바른 flash ID가 아닐 때 probe_id가 id를 덮습니다.
- connected: false
id: 0229000005d9ebc600000000000000000000000097969905
platform: mimxrt1060_evk
probe_id: 000609301751
product: DAPLink CMSIS-DAP
runner: jlink
serial: nullQuarantine
Quarantine configuration file은 지정 test 또는 platform을 격리해 건너뛰고 report에 그 상태를 남깁니다. 하나의 실패가 physical board를 손상 상태로 만들어 뒤 test까지 방해할 수 있는 대규모 suite에서 특히 유용합니다.
--quarantine-list <PATH_TO_QUARANTINE_YAML>로 file을 추가하며 여러 file을 사용할 수 있습니다. --quarantine-verify를 더하면 목록 밖의 test를 모두 건너뛰어 격리 대상의 현재 상태만 검증합니다.
scenarios와 platforms 목록을 가진 dictionary sequence로 작성하고, optional comment에 issue 링크 등 상세 이유를 적어 report에도 포함할 수 있습니다. kernel.* 같은 정규식으로 suite·subsystem 전체를 격리할 수 있습니다.
- scenarios:
- sample.basic.helloworld
comment: "Link to the issue: https://github.com/zephyrproject-rtos/zephyr/pull/33287"
- scenarios:
- kernel.common
- kernel.common.(misra|tls)
- kernel.common.nano64
platforms:
- .*_cortex_.*
- native_simPlatform 하나를 제외하는 형태:
- platforms:
- qemu_x86
comment: "broken qemu"Architecture 전체나 특정 simulator 실행도 quarantine할 수 있습니다.
Test configuration
별도 test configuration file로 Twister 기본 option, filter 동작과 coverage를 실행 환경에 맞게 조정할 수 있습니다. Test level을 정의하고 test를 하나 이상의 level에 배정해 command line에서 선택할 수도 있습니다.
Level dependency, test YAML에 없는 추가 inclusion, 정규식 기반 component inclusion, 같은 file의 level import를 지원합니다. Upstream CI 밖의 local 환경을 위해 다음 기능도 제공합니다.
- Board definition의 upstream default platform 무시
- 자체 default platform 목록으로 upstream 목록 대체 또는 확장
build_on_all을 무시해 지정 default platform 또는 command-line platform만 build- Default platform이 scope 밖일 때 Twister가 자동으로 platform coverage를 늘리는 logic 비활성화
Platform configuration
override_default_platforms: board configuration의 default를 무시하고 configuration file의 목록을 사용합니다. 기본값 False.increased_platform_scope: 기본값 True. False이면 Twister가 coverage를 자동 확장하지 않고 지정 platform만 build·실행합니다.default_platforms: 추가 default platform 목록입니다. override 값에 따라 기존 목록을 대체하거나 확장합니다.
platforms:
override_default_platforms: true
increased_platform_scope: false
default_platforms:
- qemu_x86Test level configuration
Test level, level dependency, YAML에 없는 test의 추가 inclusion을 정의합니다. Regular expression으로 component 전체를 포함하거나 같은 file에서 level을 import할 수 있습니다.
levels:
- name: my-test-level
description: >
my custom test level
adds:
- kernel.threads.*
- kernel.timer.behavior
- arch.interrupt
- boards.*결합 configuration
Platform configuration과 level configuration을 한 file에 결합할 수 있습니다.
platforms:
override_default_platforms: true
default_platforms:
- frdm_k64f
levels:
- name: smoke
description: >
A plan to be used verifying basic zephyr features.
- name: unit
description: >
A plan to be used verifying unit test.
- name: integration
description: >
A plan to be used verifying integration.
- name: acceptance
description: >
A plan to be used verifying acceptance.
- name: system
description: >
A plan to be used verifying system.
- name: regression
description: >
A plan to be used verifying regression.이 test_config.yaml로 실행하면 지정 level에 속한 scenario를 default_platforms에서만 실행합니다.
scripts/twister --test-config=<path to>/test_config.yaml
-T tests --level="smoke"Test를 무작위 순서로 실행
Ztest framework의 CONFIG_ZTEST_SHUFFLE을 활성화하면 testcase를 무작위 순서로 실행해 testcase 사이의 숨은 dependency를 찾을 수 있습니다. native_sim platform은 Twister에 -seed=value argument로 random seed를 줄 수 있습니다. 자세한 내용은 Ztest test sequence shuffle을 참조하십시오.
Robot Framework test
Robot Framework는 Zephyr가 지원하는 automated testing 방법 중 하나입니다. Human-readable text로 interactive scenario를 작성해 simulation 또는 hardware에서 실행할 수 있습니다. Zephyr 3.7.0 통합은 현재 Renode simulation에서 Robot test를 실행합니다.
Twister에서 Robot suite를 실행합니다.
$ ./scripts/twister --platform hifive1 --test samples/subsys/shell/shell_module/sample.shell.shell_module.robotpython .\scripts\twister --platform hifive1 --test samples/subsys/shell/shell_module/sample.shell.shell_module.robotRobot test 작성
Framework 기본 keyword는 Robot 공식 문서를 참조하십시오. Renode에서 Robot test를 쓰고 실행하는 방법과 자주 쓰는 keyword는 Renode testing 문서에 있습니다.
Robot suite file에서 직접 keyword를 만들거나 external Python library를 사용하거나 Renode처럼 XML-RPC로 동적 확장할 수 있습니다. 자세한 내용은 Robot Framework 확장을 참조하십시오.
Test suite 하나 실행
Test group 전체 대신 suite 하나를 지정해 실행합니다.
$ twister -p qemu_riscv32 -s tests/kernel/interrupt/arch.shared_interrupt
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.