or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

date-time-components.mddatetime-operations.mdduration-intervals.mdformatting-localization.mdindex.mdtesting-utilities.mdtimezone-management.md

testing-utilities.mddocs/

0

# Testing Utilities

1

2

Time manipulation utilities for deterministic testing. Pendulum provides comprehensive testing support including freezing time, traveling to specific moments, and managing time flow for reproducible tests.

3

4

## Capabilities

5

6

### Time Freezing

7

8

Functions for freezing time at specific moments for deterministic testing.

9

10

```python { .api }

11

def freeze() -> None:

12

"""

13

Freeze time at current moment.

14

15

All subsequent calls to now(), today(), etc. will return the same time

16

until travel_back() is called or time is unfrozen.

17

"""

18

19

def freeze(dt: DateTime) -> None:

20

"""

21

Freeze time at specific DateTime.

22

23

Parameters:

24

- dt: DateTime to freeze time at

25

"""

26

```

27

28

### Time Travel

29

30

Functions for moving through time during tests.

31

32

```python { .api }

33

def travel(

34

years: int = 0,

35

months: int = 0,

36

weeks: int = 0,

37

days: int = 0,

38

hours: int = 0,

39

minutes: int = 0,

40

seconds: int = 0,

41

microseconds: int = 0

42

) -> None:

43

"""

44

Travel forward or backward in time by specified duration.

45

46

Parameters:

47

- years: Years to travel (positive for future, negative for past)

48

- months: Months to travel

49

- weeks: Weeks to travel

50

- days: Days to travel

51

- hours: Hours to travel

52

- minutes: Minutes to travel

53

- seconds: Seconds to travel

54

- microseconds: Microseconds to travel

55

56

Note: Time continues to flow normally after traveling

57

"""

58

59

def travel_to(dt: DateTime, freeze: bool = False) -> None:

60

"""

61

Travel to specific DateTime.

62

63

Parameters:

64

- dt: Target DateTime to travel to

65

- freeze: Whether to freeze time at the target DateTime

66

"""

67

68

def travel_back() -> None:

69

"""

70

Return to real time.

71

72

Unfreezes time and restores normal time flow.

73

"""

74

```

75

76

### Traveller Class

77

78

The underlying time manipulation class that provides testing functionality.

79

80

```python { .api }

81

class Traveller:

82

def __init__(self, datetime_class: type[DateTime]):

83

"""

84

Initialize Traveller for specific DateTime class.

85

86

Parameters:

87

- datetime_class: DateTime class to control

88

"""

89

90

def freeze(self, dt: DateTime | None = None) -> None:

91

"""

92

Freeze time at specific DateTime or current time.

93

94

Parameters:

95

- dt: DateTime to freeze at (None for current time)

96

"""

97

98

def travel(

99

self,

100

years: int = 0,

101

months: int = 0,

102

weeks: int = 0,

103

days: int = 0,

104

hours: int = 0,

105

minutes: int = 0,

106

seconds: int = 0,

107

microseconds: int = 0

108

) -> None:

109

"""Travel by specified duration"""

110

111

def travel_to(self, dt: DateTime, freeze: bool = False) -> None:

112

"""Travel to specific DateTime"""

113

114

def travel_back(self) -> None:

115

"""Return to real time"""

116

```

117

118

## Usage Examples

119

120

### Basic Time Freezing

121

122

```python

123

import pendulum

124

import time

125

126

# Freeze time at current moment

127

print("Before freeze:", pendulum.now())

128

pendulum.freeze()

129

130

# Time is now frozen

131

time.sleep(2) # Wait 2 seconds

132

print("After 2 seconds:", pendulum.now()) # Same time as before

133

134

# All time functions return frozen time

135

print("Today:", pendulum.today())

136

print("Now:", pendulum.now())

137

print("Now UTC:", pendulum.now('UTC'))

138

139

# Unfreeze time

140

pendulum.travel_back()

141

print("After unfreeze:", pendulum.now()) # Real current time

142

```

143

144

### Freezing at Specific Time

145

146

