Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ Note: Test id should be started from letter "T"

The plugin supports dividing tests into separate, trackable steps. When reporting to testomat.io, you can view detailed information for each step including execution status, duration, and any errors that occurred.

**Important**: This plugin only supports **reporting** test steps to testomat.io during test execution. Test steps cannot be imported to testomat.io using **sync** option.
**Important**: This plugin only supports **reporting** test steps to testomat.io during test execution. Test steps cannot be imported to testomat.io using **sync** option. Steps reported for skipped and failed test by default. To enable steps reporting for passed tests use **TESTOMATIO_STEPS_PASSED** env variable.

Test steps can be implemented using either decorators or context managers, giving you flexibility in how you structure your tests.

Expand Down Expand Up @@ -233,6 +233,37 @@ def test_book_read():
assert book.read() == text
```

**Note:** Step is registered when the step code is executed. Therefore, if test mark as skipped(not executed at all) or test code execution stops before step code is executed, step will not be attached to test:
```python
import pytest
from pytestomatio.utils.steps import step

# Step will not be added in report
@pytest.mark.skip
def test_skipped():
with step('Step1', 'user'):
assert True

# Step will not be added in report
def test_exception_raised():
raise ValueError()
with step('Step1', 'user'):
assert True

# Step will not be added in report
def test_early_skip():
pytest.skip()
with step('Step1', 'user'):
assert True

# Step1 will be added in report, Step2 will not be
def test_nested_step_skip_or_exception():
with step('Step1', 'user'):
with step('Step2', 'user'):
pytest.skip() # or AttributeError()
```


### Configuration with environment variables
You can use environment variable to control certain features of testomat.io

Expand Down
11 changes: 7 additions & 4 deletions pytestomatio/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,15 @@ def pytest_runtest_makereport(item: Item, call: CallInfo):
if hasattr(item, 'callspec'):
request['example'] = test_item.safe_params(item.callspec.params)

if not pytest.testomatio.test_run_config.disable_steps:
step_manager = _step_managers.get(item.nodeid)
if step_manager:
if call.excinfo is not None or \
(call.excinfo is None and pytest.testomatio.test_run_config.enable_steps_for_passed_test):
request['steps'] = step_manager.get_steps()

if not pytest.testomatio.test_run_config.disable_timestamp:
request['timestamp'] = time.time()

step_manager = _step_managers.get(item.nodeid)
if step_manager:
request['steps'] = step_manager.get_steps()

if item.nodeid not in pytest.testomatio.test_run_config.status_request:
pytest.testomatio.test_run_config.status_request[item.nodeid] = request
Expand Down
4 changes: 4 additions & 0 deletions pytestomatio/testomatio/testRunConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@ def __init__(self, kind: str = 'automated'):
disable_batch_upload = os.environ.get('TESTOMATIO_DISABLE_BATCH_UPLOAD') in ['True', 'true', '1']
batch_size = os.environ.get('TESTOMATIO_BATCH_SIZE', '')
shared_run = os.environ.get('TESTOMATIO_SHARED_RUN') in ['True', 'true', '1']
disable_steps = os.environ.get('TESTOMATIO_NO_STEPS') in ['True', 'true', '1']
enable_steps_for_passed_test = os.environ.get('TESTOMATIO_STEPS_PASSED') in ['True', 'true', '1']
disable_timestamp = os.environ.get('TESTOMATIO_NO_TIMESTAMP') in ['True', 'true', '1']
update_code = os.environ.get('TESTOMATIO_UPDATE_CODE', False) in ['True', 'true', '1']
exclude_skipped = os.environ.get('TESTOMATIO_EXCLUDE_SKIPPED', False) in ['True', 'true', '1']
shared_run_timeout = os.environ.get('TESTOMATIO_SHARED_RUN_TIMEOUT', '')
self.access_event = 'publish' if os.environ.get("TESTOMATIO_PUBLISH") else None
self.test_run_id = run_id
self.title = title
self.enable_steps_for_passed_test = enable_steps_for_passed_test
self.disable_steps = disable_steps
self.kind = kind
self.disable_batch = disable_batch_upload
self.batch_size = int(batch_size) if (batch_size.isdigit() and int(batch_size) <= 100) else DEFAULT_BATCH_SIZE
Expand Down
38 changes: 38 additions & 0 deletions tests/test_testomatio/test_testRunConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ def test_init_default_values(self):
assert config.test_run_id is None
assert config.title == "test run at 2024-01-15 10:30:45"
assert config.environment is None
assert config.enable_steps_for_passed_test is False
assert config.disable_steps is False
assert config.kind == 'automated'
assert config.disable_timestamp is False
assert config.exclude_skipped is False
Expand All @@ -44,6 +46,8 @@ def test_init_with_env_variables(self):
'TESTOMATIO_ENV': 'linux,browser:chrome,1920x1080',
'TESTOMATIO_LABEL': 'smoke,regression',
'TESTOMATIO_RUNGROUP_TITLE': 'Release 2.0',
'TESTOMATIO_NO_STEPS': '1',
'TESTOMATIO_STEPS_PASSED': '1',
'TESTOMATIO_NO_TIMESTAMP': '1',
'TESTOMATIO_JIRA_ID': 'TES-1',
'TESTOMATIO_UPDATE_CODE': '1',
Expand All @@ -59,6 +63,8 @@ def test_init_with_env_variables(self):
assert config.access_event == 'publish'
assert config.test_run_id == 'run_12345'
assert config.title == 'Custom Test Run'
assert config.enable_steps_for_passed_test is True
assert config.disable_steps is True
assert config.disable_timestamp is True
assert config.environment == 'linux,browser:chrome,1920x1080'
assert config.exclude_skipped is True
Expand Down Expand Up @@ -98,6 +104,38 @@ def test_init_shared_run_false_variations(self, value):
assert config.shared_run_timeout is None
assert config.parallel is True

@pytest.mark.parametrize('value', ['True', 'true', '1'])
def test_init_disable_steps_true_variations(self, value):
"""Test different true values for TESTOMATIO_NO_STEPS"""
with patch.dict(os.environ, {'TESTOMATIO_NO_STEPS': value}, clear=True):
config = TestRunConfig()

assert config.disable_steps is True

@pytest.mark.parametrize('value', ['False', 'false', '0', 'anything'])
def test_init_disable_steps_false_variations(self, value):
"""Test different false values TESTOMATIO_NO_STEPS"""
with patch.dict(os.environ, {'TESTOMATIO_NO_STEPS': value}, clear=True):
config = TestRunConfig()

assert config.disable_steps is False

@pytest.mark.parametrize('value', ['True', 'true', '1'])
def test_enable_passed_steps_run_true_variations(self, value):
"""Test different true values for TESTOMATIO_STEPS_PASSED"""
with patch.dict(os.environ, {'TESTOMATIO_STEPS_PASSED': value}, clear=True):
config = TestRunConfig()

assert config.enable_steps_for_passed_test is True

@pytest.mark.parametrize('value', ['False', 'false', '0', 'anything'])
def test_enable_passed_steps_false_variations(self, value):
"""Test different false values TESTOMATIO_STEPS_PASSED"""
with patch.dict(os.environ, {'TESTOMATIO_STEPS_PASSED': value}, clear=True):
config = TestRunConfig()

assert config.enable_steps_for_passed_test is False

@pytest.mark.parametrize('value', ['True', 'true', '1'])
def test_init_disable_timestamp_true_variations(self, value):
"""Test different true values for TESTOMATIO_NO_TIMESTAMP"""
Expand Down
Loading