You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/explanation/04-testing-infrastructure.md
+78-2Lines changed: 78 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,7 +93,38 @@ traceability metadata`"]
93
93
94
94
The central abstraction is the capability-based `Target` model. Each target exposes capabilities such as `exec`, `file_transfer`, `restart`, `ssh`, and `sftp`. Tests declare which capabilities they require using the `@requires_capabilities` decorator, and the framework skips tests when the active target does not provide them. This design lets the same test code run against different target environments — a Docker container locally, a QEMU image in CI, a real board in the lab — with the plugin determining which capabilities are available.
95
95
96
-
The plugin model is what makes ITF extensible. Four built-in plugins cover the current target types and supporting concerns:
96
+
The plugin model is what makes ITF extensible. Plugins fall into two categories:
**Target plugins** override the `target_init` fixture to yield a `Target` subclass — they determine what environment the test runs against. Only one target plugin is active at a time. **Non-target plugins** (like DLT) provide independent fixtures and compose freely with any target plugin. Four built-in plugins cover the current scope:
97
128
98
129
| Plugin | Bazel label | Purpose |
99
130
|---|---|---|
@@ -102,7 +133,52 @@ The plugin model is what makes ITF extensible. Four built-in plugins cover the c
102
133
| DLT |`@score_itf//score/itf/plugins:dlt_plugin`| Diagnostic Log and Trace message capture and query |
103
134
| Attribute |`@score_itf//score/itf/plugins:attribute_plugin`| Requirement traceability metadata in JUnit XML |
104
135
105
-
Each plugin is a Bazel target (built via the `py_itf_plugin` rule) that handles provisioning, communication, and teardown. New target types can be added by implementing the `Target` abstract class and a `target_init` pytest fixture in a custom plugin, without changing the ITF core or the test-writing interface.
136
+
New target types can be added by implementing the `Target` abstract class and a `target_init` pytest fixture in a new plugin — the ITF core and existing tests require no changes.
137
+
138
+
The capability abstraction is what makes the same test file portable across environments:
ITF runs entirely on the host. It never communicates with the target directly — the plugin handles all provisioning, communication, and teardown. Adding support for a new hardware target (Raspberry Pi, Qualcomm board, etc.) requires only a new plugin:
ITF is structured across three Bazel modules. `score_itf` is the open-source core (plugin contract, Bazel rules, pytest integration). Private or proprietary plugins live in separate repositories (e.g. `vsps_itf_plugins` for ETAS-internal targets) and are consumed via `git_override` or `archive_override` in the test consumer's `MODULE.bazel`. This separation means the open-source core can evolve independently from private plugin implementations.
106
182
107
183
For traceability, the attribute plugin provides an `@add_test_properties` decorator that writes metadata such as `fully_verifies`, `test_type`, and `derivation_technique` into JUnit XML output. This connects ITF test results to the traceability model described in [section 4.2](#test-traceability).
Copy file name to clipboardExpand all lines: docs/how-to/testing.md
+4-45Lines changed: 4 additions & 45 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -110,7 +110,7 @@ py_test(
110
110
111
111
## Write an ITF integration test
112
112
113
-
[ITF](https://github.com/eclipse-score/itf) runs tests against real environments — Docker containers, QEMU VMs, or hardware — through a unified `Target` interface. The same test file can target different environments using `@requires_capabilities` decorators. See [Tutorial: Write Your First ITF Integration Test](../tutorials/itf-integration-test.md) for a guided introduction.
113
+
[ITF](https://github.com/eclipse-score/itf) runs tests against real environments — Docker containers, QEMU VMs, or hardware — through a unified `Target` interface. See [Tutorial: Write Your First ITF Integration Test](../tutorials/itf-integration-test.md) for a step-by-step introduction.
114
114
115
115
### Add ITF to your workspace
116
116
@@ -120,53 +120,12 @@ In `MODULE.bazel`:
120
120
bazel_dep(name="score_itf", version="0.2.0")
121
121
```
122
122
123
-
### Docker test
124
-
125
-
```python
126
-
deftest_hello(target):
127
-
exit_code, output = target.execute("echo 'Hello from target!'")
For Docker and QEMU test recipes, see the [upstream how-to](https://eclipse-score.github.io/itf/main/how-to/write_tests.html). For full plugin CLI args and capabilities, see the [upstream plugin reference](https://eclipse-score.github.io/itf/main/how-to/plugins.html).
167
124
168
125
### Capability guards
169
126
127
+
Tests declare which target capabilities they need. The framework skips tests when the active target does not provide them:
128
+
170
129
```python
171
130
from score.itf.plugins.core import requires_capabilities
Copy file name to clipboardExpand all lines: docs/reference/configuration.md
+2-9Lines changed: 2 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -82,16 +82,9 @@ py_itf_test(
82
82
)
83
83
```
84
84
85
-
Available plugins:
85
+
For the full `py_itf_test` attribute reference and `py_itf_plugin` rule, see the [upstream Bazel macros reference](https://eclipse-score.github.io/itf/main/reference/bazel_macros.html).
Copy file name to clipboardExpand all lines: docs/tutorials/itf-integration-test.md
+8-53Lines changed: 8 additions & 53 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,11 @@
1
1
# Tutorial: Write Your First ITF Integration Test
2
2
3
-
This tutorial walks through writing a working integration test using the [ITF framework](https://github.com/eclipse-score/itf). By the end, you will have a test that runs a command inside a Docker container through Bazel, and you will understand why ITF is structured the way it is.
3
+
This tutorial walks through writing a working integration test using the [ITF framework](https://github.com/eclipse-score/itf). By the end, you will have a test that runs a command inside a Docker container through Bazel.
4
4
5
5
**What you need:** a working devcontainer or local environment with Bazel and Docker available. See [Getting Started](getting-started.md) if you have not set that up yet.
6
6
7
7
---
8
8
9
-
## What ITF does
10
-
11
-
Most S-CORE tests are unit tests: they compile and run inside the Bazel sandbox on the build host. ITF tests are different — they run code against a real environment (a Docker container, a QEMU virtual machine, or a hardware device) through a unified plugin interface. This is the right tool for testing behavior that depends on a real OS, a real network, or a real device.
12
-
13
-
The same test file can target different environments. The `@requires_capabilities` decorator tells ITF which environment capabilities a test needs, and the framework skips tests that the active target cannot fulfill. Write once, run on Docker locally and on hardware in CI.
14
-
15
-
---
16
-
17
9
## Step 1: Add ITF to your workspace
18
10
19
11
In `MODULE.bazel`, add the dependency:
@@ -71,7 +63,7 @@ py_itf_test(
71
63
bazel test //tests:test_hello --test_output=all
72
64
```
73
65
74
-
You should see Docker pulling the image (once), the container starting, your `echo` command running, and a green test result. If something goes wrong, `--test_output=all` shows the full pytest output.
66
+
You should see Docker pulling the image (once), the container starting, your `echo` command running, and a green test result.
75
67
76
68
To force re-execution even if Bazel cached a previous pass:
77
69
@@ -83,7 +75,7 @@ bazel test //tests:test_hello --nocache_test_results --test_output=all
83
75
84
76
## Step 5: Make the test portable with capability guards
85
77
86
-
Add a second test that uses a capability not all targets provide. Docker supports `exec` and `file_transfer`; QEMU additionally supports `ssh` and `sftp`. Guard tests so they are skipped rather than failed on the wrong target:
78
+
The same test file can run against different target types. Guard tests on the capabilities they actually need so they are skipped rather than failed on targets that do not provide them:
87
79
88
80
```python
89
81
from score.itf.plugins.core import requires_capabilities
Run against the Docker target — `test_network_only` will be skipped because Docker does not expose `ssh`. Switch to a QEMU target and it runs. The same file works in both cases without modification.
104
-
105
-
---
106
-
107
-
## Step 6: Add traceability metadata (optional)
108
-
109
-
When a test verifies specific requirements, the attribute plugin can write that information into the JUnit XML report so the docs-as-code traceability system can link back to the requirement objects:
110
-
111
-
```python
112
-
from score.itf.plugins.core import requires_capabilities
113
-
from attribute_plugin import add_test_properties
114
-
115
-
@add_test_properties(
116
-
fully_verifies=["REQ-HELLO-001"],
117
-
test_type="requirements-based",
118
-
derivation_technique="requirements-analysis",
119
-
)
120
-
deftest_hello(target):
121
-
exit_code, output = target.execute("echo 'Hello from ITF!'")
122
-
assert exit_code ==0
123
-
assertb"Hello from ITF!"in output
124
-
```
125
-
126
-
Update the BUILD target to include the attribute plugin:
127
-
128
-
```starlark
129
-
py_itf_test(
130
-
name="test_hello",
131
-
srcs= ["test_hello.py"],
132
-
args= ["--docker-image=ubuntu:24.04"],
133
-
plugins= [
134
-
"@score_itf//score/itf/plugins:docker_plugin",
135
-
"@score_itf//score/itf/plugins:attribute_plugin",
136
-
],
137
-
)
138
-
```
139
-
140
-
The metadata appears as JUnit XML attributes on the test case element and can be consumed by Sphinx-based traceability tooling without a separate database or postprocessing step.
95
+
Run against the Docker target — `test_network_only` is skipped because Docker does not expose `ssh`. Switch to a QEMU target and it runs. The same file works in both cases without modification.
141
96
142
97
---
143
98
@@ -148,12 +103,12 @@ You now have a working ITF test that:
148
103
- runs inside a Docker container through `bazel test`
149
104
- participates in Bazel's incremental build and result caching
150
105
- guards itself with `@requires_capabilities` so it can run against multiple target types
151
-
- optionally writes requirement traceability into the test result report
152
106
153
107
---
154
108
155
109
## Next steps
156
110
157
-
-[Write an ITF test against a QEMU target](../how-to/testing.md#write-an-itf-integration-test) — SSH-based interaction with a VM
158
-
-[Run QNX unit tests](../how-to/testing.md#advanced-qnx-unit-tests) — cross-compiled tests in a QNX microvm
0 commit comments