```python

147

import pendulum

148

149

# Freeze at specific date/time

150

target_dt = pendulum.datetime(2024, 12, 25, 10, 30, 0, tz='UTC')

151

pendulum.freeze(target_dt)

152

153

print("Frozen at:", pendulum.now()) # 2024-12-25T10:30:00+00:00

154

print("Today:", pendulum.today()) # 2024-12-25T00:00:00+00:00

155

156

# All timezone-aware functions work with frozen time

157

print("Paris time:", pendulum.now('Europe/Paris'))

158

print("Tokyo time:", pendulum.now('Asia/Tokyo'))

159

160

pendulum.travel_back()

161

```

162

163

### Time Travel

164

165

```python

166

import pendulum

167

168

print("Real time:", pendulum.now())

169

170

# Travel to the future

171

pendulum.travel(days=7, hours=3)

172

print("Future time:", pendulum.now()) # 7 days and 3 hours later

173

174

# Travel to the past

175

pendulum.travel(days=-14) # 14 days ago from current position

176

print("Past time:", pendulum.now())

177

178

# Travel back to real time

179

pendulum.travel_back()

180

print("Back to real time:", pendulum.now())

181

```

182

183

### Travel to Specific DateTime

184

185

```python

186

import pendulum

187

188

# Travel to specific moment

189

birthday = pendulum.datetime(2024, 6, 15, 12, 0, 0)

190

pendulum.travel_to(birthday)

191

192

print("Traveled to:", pendulum.now())

193

print("Is birthday:", pendulum.now().format('MMMM Do, YYYY'))

194

195

# Travel and freeze

196

new_year = pendulum.datetime(2025, 1, 1, 0, 0, 0)

197

pendulum.travel_to(new_year, freeze=True)

198

199

print("New Year (frozen):", pendulum.now())

200

# Time is now frozen at New Year

201

202

pendulum.travel_back()

203

```

204

205

### Testing Date-Dependent Code

206

207

```python

208

import pendulum

209

210

def get_age(birth_date):

211

"""Calculate age based on current date"""

212

today = pendulum.today()

213

return today.year - birth_date.year - (

214

(today.month, today.day) < (birth_date.month, birth_date.day)

215

)

216

217

# Test age calculation

218

birth_date = pendulum.date(1990, 3, 15)

219

220

# Test before birthday in 2024

221

pendulum.travel_to(pendulum.datetime(2024, 3, 10))

222

age_before = get_age(birth_date)

223

print(f"Age before birthday: {age_before}") # 33

224

225

# Test after birthday in 2024

226

pendulum.travel_to(pendulum.datetime(2024, 3, 20))

227

age_after = get_age(birth_date)

228

print(f"Age after birthday: {age_after}") # 34

229

230

pendulum.travel_back()

231

```

232

233

### Testing Time-Sensitive Operations

234

235

```python

236

import pendulum

237

238

def is_business_hours():

239

"""Check if current time is during business hours (9 AM - 5 PM, Mon-Fri)"""

240

now = pendulum.now('America/New_York')

241

242

# Check if weekday (Monday=0, Friday=4)

243

if now.day_of_week > 4: # Saturday=5, Sunday=6

244

return False

245

246

# Check if between 9 AM and 5 PM

247

return 9 <= now.hour < 17

248

249

# Test during business hours

250

business_time = pendulum.datetime(2024, 3, 15, 14, 30, tz='America/New_York') # Friday 2:30 PM

251

pendulum.travel_to(business_time)

252

print(f"Business hours: {is_business_hours()}") # True

253

254

# Test outside business hours

255

weekend_time = pendulum.datetime(2024, 3, 16, 14, 30, tz='America/New_York') # Saturday 2:30 PM

256

pendulum.travel_to(weekend_time)

257

print(f"Weekend: {is_business_hours()}") # False

258

259

# Test after hours

260

evening_time = pendulum.datetime(2024, 3, 15, 18, 30, tz='America/New_York') # Friday 6:30 PM

261

pendulum.travel_to(evening_time)

262

print(f"After hours: {is_business_hours()}") # False

263

264

pendulum.travel_back()

265

```

266

267

### Testing with Context Managers

268

269

