Skip to content

Commit a238f15

Browse files
committed
pytest-profiling: feat: support cProfile output filtering via regex
1 parent 3143865 commit a238f15

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

pytest-profiling/README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Install using your favourite package installer:
1616
# or
1717
easy_install pytest-profiling
1818
```
19-
19+
2020
Enable the fixture explicitly in your tests or conftest.py (not required when using setuptools entry points):
2121

2222
```python
@@ -31,9 +31,17 @@ Once installed, the plugin provides extra options to pytest:
3131
$ py.test --help
3232
...
3333
Profiling:
34-
--profile generate profiling information
35-
--profile-svg generate profiling graph (using gprof2dot and dot
36-
-Tsvg)
34+
--profile generate profiling information
35+
--profile-svg generate profiling graph (using gprof2dot and dot -Tsvg)
36+
--pstats-dir=PSTATS_DIR
37+
configure the dump directory of profile data files
38+
--element-number=ELEMENT_NUMBER
39+
defines how many elements will display in a result
40+
--element-regex=ELEMENT_REGEX
41+
filters elements displayed using regex
42+
--strip-dirs configure to show/hide the leading path information from
43+
file names
44+
3745
```
3846

3947
The ``--profile`` and ``profile-svg`` options can be combined with any other option:

pytest-profiling/pytest_profiling.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,12 @@ class Profiling(object):
3131
dot_cmd = None
3232
gprof2dot_cmd = None
3333

34-
def __init__(self, svg, dir=None, element_number=20, stripdirs=False):
34+
def __init__(self, svg, dir=None, element_number=20, stripdirs=False, element_regex=None):
3535
self.svg = svg
3636
self.dir = 'prof' if dir is None else dir[0]
3737
self.stripdirs = stripdirs
3838
self.element_number = element_number
39+
self.element_regex = element_regex
3940
self.profs = []
4041
self.gprof2dot = os.path.abspath(os.path.join(os.path.dirname(sys.executable), 'gprof2dot'))
4142
if not os.path.isfile(self.gprof2dot):
@@ -98,7 +99,12 @@ def pytest_terminal_summary(self, terminalreporter):
9899
stats = pstats.Stats(self.combined, stream=terminalreporter)
99100
if self.stripdirs:
100101
stats.strip_dirs()
101-
stats.sort_stats('cumulative').print_stats(self.element_number)
102+
if self.element_regex:
103+
print_args = self.element_regex, self.element_number
104+
else:
105+
print_args = (self.element_number,)
106+
stats.sort_stats('cumulative')
107+
stats.print_stats(*print_args)
102108
if self.svg_name:
103109
if not self.exit_code:
104110
# 0 - SUCCESS
@@ -144,6 +150,8 @@ def pytest_addoption(parser):
144150
help="generate profiling graph (using gprof2dot and dot -Tsvg)")
145151
group.addoption("--pstats-dir", nargs=1,
146152
help="configure the dump directory of profile data files")
153+
group.addoption("--profile-element-regex", type=str, default=None,
154+
help="filters elements displayed using regex")
147155
group.addoption("--element-number", action="store", type=int, default=20,
148156
help="defines how many elements will display in a result")
149157
group.addoption("--strip-dirs", action="store_true",
@@ -157,4 +165,5 @@ def pytest_configure(config):
157165
config.pluginmanager.register(Profiling(config.getvalue('profile_svg'),
158166
config.getvalue('pstats_dir'),
159167
element_number=config.getvalue('element_number'),
160-
stripdirs=config.getvalue('strip_dirs')))
168+
stripdirs=config.getvalue('strip_dirs'),
169+
element_regex=config.getvalue('profile_element_regex')))

pytest-profiling/tests/integration/test_profile_integration.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,17 @@ def test_profile_chdir(pytestconfig, virtualenv):
6969
pytestconfig,
7070
cd=virtualenv.workspace,
7171
)
72+
73+
74+
def test_profile_limited_output(pytestconfig, virtualenv):
75+
element_args = ["--element-number=2", r'--profile-element-regex=.*(test_regex|makedirs).*']
76+
# element_args = ["--element-number=100"]
77+
print(["-m", "pytest", "--profile", *element_args, "tests/unit/test_regex.py"])
78+
output = virtualenv.run_with_coverage(
79+
["-m", "pytest", "--profile", *element_args, "tests/unit/test_regex.py"],
80+
pytestconfig,
81+
cd=virtualenv.workspace,
82+
)
83+
assert "test_regex.py:4(test_regex)" in output
84+
assert "makedirs" in output
85+
assert "chdir" not in output

pytest-profiling/tests/unit/test_profile.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ def test_adds_options():
101101
group = parser.getgroup.return_value
102102
group.addoption.assert_any_call("--profile", action="store_true", help=ANY)
103103
group.addoption.assert_any_call("--profile-svg", action="store_true", help=ANY)
104+
group.addoption.assert_any_call("--pstats-dir", nargs=1, help=ANY)
105+
group.addoption.assert_any_call("--profile-element-regex", type=str, default=None, help=ANY)
106+
group.addoption.assert_any_call("--element-number", action="store", type=int, default=20, help=ANY)
107+
group.addoption.assert_any_call("--strip-dirs", action="store_true", help=ANY)
104108

105109

106110
def test_configures():

0 commit comments

Comments
 (0)