Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

""" generic mechanism for marking and selecting python functions. """ 

from __future__ import absolute_import 

from __future__ import division 

from __future__ import print_function 

 

from .legacy import matchkeyword 

from .legacy import matchmark 

from .structures import EMPTY_PARAMETERSET_OPTION 

from .structures import get_empty_parameterset_mark 

from .structures import Mark 

from .structures import MARK_GEN 

from .structures import MarkDecorator 

from .structures import MarkGenerator 

from .structures import ParameterSet 

from _pytest.config import UsageError 

 

__all__ = ["Mark", "MarkDecorator", "MarkGenerator", "get_empty_parameterset_mark"] 

 

 

def param(*values, **kw): 

"""Specify a parameter in `pytest.mark.parametrize`_ calls or 

:ref:`parametrized fixtures <fixture-parametrize-marks>`. 

 

.. code-block:: python 

 

@pytest.mark.parametrize("test_input,expected", [ 

("3+5", 8), 

pytest.param("6*9", 42, marks=pytest.mark.xfail), 

]) 

def test_eval(test_input, expected): 

assert eval(test_input) == expected 

 

:param values: variable args of the values of the parameter set, in order. 

:keyword marks: a single mark or a list of marks to be applied to this parameter set. 

:keyword str id: the id to attribute to this parameter set. 

""" 

return ParameterSet.param(*values, **kw) 

 

 

def pytest_addoption(parser): 

group = parser.getgroup("general") 

group._addoption( 

"-k", 

action="store", 

dest="keyword", 

default="", 

metavar="EXPRESSION", 

help="only run tests which match the given substring expression. " 

"An expression is a python evaluatable expression " 

"where all names are substring-matched against test names " 

"and their parent classes. Example: -k 'test_method or test_" 

"other' matches all test functions and classes whose name " 

"contains 'test_method' or 'test_other', while -k 'not test_method' " 

"matches those that don't contain 'test_method' in their names. " 

"Additionally keywords are matched to classes and functions " 

"containing extra names in their 'extra_keyword_matches' set, " 

"as well as functions which have names assigned directly to them.", 

) 

 

group._addoption( 

"-m", 

action="store", 

dest="markexpr", 

default="", 

metavar="MARKEXPR", 

help="only run tests matching given mark expression. " 

"example: -m 'mark1 and not mark2'.", 

) 

 

group.addoption( 

"--markers", 

action="store_true", 

help="show markers (builtin, plugin and per-project ones).", 

) 

 

parser.addini("markers", "markers for test functions", "linelist") 

parser.addini(EMPTY_PARAMETERSET_OPTION, "default marker for empty parametersets") 

 

 

def pytest_cmdline_main(config): 

import _pytest.config 

 

if config.option.markers: 

config._do_configure() 

tw = _pytest.config.create_terminal_writer(config) 

for line in config.getini("markers"): 

parts = line.split(":", 1) 

name = parts[0] 

rest = parts[1] if len(parts) == 2 else "" 

tw.write("@pytest.mark.%s:" % name, bold=True) 

tw.line(rest) 

tw.line() 

config._ensure_unconfigure() 

return 0 

 

 

pytest_cmdline_main.tryfirst = True 

 

 

def deselect_by_keyword(items, config): 

keywordexpr = config.option.keyword.lstrip() 

if keywordexpr.startswith("-"): 

keywordexpr = "not " + keywordexpr[1:] 

selectuntil = False 

if keywordexpr[-1:] == ":": 

selectuntil = True 

keywordexpr = keywordexpr[:-1] 

 

remaining = [] 

deselected = [] 

for colitem in items: 

if keywordexpr and not matchkeyword(colitem, keywordexpr): 

deselected.append(colitem) 

else: 

if selectuntil: 

keywordexpr = None 

remaining.append(colitem) 

 

if deselected: 

config.hook.pytest_deselected(items=deselected) 

items[:] = remaining 

 

 

def deselect_by_mark(items, config): 

matchexpr = config.option.markexpr 

if not matchexpr: 

return 

 

remaining = [] 

deselected = [] 

for item in items: 

if matchmark(item, matchexpr): 

remaining.append(item) 

else: 

deselected.append(item) 

 

if deselected: 

config.hook.pytest_deselected(items=deselected) 

items[:] = remaining 

 

 

def pytest_collection_modifyitems(items, config): 

deselect_by_keyword(items, config) 

deselect_by_mark(items, config) 

 

 

def pytest_configure(config): 

config._old_mark_config = MARK_GEN._config 

if config.option.strict: 

MARK_GEN._config = config 

 

empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION) 

 

if empty_parameterset not in ("skip", "xfail", "fail_at_collect", None, ""): 

raise UsageError( 

"{!s} must be one of skip, xfail or fail_at_collect" 

" but it is {!r}".format(EMPTY_PARAMETERSET_OPTION, empty_parameterset) 

) 

 

 

def pytest_unconfigure(config): 

MARK_GEN._config = getattr(config, "_old_mark_config", None)