forked from pytest-dev/pytest
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test_profile.py
94 lines (75 loc) · 3.48 KB
/
test_profile.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# HACK: if the profile plugin is imported before the coverage plugin then all
# the top-level code in pytest_profiling will be omitted from
# coverage, so force it to be reloaded within this test unit under coverage
from six.moves import reload_module # @UnresolvedImport
import pytest_profiling
reload_module(pytest_profiling)
from pytest_profiling import Profiling, pytest_addoption, pytest_configure
from mock import Mock, ANY, patch, sentinel
def test_creates_prof_dir():
with patch('os.makedirs', side_effect=OSError) as makedirs:
Profiling(False).pytest_sessionstart(Mock())
makedirs.assert_called_with('prof')
def test_hooks_pyfunc_call():
assert getattr(Profiling.pytest_pyfunc_call, 'tryfirst')
multicall, pyfuncitem, plugin = Mock(), Mock(), Profiling(False)
pyfuncitem.name.__add__ = Mock()
with patch('os.path.join', return_value=sentinel.join):
with patch('pytest_profiling.cProfile.Profile') as Profile:
plugin.pytest_pyfunc_call(multicall, pyfuncitem)
prof = Profile() # mock instances are singletons
assert prof.runctx.called
assert prof.dump_stats.called
runctx_args, _ = prof.runctx.call_args
(dump_stats_filename, ), _ = prof.dump_stats.call_args
assert dump_stats_filename == sentinel.join
assert not multicall.execute.called
eval(*runctx_args)
assert multicall.execute.called
assert plugin.profs == [sentinel.join]
def test_combines_profs():
plugin = Profiling(False)
plugin.profs = [sentinel.prof0, sentinel.prof1]
with patch('pstats.Stats') as Stats:
plugin.pytest_sessionfinish(Mock(), Mock())
Stats.assert_called_once_with(sentinel.prof0)
Stats.return_value.add.assert_called_once_with(sentinel.prof1)
assert Stats.return_value.dump_stats.called
def test_generates_svg():
plugin = Profiling(True)
plugin.profs = [sentinel.prof]
with patch('pstats.Stats'):
with patch('pipes.Template') as Template:
plugin.pytest_sessionfinish(Mock(), Mock())
assert any('gprof2dot' in args[0][0] for args in Template.return_value.append.call_args_list)
assert Template.return_value.copy.called
def test_writes_summary():
plugin = Profiling(False)
plugin.profs = [sentinel.prof]
terminalreporter, stats = Mock(), Mock()
with patch('pstats.Stats', return_value=stats) as Stats:
plugin.pytest_sessionfinish(Mock(), Mock())
plugin.pytest_terminal_summary(terminalreporter)
assert 'Profiling' in terminalreporter.write.call_args[0][0]
assert Stats.called_with(stats, stream=terminalreporter)
def test_writes_summary_svg():
plugin = Profiling(True)
plugin.profs = [sentinel.prof]
terminalreporter = Mock()
with patch('pstats.Stats'):
with patch('pipes.Template'):
plugin.pytest_sessionfinish(Mock(), Mock())
plugin.pytest_terminal_summary(terminalreporter)
assert 'SVG' in terminalreporter.write.call_args[0][0]
def test_adds_options():
parser = Mock()
pytest_addoption(parser)
parser.getgroup.assert_called_with('Profiling')
group = parser.getgroup.return_value
group.addoption.assert_any_call('--profile', action='store_true', help=ANY)
group.addoption.assert_any_call('--profile-svg', action='store_true', help=ANY)
def test_configures():
config = Mock(getvalue=lambda x: x == 'profile')
with patch('pytest_profiling.Profiling') as Profiling:
pytest_configure(config)
config.pluginmanager.register.assert_called_with(Profiling.return_value)