Skip to content

Commit f4daea8

Browse files
committed
Fixes and new tests
1 parent 7f4f322 commit f4daea8

File tree

5 files changed

+138
-76
lines changed

5 files changed

+138
-76
lines changed

reportportal_client/helpers.py

Lines changed: 9 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import logging
1616
import time
1717
import uuid
18+
import warnings
1819
from platform import machine, processor, system
1920

2021
import six
@@ -168,61 +169,16 @@ def get_function_params(func, args, kwargs):
168169
:return: a set of tuples (name, value)
169170
"""
170171
# Use deprecated method for python 2.7 compatibility, it's still here for
171-
# Python 3.10.2
172-
# noinspection PyDeprecation
173-
arg_spec = inspect.getargspec(func)
172+
# Python 3.10.2, so it's completely redundant to show the warning
173+
with warnings.catch_warnings():
174+
warnings.filterwarnings("ignore", category=DeprecationWarning)
175+
# noinspection PyDeprecation
176+
arg_spec = inspect.getargspec(func)
174177
result = dict()
175178
for i, arg_name in enumerate(arg_spec.args):
176-
if arg_name in kwargs:
179+
if i >= len(args):
177180
break
178-
result[arg_name] = str(args[i])
181+
result[arg_name] = args[i]
179182
for arg_name, arg_value in kwargs.items():
180-
result[arg_name] = str(arg_value)
183+
result[arg_name] = arg_value
181184
return result if len(result.items()) > 0 else None
182-
183-
184-
__POSITIVE_STATUSES = ('PASSED', 'SKIPPED', 'STOPPED', 'INFO', 'WARN')
185-
186-
187-
def evaluate_status(current_status, child_status):
188-
"""Calculate an Item status according to its child and current status.
189-
190-
E.G.: SUITE-TEST or TEST-STEP.
191-
192-
Example 1:
193-
- Current status: FAILED
194-
- Child item status: SKIPPED
195-
Result: FAILED
196-
197-
Example 2:
198-
- Current status: PASSED
199-
- Child item status: SKIPPED
200-
Result: PASSED
201-
202-
Example 3:
203-
- Current status: PASSED
204-
- Child item status: FAILED
205-
Result: FAILED
206-
207-
Example 4:
208-
- Current status: SKIPPED
209-
- Child item status: FAILED
210-
Result: FAILED
211-
"""
212-
if child_status is None:
213-
return current_status
214-
if current_status is None:
215-
return child_status
216-
if child_status in __POSITIVE_STATUSES:
217-
return current_status
218-
if child_status == 'CANCELLED':
219-
if current_status in __POSITIVE_STATUSES:
220-
return 'CANCELLED'
221-
else:
222-
return current_status
223-
if child_status == 'INTERRUPTED':
224-
if current_status in __POSITIVE_STATUSES + tuple('CANCELLED'):
225-
return 'INTERRUPTED'
226-
else:
227-
return current_status
228-
return child_status

reportportal_client/steps/__init__.py

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
from functools import wraps
1515

1616
from reportportal_client._local import current
17-
from reportportal_client.helpers import get_function_params, evaluate_status, \
18-
timestamp
17+
from reportportal_client.helpers import get_function_params, timestamp
1918
from reportportal_client.static.defines import NOT_FOUND
2019

2120
NESTED_STEP_ITEMS = ('step', 'scenario', 'before_class', 'before_groups',
@@ -74,35 +73,45 @@ def __init__(self, name, params, status, rp_client):
7473
self.name = name
7574
self.params = params
7675
self.status = status
77-
self.client = rp_client if rp_client else current()
76+
self.client = rp_client
7877
self.__item_id = None
7978

8079
def __enter__(self):
81-
if not self.client:
80+
# Cannot call _local.current() early since it will be initialized
81+
# before client put something in there
82+
rp_client = self.client if self.client else current()
83+
if not rp_client:
8284
return
83-
self.__item_id = self.client.step_reporter \
85+
self.__item_id = rp_client.step_reporter \
8486
.start_nested_step(self.name, timestamp(), parameters=self.params)
85-
logger.info("Parameters: " + str(self.params))
87+
if self.params:
88+
rp_client.log(timestamp(), "Parameters: " + str(self.params),
89+
level='INFO', item_id=self.__item_id)
8690

8791
def __exit__(self, exc_type, exc_val, exc_tb):
92+
# Cannot call _local.current() early since it will be initialized
93+
# before client put something in there
94+
rp_client = self.client if self.client else current()
95+
if not rp_client:
96+
return
97+
# Avoid failure in case if 'rp_client' was 'None' on function start
8898
if not self.__item_id:
8999
return
90100
step_status = self.status
91101
if any((exc_type, exc_val, exc_tb)):
92102
step_status = 'FAILED'
93-
self.client.step_reporter \
94-
.finish_nested_step(self.__item_id, timestamp(),
95-
evaluate_status(self.status, step_status))
103+
rp_client.step_reporter \
104+
.finish_nested_step(self.__item_id, timestamp(), step_status)
96105

97106
def __call__(self, func):
98107
@wraps(func)
99108
def wrapper(*args, **kwargs):
100109
__tracebackhide__ = True
101-
if self.params is None:
102-
self.params = get_function_params(func, args, kwargs)
103-
with self:
110+
params = self.params
111+
if params is None:
112+
params = get_function_params(func, args, kwargs)
113+
with Step(self.name, params, self.status, self.client):
104114
return func(*args, **kwargs)
105-
106115
return wrapper
107116

108117

reportportal_client/steps/__init__.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,4 @@ class Step:
6464
def step(name_source: Union[Callable, Text],
6565
params: Dict = ...,
6666
status: Text = ...,
67-
rp_client: RPClient = ...) -> Step: ...
67+
rp_client: RPClient = ...) -> None: ...

tests/steps/test_steps.py

Lines changed: 106 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,46 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License
1313
from reportportal_client import step
14+
from reportportal_client._local import set_current
1415

1516
NESTED_STEP_NAME = 'test nested step'
1617
PARENT_STEP_ID = '123-123-1234-123'
1718
NESTED_STEP_ID = '321-321-4321-321'
1819

1920

2021
def test_nested_steps_are_skipped_without_parent(rp_client):
21-
with step(NESTED_STEP_NAME, rp_client=rp_client):
22-
print("Hello nested steps")
22+
with step(NESTED_STEP_NAME):
23+
pass
24+
2325
assert rp_client.session.post.call_count == 0
2426
assert rp_client.session.put.call_count == 0
2527

2628

2729
def test_nested_steps_reported_with_parent(rp_client):
2830
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
2931

30-
with step(NESTED_STEP_NAME, rp_client=rp_client):
31-
print("Hello nested steps")
32+
with step(NESTED_STEP_NAME):
33+
pass
34+
3235
assert rp_client.session.post.call_count == 1
3336
assert rp_client.session.put.call_count == 1
3437

3538

39+
def test_nested_steps_are_skipped_without_client(rp_client):
40+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
41+
set_current(None)
42+
with step(NESTED_STEP_NAME):
43+
pass
44+
45+
assert rp_client.session.post.call_count == 0
46+
assert rp_client.session.put.call_count == 0
47+
48+
3649
def test_nested_step_name(rp_client):
3750
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
3851

39-
with step(NESTED_STEP_NAME, rp_client=rp_client):
40-
print("Hello nested steps")
52+
with step(NESTED_STEP_NAME):
53+
pass
4154

4255
assert rp_client.session.post.call_args[1]['json']['name'] == \
4356
NESTED_STEP_NAME
@@ -46,8 +59,93 @@ def test_nested_step_name(rp_client):
4659
def test_nested_step_times(rp_client):
4760
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
4861

49-
with step(NESTED_STEP_NAME, rp_client=rp_client):
50-
print("Hello nested steps")
62+
with step(NESTED_STEP_NAME):
63+
pass
5164

5265
assert rp_client.session.post.call_args[1]['json']['startTime']
5366
assert rp_client.session.put.call_args[1]['json']['endTime']
67+
68+
69+
@step
70+
def nested_step():
71+
pass
72+
73+
74+
def test_nested_step_decorator(rp_client):
75+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
76+
nested_step()
77+
78+
assert rp_client.session.post.call_count == 1
79+
assert rp_client.session.put.call_count == 1
80+
assert len(rp_client._log_manager._logs_batch) == 0
81+
82+
83+
def test_nested_step_failed(rp_client):
84+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
85+
try:
86+
with step(NESTED_STEP_NAME):
87+
raise AssertionError
88+
except AssertionError:
89+
pass
90+
assert rp_client.session.post.call_count == 1
91+
assert rp_client.session.put.call_count == 1
92+
assert rp_client.session.put.call_args[1]['json']['status'] == 'FAILED'
93+
94+
95+
def test_nested_step_custom_status(rp_client):
96+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
97+
with step(NESTED_STEP_NAME, status='INFO'):
98+
pass
99+
assert rp_client.session.post.call_count == 1
100+
assert rp_client.session.put.call_count == 1
101+
assert rp_client.session.put.call_args[1]['json']['status'] == 'INFO'
102+
103+
104+
def test_nested_step_custom_status_failed(rp_client):
105+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
106+
try:
107+
with step(NESTED_STEP_NAME, status='INFO'):
108+
raise AssertionError
109+
except AssertionError:
110+
pass
111+
assert rp_client.session.post.call_count == 1
112+
assert rp_client.session.put.call_count == 1
113+
assert rp_client.session.put.call_args[1]['json']['status'] == 'FAILED'
114+
115+
116+
@step
117+
def nested_step_params(param1, param2, param3=None):
118+
pass
119+
120+
121+
def test_verify_parameters_logging_default_value(rp_client):
122+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
123+
nested_step_params(1, 'two')
124+
assert len(rp_client._log_manager._logs_batch) == 1
125+
assert rp_client._log_manager._logs_batch[0].message \
126+
== "Parameters: {'param1': 1, 'param2': 'two'}"
127+
128+
129+
def test_verify_parameters_logging_no_default_value(rp_client):
130+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
131+
nested_step_params(1, 'two', 'three')
132+
assert len(rp_client._log_manager._logs_batch) == 1
133+
assert rp_client._log_manager._logs_batch[0].message \
134+
== "Parameters: {'param1': 1, 'param2': 'two', 'param3': 'three'}"
135+
136+
137+
def test_verify_parameters_logging_named_value(rp_client):
138+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
139+
nested_step_params(1, 'two', param3='three')
140+
assert len(rp_client._log_manager._logs_batch) == 1
141+
assert rp_client._log_manager._logs_batch[0].message \
142+
== "Parameters: {'param1': 1, 'param2': 'two', 'param3': 'three'}"
143+
144+
145+
def test_verify_parameters_inline_logging(rp_client):
146+
rp_client.step_reporter.set_parent('STEP', PARENT_STEP_ID)
147+
with step(NESTED_STEP_NAME, params={'param1': 1, 'param2': 'two'}):
148+
pass
149+
assert len(rp_client._log_manager._logs_batch) == 1
150+
assert rp_client._log_manager._logs_batch[0].message \
151+
== "Parameters: {'param1': 1, 'param2': 'two'}"

tests/test_helpers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"""This modules contains unit tests for the helpers module."""
2-
32
from six.moves import mock
43

54
from reportportal_client.helpers import (

0 commit comments

Comments
 (0)