```python

270

import pendulum

271

from contextlib import contextmanager

272

273

@contextmanager

274

def frozen_time(dt):

275

"""Context manager for temporarily freezing time"""

276

pendulum.freeze(dt)

277

try:

278

yield

279

finally:

280

pendulum.travel_back()

281

282

@contextmanager

283

def time_travel(dt):

284

"""Context manager for temporarily traveling to specific time"""

285

pendulum.travel_to(dt)

286

try:

287

yield

288

finally:

289

pendulum.travel_back()

290

291

# Use with context managers

292

test_time = pendulum.datetime(2024, 7, 4, 12, 0, 0)

293

294

with frozen_time(test_time):

295

print("Inside frozen context:", pendulum.now())

296

# Time is frozen at test_time

297

298

print("Outside context:", pendulum.now()) # Real time

299

300

with time_travel(test_time):

301

print("Inside travel context:", pendulum.now())

302

# Time continues flowing from test_time

303

304

print("Back to real time:", pendulum.now())

305

```

306

307

### Testing Date Arithmetic

308

309

```python

310

import pendulum

311

312

def days_until_next_friday():

313

"""Calculate days until next Friday"""

314

today = pendulum.today()

315

days_ahead = 4 - today.day_of_week # Friday is day 4

316

if days_ahead <= 0: # Today is Friday or later

317

days_ahead += 7

318

return days_ahead

319

320

# Test from different days of the week

321

test_cases = [

322

("Monday", pendulum.date(2024, 3, 11)), # Monday

323

("Wednesday", pendulum.date(2024, 3, 13)), # Wednesday

324

("Friday", pendulum.date(2024, 3, 15)), # Friday

325

("Sunday", pendulum.date(2024, 3, 17)), # Sunday

326

]

327

328

for day_name, test_date in test_cases:

329

pendulum.travel_to(pendulum.datetime(test_date.year, test_date.month, test_date.day))

330

days = days_until_next_friday()

331

print(f"{day_name}: {days} days until Friday")

332

333

pendulum.travel_back()

334

```

335

336

### Testing Timezone-Dependent Code

337

338

```python

339

import pendulum

340

341

def get_market_status():

342

"""Get stock market status based on NYC time"""

343

ny_time = pendulum.now('America/New_York')

344

345

# Market closed on weekends

346

if ny_time.day_of_week > 4:

347

return "Closed (Weekend)"

348

349

# Market hours: 9:30 AM - 4:00 PM EST/EDT

350

if ny_time.time() < pendulum.time(9, 30):

351

return "Pre-market"

352

elif ny_time.time() < pendulum.time(16, 0):

353

return "Open"

354

else:

355

return "After-hours"

356

357

# Test during different times

358

test_times = [

359

("Pre-market", pendulum.datetime(2024, 3, 15, 8, 0, tz='America/New_York')),

360

("Market open", pendulum.datetime(2024, 3, 15, 12, 0, tz='America/New_York')),

361

("After hours", pendulum.datetime(2024, 3, 15, 18, 0, tz='America/New_York')),

362

("Weekend", pendulum.datetime(2024, 3, 16, 12, 0, tz='America/New_York')),

363

]

364

365

for description, test_time in test_times:

366

pendulum.travel_to(test_time)

367

status = get_market_status()

368

print(f"{description}: {status}")

369

370

pendulum.travel_back()

371

```

372

373

### Unit Testing Integration

374

375

```python

376

import pendulum

377

import unittest

378

379

class TestTimeDependent(unittest.TestCase):

380

def setUp(self):

381

"""Set up test with known time"""

382

self.test_time = pendulum.datetime(2024, 3, 15, 10, 30, 0)

383

pendulum.freeze(self.test_time)

384

385

def tearDown(self):

386

"""Restore real time after each test"""

387

pendulum.travel_back()

388

389

def test_current_time(self):

390

"""Test that time is frozen during test"""

391

now1 = pendulum.now()

392

now2 = pendulum.now()

393

self.assertEqual(now1, now2)

394

self.assertEqual(now1, self.test_time)

395

396

def test_date_calculation(self):

397

"""Test date calculations with frozen time"""

398

today = pendulum.today()

399

expected = pendulum.date(2024, 3, 15)

400

self.assertEqual(today.date(), expected)

401

402

tomorrow = today.add(days=1)

403

expected_tomorrow = pendulum.date(2024, 3, 16)

404

self.assertEqual(tomorrow.date(), expected_tomorrow)

405

406

# Running the tests would work with frozen time

407

```