Skip to content

Commit fca63cd

Browse files
authored
#21 - Using json format to describe a pytest session (#22)
1 parent e76232d commit fca63cd

File tree

5 files changed

+72
-18
lines changed

5 files changed

+72
-18
lines changed

docs/sources/changelog.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Changelog
33
=========
44

5+
* :release:`1.4.0 <2020-06-04>`
6+
* :feature:`21` Using json format to populate the RUN_DESCRIPTION field (through --description and --tag fields)
7+
58
* :release:`1.3.0 <2020-05-12>`
69
* :feature:`19` Normalized http codes used for sending metrics to a remote server.
710

docs/sources/configuration.rst

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,45 @@ Adding a description to a run
8383
-----------------------------
8484

8585
Sometimes, you might want to compare identical state of your code. In such cases, relying only on the scm
86-
references and the run date of the session. For that, `pytest-monitor` can assist you by adding a
87-
description field to your session.
86+
references and the run date of the session. For that, `pytest-monitor` can assist you by tagging
87+
your session using description and tags.
88+
The description should be used to provide a brief summary of your run while tags can be used to
89+
set special information you want to focus during your analysis.
8890
Setting a description is as simple as this:
8991

9092
.. code-block:: shell
9193
9294
bash $> pytest --description "Any run description you want"
95+
96+
97+
Flagging your session with specific information is as complex as setting the description:
98+
99+
.. code-block:: shell
100+
101+
bash $> pytest --tag pandas=1.0.1 --tag numpy=1.17
102+
103+
This will result in a session with the following description:
104+
105+
.. code-block:: text
106+
107+
{
108+
"pandas": "1.0.1",
109+
"numpy": "1.17"
110+
}
111+
112+
113+
You can perfectly use both options to fully describe your session:
114+
115+
.. code-block:: shell
116+
117+
bash $> pytest --tag pandas=1.0.1 --tag numpy=1.17 --description "Your summary"
118+
119+
This will result in a session with the following description:
120+
121+
.. code-block:: text
122+
123+
{
124+
"msg": "Your summary",
125+
"pandas": "1.0.1",
126+
"numpy": "1.17"
127+
}

pytest_monitor/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "1.3.0"
1+
__version__ = "1.4.0"
22
__author__ = "Jean-Sebastien Dieu"

pytest_monitor/pytest_monitor.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,25 @@ def pytest_addoption(parser):
2727
help='Select the scope to monitor. By default, only function is monitored.'
2828
'Values are function, class, module, session. You can set one or more of these'
2929
'by listing them using a comma separated list')
30-
group.addoption('--parametrization-explicit', dest='want_explicit_ids', action='store_true',
30+
group.addoption('--parametrization-explicit', dest='mtr_want_explicit_ids', action='store_true',
3131
help='Set this option to distinguish parametrized tests given their values.'
3232
' This requires the parameters to be stringifiable.')
3333
group.addoption('--no-monitor', action='store_true', dest='mtr_none', help='Disable all traces')
34-
group.addoption('--remote', action='store', dest='remote',
34+
group.addoption('--remote', action='store', dest='mtr_remote',
3535
help='Remote server to send the results to. Format is <ADRESS>:<PORT>')
3636
group.addoption('--db', action='store', dest='mtr_db_out', default='.pymon',
3737
help='Use the given sqlite database for storing results.')
38-
group.addoption('--no-db', action='store_true', help='Do not store results in local db.')
39-
group.addoption('--force-component', action='store',
38+
group.addoption('--no-db', action='store_true', dest='mtr_no_db', help='Do not store results in local db.')
39+
group.addoption('--force-component', action='store', dest='mtr_force_component',
4040
help='Force the component to be set at the given value for the all tests run'
4141
' in this session.')
42-
group.addoption('--component-prefix', action='store',
42+
group.addoption('--component-prefix', action='store', dest='mtr_component_prefix',
4343
help='Prefix each found components with the given value (applies to all tests'
4444
' run in this session).')
45-
group.addoption('--description', action='store', default='',
45+
group.addoption('--description', action='store', default='', dest='mtr_description',
4646
help='Use this option to provide a small summary about this run.')
47+
group.addoption('--tag', action='append', dest='mtr_tags', default=[],
48+
help='Provide meaningfull flags to your run. This can help you in your analysis.')
4749

4850

4951
def pytest_configure(config):
@@ -143,7 +145,7 @@ def prof():
143145

144146

145147
def pytest_make_parametrize_id(config, val, argname):
146-
if config.option.want_explicit_ids:
148+
if config.option.mtr_want_explicit_ids:
147149
return f'{argname}={val}'
148150

149151

@@ -153,22 +155,23 @@ def pytest_sessionstart(session):
153155
Instantiate a monitor session to save collected metrics.
154156
We yield at the end to let pytest pursue the execution.
155157
"""
156-
if session.config.option.force_component and session.config.option.component_prefix:
158+
if session.config.option.mtr_force_component and session.config.option.mtr_component_prefix:
157159
raise pytest.UsageError('Invalid usage: --force-component and --component-prefix are incompatible options!')
158-
if session.config.option.no_db and not session.config.option.remote and not session.config.option.mtr_none:
160+
if session.config.option.mtr_no_db and not session.config.option.mtr_remote and not session.config.option.mtr_none:
159161
warnings.warn('pytest-monitor: No storage specified but monitoring is requested. Disabling monitoring.')
160162
session.config.option.mtr_none = True
161-
component = session.config.option.force_component or session.config.option.component_prefix
162-
if session.config.option.component_prefix:
163+
component = session.config.option.mtr_force_component or session.config.option.mtr_component_prefix
164+
if session.config.option.mtr_component_prefix:
163165
component += '.{user_component}'
164166
if not component:
165167
component = '{user_component}'
166-
db = None if (session.config.option.mtr_none or session.config.option.no_db) else session.config.option.mtr_db_out
167-
remote = None if session.config.option.mtr_none else session.config.option.remote
168+
db = None if (session.config.option.mtr_none or session.config.option.mtr_no_db) else session.config.option.mtr_db_out
169+
remote = None if session.config.option.mtr_none else session.config.option.mtr_remote
168170
session.pytest_monitor = PyTestMonitorSession(db=db, remote=remote,
169171
component=component,
170172
scope=session.config.option.mtr_scope)
171-
session.pytest_monitor.compute_info(session.config.option.description)
173+
session.pytest_monitor.compute_info(session.config.option.mtr_description,
174+
session.config.option.mtr_tags)
172175
yield
173176

174177

pytest_monitor/session.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,27 @@ def get_env_id(self, env):
5454
remote = None
5555
return db, remote
5656

57-
def compute_info(self, description):
57+
def compute_info(self, description, tags):
5858
run_date = datetime.datetime.now().isoformat()
5959
scm = determine_scm_revision()
6060
h = hashlib.md5()
6161
h.update(scm.encode())
6262
h.update(run_date.encode())
6363
h.update(description.encode())
6464
self.__session = h.hexdigest()
65+
# From description + tags to JSON format
66+
d=dict()
67+
if description:
68+
d['description'] = description
69+
for tag in tags:
70+
if type(tag) is str:
71+
_tag_info = tag.split('=', 1)
72+
d[_tag_info[0]] = _tag_info[1]
73+
else:
74+
for sub_tag in tag:
75+
_tag_info = subtag.split('=', 1)
76+
d[_tag_info[0]] = _tag_info[1]
77+
description = json.dumps(d)
6578
# Now get memory usage base and create the database
6679
self.prepare()
6780
self.set_environment_info(ExecutionContext())

0 commit comments

Comments
 (0)