or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

distribution-scheduling.mdhook-specifications.mdindex.mdloop-on-fail.mdplugin-configuration.mdsession-management.mdworker-detection.md

loop-on-fail.mddocs/

0

# Loop-on-Fail (Deprecated)

1

2

Legacy functionality for automatically re-running failed tests when files change. This feature is deprecated and will be removed in pytest-xdist 4.0.

3

4

**⚠️ DEPRECATION WARNING: The --looponfail command line argument and looponfailroots config variable are deprecated. The loop-on-fail feature will be removed in pytest-xdist 4.0.**

5

6

## Capabilities

7

8

### Loop-on-Fail Main Function

9

10

Entry point for loop-on-fail functionality that continuously monitors for file changes and re-runs failed tests.

11

12

```python { .api }

13

def pytest_cmdline_main(config: pytest.Config) -> int | None:

14

"""

15

Handle looponfail command line option.

16

17

Args:

18

config: pytest configuration object

19

20

Returns:

21

int: Exit code 2 for looponfail mode, None for normal processing

22

23

Raises:

24

pytest.UsageError: If --pdb is used with --looponfail (incompatible)

25

"""

26

27

def looponfail_main(config: pytest.Config) -> None:

28

"""

29

Main loop-on-fail functionality.

30

31

Continuously monitors files for changes and re-runs failed tests

32

until all tests pass or interrupted with Ctrl-C.

33

34

Args:

35

config: pytest configuration object

36

"""

37

```

38

39

### Remote Control

40

41

Controls remote test execution in a subprocess for loop-on-fail mode.

42

43

```python { .api }

44

class RemoteControl:

45

"""Controls remote test execution for loop-on-fail."""

46

47

def __init__(self, config: pytest.Config) -> None:

48

"""

49

Initialize remote control.

50

51

Args:

52

config: pytest configuration object

53

"""

54

55

def setup(self) -> None:

56

"""Set up remote worker session for test execution."""

57

58

def teardown(self) -> None:

59

"""Tear down remote worker session."""

60

61

def loop_once(self) -> None:

62

"""Execute one iteration of the test loop."""

63

```

64

65

### File System Monitoring

66

67

Monitors file system changes to trigger test re-runs.

68

69

```python { .api }

70

class StatRecorder:

71

"""Records and monitors file system changes."""

72

73

def __init__(self, rootdirs: Sequence[Path]) -> None:

74

"""

75

Initialize file system monitor.

76

77

Args:

78

rootdirs: directories to monitor for changes

79

"""

80

81

def waitonchange(self, checkinterval: float = 1.0) -> None:

82

"""

83

Wait for file system changes.

84

85

Args:

86

checkinterval: interval in seconds between checks

87

"""

88

```

89

90

### Configuration Options

91

92

Command line options for loop-on-fail functionality.

93

94

```python { .api }

95

def pytest_addoption(parser: pytest.Parser) -> None:

96

"""

97

Add looponfail command line option.

98

99

Adds the -f/--looponfail option to pytest's argument parser.

100

101

Args:

102

parser: pytest argument parser

103

"""

104

```

105

106

**Options:**

107

- `-f/--looponfail`: Run tests in subprocess, wait for file modifications, then re-run failing test set until all pass

108

109

**Configuration:**

110

- `looponfailroots`: List of directories to monitor for changes (ini file setting)

111

112

## Usage Examples

113

114

### Basic Loop-on-Fail Usage

115

116

```bash

117

# DEPRECATED - will be removed in pytest-xdist 4.0

118

pytest -f

119

120

# With specific directories to monitor

121

pytest -f --looponfailroots=src,tests

122

```

123

124

### Configuration File Setup

125

126

```ini

127

# In pytest.ini or tox.ini - DEPRECATED

128

[tool:pytest]

129

looponfailroots = src tests lib

130

```

131

132

### Programmatic Usage (Not Recommended)

133

134

```python

135

# DEPRECATED - for reference only

136

import pytest

137

from xdist.looponfail import looponfail_main

138

139

def run_loop_on_fail():

140

"""Example of programmatic loop-on-fail usage."""

141

# Create pytest config

142

config = pytest.Config()

143

config.option.looponfail = True

144

145

try:

146

looponfail_main(config)

147

except KeyboardInterrupt:

148

print("Loop-on-fail interrupted by user")

149

```

150

151

### Migration Path

152

153

Since loop-on-fail is deprecated, consider these alternatives:

154

155

#### Alternative 1: pytest-watch

156

157

```bash

158

# Install pytest-watch as replacement

159

pip install pytest-watch

160

161

# Use ptw instead of pytest -f

162

ptw --runner "pytest -x"

163

```

164

165

#### Alternative 2: File Watching Scripts

166

167

```python

168

# custom_watch.py - Simple replacement

169

import time

170

import subprocess

171

from watchdog.observers import Observer

172

from watchdog.events import FileSystemEventHandler

173

174

class TestRunner(FileSystemEventHandler):

175

def __init__(self):

176

self.last_run = 0

177

178

def on_modified(self, event):

179

if event.is_directory:

180

return

181

182

# Debounce rapid file changes

183

now = time.time()

184

if now - self.last_run < 2:

185

return

186

187

self.last_run = now

188

189

# Run tests

190

print(f"File {event.src_path} changed, running tests...")

191

result = subprocess.run(['pytest', '--tb=short'],

192

capture_output=True, text=True)

193

194

if result.returncode == 0:

195

print("All tests passed!")

196

else:

197

print("Tests failed, watching for changes...")

198

199

if __name__ == "__main__":

200

event_handler = TestRunner()

201

observer = Observer()

202

observer.schedule(event_handler, path='.', recursive=True)

203

observer.start()

204

205

try:

206

while True:

207

time.sleep(1)

208

except KeyboardInterrupt:

209

observer.stop()

210

observer.join()

211

```

212

213

#### Alternative 3: IDE Integration

214

215

Modern IDEs provide built-in test watching functionality:

216

217

```python

218

# VS Code with Python extension

219

# - Enable "python.testing.autoTestDiscoverOnSaveEnabled"

220

# - Use Test Explorer for continuous testing

221

222

# PyCharm Professional

223

# - Use "Run with Coverage" in continuous mode

224

# - Enable "Rerun tests automatically"

225

```

226

227

## Migration Guide

228

229

1. **Replace `-f/--looponfail`**:

230

```bash

231

# Old (deprecated)

232

pytest -f

233

234

# New alternatives

235

pip install pytest-watch

236

ptw --runner "pytest -x"

237

238

# Or use IDE integration

239

```

240

241

2. **Replace `looponfailroots` configuration**:

242

```bash

243

# Old pytest.ini

244

[tool:pytest]

245

looponfailroots = src tests

246

247

# New with pytest-watch

248

ptw --runner "pytest -x" src tests

249

```

250

251

3. **Update CI/CD pipelines**:

252

```yaml

253

# Remove looponfail from CI scripts

254

# It was never intended for CI use anyway

255

256

# Old

257

- run: pytest -f # Don't do this in CI

258

259

# Correct

260

- run: pytest # Standard test execution

261

```

262

263

4. **Development workflow adjustment**:

264

```bash

265

# Instead of pytest -f, use:

266

# Option 1: pytest-watch

267

ptw

268

269

# Option 2: IDE auto-test features

270

# Configure your IDE for automatic test execution

271

272

# Option 3: Custom file watching

273

# Implement custom solution using watchdog or similar

274

```