twister: pytest: Parametrize scope of the dut fixture
Added pytest_dut_scope keyword under harness_config section. New keyword is used to determine the scope of dut and shell fixtures in pytest-twister-harness plugin. Signed-off-by: Grzegorz Chwierut <grzegorz.chwierut@nordicsemi.no>
This commit is contained in:
parent
e57e7f28a9
commit
fffe0b9fad
7 changed files with 57 additions and 7 deletions
|
@ -69,6 +69,9 @@ DUT (initialize logging, flash device, connect serial etc).
|
|||
This fixture yields a device prepared according to the requested type
|
||||
(native posix, qemu, hardware, etc.). All types of devices share the same API.
|
||||
This allows for writing tests which are device-type-agnostic.
|
||||
Scope of this fixture is determined by the ``pytest_dut_scope``
|
||||
keyword placed under ``harness_config`` section.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -81,8 +84,10 @@ shell
|
|||
-----
|
||||
|
||||
Provide an object with methods used to interact with shell application.
|
||||
It calls `wait_for_promt` method, to not start scenario until DUT is ready.
|
||||
Note that it uses `dut` fixture, so `dut` can be skipped when `shell` is used.
|
||||
It calls ``wait_for_promt`` method, to not start scenario until DUT is ready.
|
||||
Note that it uses ``dut`` fixture, so ``dut`` can be skipped when ``shell`` is used.
|
||||
Scope of this fixture is determined by the ``pytest_dut_scope``
|
||||
keyword placed under ``harness_config`` section.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
|
@ -514,6 +514,11 @@ harness_config: <harness configuration options>
|
|||
pytest_args: <list of arguments> (default empty)
|
||||
Specify a list of additional arguments to pass to ``pytest``.
|
||||
|
||||
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_test_path: <robot file path> (default empty)
|
||||
Specify a path to a file containing a Robot Framework test suite to be run.
|
||||
|
||||
|
|
|
@ -36,11 +36,16 @@ def device_object(twister_harness_config: TwisterHarnessConfig) -> Generator[Dev
|
|||
device_object.close()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
def determine_scope(fixture_name, config):
|
||||
if dut_scope := config.getoption("--dut-scope", None):
|
||||
return dut_scope
|
||||
return 'function'
|
||||
|
||||
|
||||
@pytest.fixture(scope=determine_scope)
|
||||
def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generator[DeviceAdapter, None, None]:
|
||||
"""Return launched device - with run application."""
|
||||
test_name = request.node.name
|
||||
device_object.initialize_log_files(test_name)
|
||||
device_object.initialize_log_files(request.node.name)
|
||||
try:
|
||||
device_object.launch()
|
||||
yield device_object
|
||||
|
@ -48,7 +53,7 @@ def dut(request: pytest.FixtureRequest, device_object: DeviceAdapter) -> Generat
|
|||
device_object.close()
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@pytest.fixture(scope=determine_scope)
|
||||
def shell(dut: DeviceAdapter) -> Shell:
|
||||
"""Return ready to use shell interface"""
|
||||
shell = Shell(dut, timeout=20.0)
|
||||
|
|
|
@ -100,6 +100,11 @@ def pytest_addoption(parser: pytest.Parser):
|
|||
metavar='PATH',
|
||||
help='Script executed after closing serial connection.'
|
||||
)
|
||||
twister_harness_group.addoption(
|
||||
'--dut-scope',
|
||||
choices=('function', 'class', 'module', 'package', 'session'),
|
||||
help='The scope for which `dut` and `shell` fixtures are shared.'
|
||||
)
|
||||
|
||||
|
||||
def pytest_configure(config: pytest.Config):
|
||||
|
|
|
@ -268,6 +268,7 @@ class Pytest(Harness):
|
|||
config = self.instance.testsuite.harness_config
|
||||
pytest_root = config.get('pytest_root', ['pytest']) if config else ['pytest']
|
||||
pytest_args = config.get('pytest_args', []) if config else []
|
||||
pytest_dut_scope = config.get('pytest_dut_scope', None) if config else None
|
||||
command = [
|
||||
'pytest',
|
||||
'--twister-harness',
|
||||
|
@ -281,6 +282,8 @@ class Pytest(Harness):
|
|||
command.extend([os.path.normpath(os.path.join(
|
||||
self.source_dir, os.path.expanduser(os.path.expandvars(src)))) for src in pytest_root])
|
||||
command.extend(pytest_args)
|
||||
if pytest_dut_scope:
|
||||
command.append(f'--dut-scope={pytest_dut_scope}')
|
||||
|
||||
handler: Handler = self.instance.handler
|
||||
|
||||
|
@ -427,7 +430,7 @@ class Pytest(Harness):
|
|||
self.instance.execution_time = float(elem_ts.get('time'))
|
||||
|
||||
for elem_tc in elem_ts.findall('testcase'):
|
||||
tc = self.instance.get_case_or_create(f"{self.id}.{elem_tc.get('name')}")
|
||||
tc = self.instance.add_testcase(f"{self.id}.{elem_tc.get('name')}")
|
||||
tc.duration = float(elem_tc.get('time'))
|
||||
elem = elem_tc.find('*')
|
||||
if elem is None:
|
||||
|
|
|
@ -104,6 +104,10 @@ mapping:
|
|||
required: false
|
||||
sequence:
|
||||
- type: str
|
||||
"pytest_dut_scope":
|
||||
type: str
|
||||
enum: ["function", "class", "module", "package", "session"]
|
||||
required: false
|
||||
"regex":
|
||||
type: seq
|
||||
required: false
|
||||
|
@ -304,6 +308,10 @@ mapping:
|
|||
required: false
|
||||
sequence:
|
||||
- type: str
|
||||
"pytest_dut_scope":
|
||||
type: str
|
||||
enum: ["function", "class", "module", "package", "session"]
|
||||
required: false
|
||||
"regex":
|
||||
type: seq
|
||||
required: false
|
||||
|
|
|
@ -48,6 +48,25 @@ def test_pytest_command(testinstance: TestInstance, device_type):
|
|||
assert c in command
|
||||
|
||||
|
||||
def test_pytest_command_dut_scope(testinstance: TestInstance):
|
||||
pytest_harness = Pytest()
|
||||
dut_scope = 'session'
|
||||
testinstance.testsuite.harness_config['pytest_dut_scope'] = dut_scope
|
||||
pytest_harness.configure(testinstance)
|
||||
command = pytest_harness.generate_command()
|
||||
assert f'--dut-scope={dut_scope}' in command
|
||||
|
||||
|
||||
def test_pytest_command_extra_args(testinstance: TestInstance):
|
||||
pytest_harness = Pytest()
|
||||
pytest_args = ['-k test1', '-m mark1']
|
||||
testinstance.testsuite.harness_config['pytest_args'] = pytest_args
|
||||
pytest_harness.configure(testinstance)
|
||||
command = pytest_harness.generate_command()
|
||||
for c in pytest_args:
|
||||
assert c in command
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
('pytest_root', 'expected'),
|
||||
[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue