or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

assertions.mdconfiguration.mdfixtures.mdindex.mdmarks.mdreporting.mdtest-collection.mdtest-utilities.mdtesting-functions.mdwarnings.md

test-utilities.mddocs/

0

# Test Utilities and Environment Control

1

2

Utilities for controlling test environments including monkeypatching, output capture, temporary paths, and specialized tools for testing pytest plugins. These utilities provide comprehensive control over the test execution environment.

3

4

## Capabilities

5

6

### Environment Modification

7

8

MonkeyPatch provides safe, temporary modifications to objects, environment variables, and system paths.

9

10

```python { .api }

11

class MonkeyPatch:

12

"""Helper for temporarily modifying objects, environment, and sys.path."""

13

14

def setattr(self, target, name, value=<notset>, raising: bool = True) -> None:

15

"""Set attribute on target object."""

16

17

def setitem(self, dic, name, value) -> None:

18

"""Set dictionary item."""

19

20

def setenv(self, name: str, value: str, prepend: str | None = None) -> None:

21

"""Set environment variable."""

22

23

def syspath_prepend(self, path) -> None:

24

"""Prepend to sys.path."""

25

26

def chdir(self, path) -> None:

27

"""Change current working directory."""

28

29

def undo(self) -> None:

30

"""Undo all changes."""

31

```

32

33

**Usage Example:**

34

35

```python

36

def test_monkeypatch(monkeypatch):

37

# Modify object attribute

38

monkeypatch.setattr("os.getcwd", lambda: "/fake/path")

39

40

# Set environment variable

41

monkeypatch.setenv("TEST_MODE", "true")

42

43

# Modify dictionary

44

import sys

45

monkeypatch.setitem(sys.modules, "fake_module", FakeModule())

46

47

# Change directory

48

monkeypatch.chdir("/tmp")

49

50

# All changes are automatically undone after test

51

```

52

53

### Output Capture

54

55

Capture stdout, stderr, and file descriptor output during test execution.

56

57

```python { .api }

58

class CaptureFixture:

59

"""Captures stdout/stderr output during tests."""

60

61

def readouterr(self) -> CaptureResult:

62

"""Read and return captured output."""

63

64

def disabled(self):

65

"""Context manager to temporarily disable capturing."""

66

67

class CaptureResult:

68

"""Result of captured output."""

69

out: str # Captured stdout

70

err: str # Captured stderr

71

```

72

73

**Usage Example:**

74

75

```python

76

def test_output_capture(capsys):

77

print("Hello stdout")

78

print("Hello stderr", file=sys.stderr)

79

80

captured = capsys.readouterr()

81

assert captured.out == "Hello stdout\\n"

82

assert captured.err == "Hello stderr\\n"

83

84

# Temporarily disable capture

85

with capsys.disabled():

86

print("This will be printed normally")

87

88

# Different capture fixtures available:

89

def test_capture_variants(capsys, capsysbinary, capfd, capfdbinary):

90

# capsys: capture sys.stdout/stderr (text)

91

# capsysbinary: capture sys.stdout/stderr (binary)

92

# capfd: capture file descriptors 1/2 (text)

93

# capfdbinary: capture file descriptors 1/2 (binary)

94

pass

95

```

96

97

### Log Capture

98

99

Capture and inspect log messages during test execution.

100

101

```python { .api }

102

class LogCaptureFixture:

103

"""Provides access and control of log capturing."""

104

105

# Attributes

106

handler: LogCaptureHandler # Log handler

107

records: list[logging.LogRecord] # Captured log records

108

109

def get_records(self, when: str) -> list[logging.LogRecord]:

110

"""Get log records for specific test phase."""

111

112

def clear(self) -> None:

113

"""Clear captured records."""

114

115

def set_level(self, level: int | str, logger: str | None = None) -> None:

116

"""Set logging level."""

117

```

118

119

**Usage Example:**

120

121

```python

122

import logging

123

124

def test_logging(caplog):

125

with caplog.at_level(logging.INFO):

126

logging.info("This is an info message")

127

logging.warning("This is a warning")

128

129

assert len(caplog.records) == 2

130

assert caplog.records[0].levelname == "INFO"

131

assert "info message" in caplog.records[0].message

132

133

# Clear records

134

caplog.clear()

135

assert len(caplog.records) == 0

136

137

# Check specific logger

138

logger = logging.getLogger("myapp")

139

logger.error("Application error")

140

141

assert any("Application error" in record.message

142

for record in caplog.records)

143

```

144

145

### Temporary Paths

146

147

Factory for creating temporary directories and files.

148

149

```python { .api }

150

class TempPathFactory:

151

"""Factory for creating temporary directories."""

152

153

def mktemp(self, basename: str, numbered: bool = True) -> Path:

154

"""Create temporary directory."""

155

156

def getbasetemp(self) -> Path:

157

"""Get base temporary directory."""

158

159

# Built-in fixtures

160

def test_temp_paths(tmp_path, tmp_path_factory):

161

# tmp_path: pathlib.Path to temporary directory (function scope)

162

# tmp_path_factory: TempPathFactory instance

163

164

# Create file in temporary directory

165

file_path = tmp_path / "test_file.txt"

166

file_path.write_text("test content")

167

assert file_path.read_text() == "test content"

168

169

# Create additional temp directory

170

another_temp = tmp_path_factory.mktemp("custom_dir")

171

assert another_temp.exists()

172

```

