Skip to content

Commit ef29f21

Browse files
committed
new test that plays the game with random inputs. Kind of crazy
1 parent 93cf8ce commit ef29f21

File tree

3 files changed

+124
-2
lines changed

3 files changed

+124
-2
lines changed

poetry.lock

+16-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ ansimarkup = "^2.1.0"
1414
pytest = "^7.4.3"
1515
grandalf = "^0.8"
1616
pyinstaller = "^6.3.0"
17+
pytest-timeout = "^2.3.1"
1718

1819
[tool.poetry.group.dev.dependencies]
1920
pytest-watch = "^4.2.0"

tests/test_game.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from __future__ import annotations
2+
3+
import random
4+
5+
import pytest
6+
7+
import entities
8+
import game
9+
import helper
10+
import shop
11+
from ansi_tags import ansiprint
12+
from entities import CardType
13+
import time
14+
15+
16+
def replacement_clear_screen():
17+
'''Replacement for game.view.clear() so that I can see the test output'''
18+
print("\n--------------------------\n")
19+
20+
21+
def repeat_check(repeat_catcher, last_return, current_return) -> tuple[int, bool]:
22+
'''Check if the player is stuck in a loop
23+
'''
24+
if last_return == current_return:
25+
repeat_catcher += 1
26+
else:
27+
repeat_catcher = 0
28+
if repeat_catcher > 3:
29+
print("Player is stuck in a loop")
30+
return repeat_catcher, True
31+
return repeat_catcher, False
32+
33+
@pytest.mark.timeout(30)
34+
@pytest.mark.parametrize("seed", list(range(10)))
35+
def test_e2e(seed, monkeypatch):
36+
'''Test the game from start to finish
37+
Plays with (more or less) random inputs to test the game.
38+
Seems to find lots of bugs, but very hard to repeat.
39+
'''
40+
ansiprint(f"<red><bold>Seed for this run is: {seed}</bold></red>")
41+
mygame = game.Game(seed=seed)
42+
repeat_catcher = 0
43+
last_return = None
44+
def patched_input(*args, **kwargs):
45+
'''Patch for input that can play the game!
46+
'''
47+
nonlocal mygame
48+
nonlocal repeat_catcher
49+
nonlocal last_return
50+
random_return = random.choice(
51+
['1', '2', '3', '4', '5', '6', '7', '8', '9', 'e',
52+
'p', 'm', 'd', 'a', 's', 'x', 'f', 'y', 'n',
53+
'rest', 'smith', 'view deck', 'leave', 'exit', 'lift', 'toke', 'dig'])
54+
player = mygame.player
55+
if player.state == entities.State.DEAD:
56+
return '\n'
57+
if args and "Choose" in args[0]:
58+
choice = random.randint(1, 10)
59+
print(f"Player chose {choice}")
60+
return str(choice)
61+
possible_cards = [card for card in player.hand if card.energy_cost <= player.energy and card.type != CardType.STATUS]
62+
if len(possible_cards) > 0:
63+
ret = str(random.randint(1, len(possible_cards)))
64+
repeat_catcher, check = repeat_check(repeat_catcher, last_return, ret)
65+
if not check:
66+
last_return = ret
67+
print(f"Player chose {ret}")
68+
return ret
69+
else:
70+
print(f"Player chose {random_return}")
71+
last_return = random_return
72+
return random_return
73+
74+
if player.energy == 0 and player.in_combat:
75+
print("Player has no energy left.")
76+
# from pprint import pprint
77+
# pprint(player.__dict__)
78+
repeat_catcher, check = repeat_check(repeat_catcher, last_return, 'e')
79+
if not check:
80+
last_return = 'e'
81+
print("Player chose 'e'")
82+
return 'e'
83+
else:
84+
last_return = random_return
85+
print(f"Player chose {random_return}")
86+
return random_return
87+
88+
# Default to picking randomly
89+
print(f"Player chose {random_return}")
90+
return random_return
91+
92+
with monkeypatch.context() as m:
93+
m.setattr('builtins.input', patched_input)
94+
m.setattr(helper, 'sleep', lambda x: None)
95+
m.setattr(entities, 'sleep', lambda x: None)
96+
m.setattr(game, 'sleep', lambda x: None)
97+
helper.view.clear = replacement_clear_screen
98+
try:
99+
start = time.time()
100+
mygame.start()
101+
except Exception as e:
102+
ansiprint(f"<red><bold>Failed with seed: {seed}</bold></red>")
103+
raise e
104+
finally:
105+
end = time.time()
106+
ansiprint(f"\n\n<green><bold>Game took {end - start:.2f} seconds</bold></green>")
107+

0 commit comments

Comments
 (0)