pytestplugin.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. # coding=utf-8
  2. #
  3. # This file is part of Hypothesis, which may be found at
  4. # https://github.com/HypothesisWorks/hypothesis-python
  5. #
  6. # Most of this work is copyright (C) 2013-2018 David R. MacIver
  7. # (david@drmaciver.com), but it contains contributions by others. See
  8. # CONTRIBUTING.rst for a full list of people who may hold copyright, and
  9. # consult the git log if you need to determine who owns an individual
  10. # contribution.
  11. #
  12. # This Source Code Form is subject to the terms of the Mozilla Public License,
  13. # v. 2.0. If a copy of the MPL was not distributed with this file, You can
  14. # obtain one at http://mozilla.org/MPL/2.0/.
  15. #
  16. # END HEADER
  17. from __future__ import division, print_function, absolute_import
  18. import pytest
  19. import hypothesis.core as core
  20. from hypothesis.reporting import default as default_reporter
  21. from hypothesis.reporting import with_reporter
  22. from hypothesis.statistics import collector
  23. from hypothesis.internal.compat import OrderedDict, text_type
  24. from hypothesis.internal.detection import is_hypothesis_test
  25. LOAD_PROFILE_OPTION = '--hypothesis-profile'
  26. PRINT_STATISTICS_OPTION = '--hypothesis-show-statistics'
  27. SEED_OPTION = '--hypothesis-seed'
  28. class StoringReporter(object):
  29. def __init__(self, config):
  30. self.config = config
  31. self.results = []
  32. def __call__(self, msg):
  33. if self.config.getoption('capture', 'fd') == 'no':
  34. default_reporter(msg)
  35. if not isinstance(msg, text_type):
  36. msg = repr(msg)
  37. self.results.append(msg)
  38. def pytest_addoption(parser):
  39. group = parser.getgroup('hypothesis', 'Hypothesis')
  40. group.addoption(
  41. LOAD_PROFILE_OPTION,
  42. action='store',
  43. help='Load in a registered hypothesis.settings profile'
  44. )
  45. group.addoption(
  46. PRINT_STATISTICS_OPTION,
  47. action='store_true',
  48. help='Configure when statistics are printed',
  49. default=False
  50. )
  51. group.addoption(
  52. SEED_OPTION,
  53. action='store',
  54. help='Set a seed to use for all Hypothesis tests'
  55. )
  56. def pytest_configure(config):
  57. core.running_under_pytest = True
  58. from hypothesis import settings
  59. profile = config.getoption(LOAD_PROFILE_OPTION)
  60. if profile:
  61. settings.load_profile(profile)
  62. seed = config.getoption(SEED_OPTION)
  63. if seed is not None:
  64. try:
  65. seed = int(seed)
  66. except ValueError:
  67. pass
  68. core.global_force_seed = seed
  69. config.addinivalue_line(
  70. 'markers',
  71. 'hypothesis: Tests which use hypothesis.')
  72. gathered_statistics = OrderedDict()
  73. @pytest.mark.hookwrapper
  74. def pytest_runtest_call(item):
  75. if not (hasattr(item, 'obj') and is_hypothesis_test(item.obj)):
  76. yield
  77. else:
  78. store = StoringReporter(item.config)
  79. def note_statistics(stats):
  80. gathered_statistics[item.nodeid] = stats
  81. with collector.with_value(note_statistics):
  82. with with_reporter(store):
  83. yield
  84. if store.results:
  85. item.hypothesis_report_information = list(store.results)
  86. @pytest.mark.hookwrapper
  87. def pytest_runtest_makereport(item, call):
  88. report = (yield).get_result()
  89. if hasattr(item, 'hypothesis_report_information'):
  90. report.sections.append((
  91. 'Hypothesis',
  92. '\n'.join(item.hypothesis_report_information)
  93. ))
  94. def pytest_terminal_summary(terminalreporter):
  95. if not terminalreporter.config.getoption(PRINT_STATISTICS_OPTION):
  96. return
  97. terminalreporter.section('Hypothesis Statistics')
  98. for name, statistics in gathered_statistics.items():
  99. terminalreporter.write_line(name + ':')
  100. terminalreporter.write_line('')
  101. if not statistics.has_runs:
  102. terminalreporter.write_line(' - Test was never run')
  103. continue
  104. terminalreporter.write_line((
  105. ' - %d passing examples, %d failing examples,'
  106. ' %d invalid examples') % (
  107. statistics.passing_examples, statistics.failing_examples,
  108. statistics.invalid_examples,
  109. ))
  110. terminalreporter.write_line(
  111. ' - Typical runtimes: %s' % (statistics.runtimes,)
  112. )
  113. terminalreporter.write_line(
  114. ' - Fraction of time spent in data generation: %s' % (
  115. statistics.draw_time_percentage,))
  116. terminalreporter.write_line(
  117. ' - Stopped because %s' % (statistics.exit_reason,)
  118. )
  119. if statistics.events:
  120. terminalreporter.write_line(' - Events:')
  121. for event in statistics.events:
  122. terminalreporter.write_line(
  123. ' * %s' % (event,)
  124. )
  125. terminalreporter.write_line('')
  126. def pytest_collection_modifyitems(items):
  127. for item in items:
  128. if not isinstance(item, pytest.Function):
  129. continue
  130. if getattr(item.function, 'is_hypothesis_test', False):
  131. item.add_marker('hypothesis')
  132. def load():
  133. pass