173

174

### Plugin Testing Framework

175

176

Comprehensive tools for testing pytest plugins and functionality.

177

178

```python { .api }

179

class Pytester:

180

"""Facilities for testing pytest plugins and functionality."""

181

182

def makepyfile(self, **kwargs) -> Path:

183

"""Create Python file with content."""

184

185

def makeconftest(self, source: str) -> Path:

186

"""Create conftest.py file."""

187

188

def makefile(self, ext: str, **kwargs) -> Path:

189

"""Create file with given extension."""

190

191

def mkdir(self, name: str) -> Path:

192

"""Create directory."""

193

194

def runpytest(self, *args, **kwargs) -> RunResult:

195

"""Run pytest in subprocess."""

196

197

def runpytest_subprocess(self, *args, **kwargs) -> RunResult:

198

"""Run pytest in subprocess with isolation."""

199

200

def runpytest_inprocess(self, *args, **kwargs) -> RunResult:

201

"""Run pytest in same process."""

202

203

class RunResult:

204

"""Result of running pytest in subprocess."""

205

206

# Attributes

207

ret: int # Return code

208

outlines: list[str] # stdout lines

209

errlines: list[str] # stderr lines

210

stdout: str # Full stdout

211

stderr: str # Full stderr

212

duration: float # Execution duration

213

214

def parseoutcomes(self) -> dict[str, int]:

215

"""Parse test outcomes from output."""

216

217

def assert_outcomes(self, **expected) -> None:

218

\"\"\"Assert expected test outcomes.\"\"\"\n\nclass HookRecorder:\n \"\"\"Records hook calls for testing.\"\"\"\n \n def getcalls(self, names: str | list[str]) -> list[RecordedHookCall]:\n \"\"\"Get recorded calls for hook names.\"\"\"\n \n def assert_contains(self, entries) -> None:\n \"\"\"Assert recorder contains specific entries.\"\"\"\n \n def pop(self, name: str) -> RecordedHookCall:\n \"\"\"Remove and return last call for hook name.\"\"\"\n\nclass RecordedHookCall:\n \"\"\"Represents a recorded hook call.\"\"\"\n pass\n\nclass LineMatcher:\n \"\"\"Flexible matching of text output lines.\"\"\"\n \n def fnmatch_lines(self, lines2: list[str]) -> None:\n \"\"\"Assert lines match using fnmatch patterns.\"\"\"\n \n def re_match_lines(self, lines2: list[str]) -> None:\n \"\"\"Assert lines match using regex patterns.\"\"\"\n \n def no_fnmatch_line(self, pat: str) -> None:\n \"\"\"Assert no line matches fnmatch pattern.\"\"\"\n```\n\n**Usage Example:**\n\n```python\ndef test_my_plugin(pytester):\n # Create test files\n pytester.makepyfile(\"\"\"\n def test_example():\n assert True\n \"\"\")\n \n pytester.makeconftest(\"\"\"\n import pytest\n \n @pytest.fixture\n def my_fixture():\n return \"test_value\"\n \"\"\")\n \n # Run pytest\n result = pytester.runpytest(\"-v\")\n \n # Check results\n result.assert_outcomes(passed=1)\n assert result.ret == 0\n \n # Check output\n result.stdout.fnmatch_lines([\n \"*test_example PASSED*\"\n ])\n\ndef test_hook_recording(pytester):\n pytester.makepyfile(\"\"\"\n def test_foo(): pass\n \"\"\")\n \n # Record hooks\n rec = pytester.runpytest(\"--collect-only\")\n \n # Check hook calls\n calls = rec.getcalls(\"pytest_collection_modifyitems\")\n assert len(calls) == 1\n```\n\n### Legacy Path Support (Deprecated)\n\nLegacy support for py.path and testdir (deprecated in favor of pathlib.Path).\n\n```python { .api }\nclass TempdirFactory:\n \"\"\"Legacy factory for temporary directories (deprecated).\"\"\"\n pass\n\nclass Testdir:\n \"\"\"Legacy test directory helper (deprecated).\"\"\"\n pass\n```\n\n## Built-in Utility Fixtures\n\nSummary of built-in fixtures for test utilities:\n\n```python\ndef test_with_all_utilities(\n monkeypatch, # MonkeyPatch instance\n capsys, # Capture sys.stdout/stderr (text)\n capsysbinary, # Capture sys.stdout/stderr (binary)\n capfd, # Capture file descriptors (text)\n capfdbinary, # Capture file descriptors (binary) \n caplog, # LogCaptureFixture instance\n tmp_path, # pathlib.Path to temp directory\n tmp_path_factory, # TempPathFactory instance\n pytester, # Pytester instance (for plugin testing)\n recwarn, # WarningsRecorder instance\n # Legacy (deprecated)\n tmpdir, # py.path.local temp directory\n tmpdir_factory, # TempdirFactory instance\n testdir # Testdir instance\n):\n pass\n```