【发布时间】:2020-11-30 03:18:18
【问题描述】:
如何将事件从 pytest 测试模块注入到正在运行的 pygame 中?
以下是一个 pygame 的最小示例,它在按下 J 时绘制一个白色矩形,并在按下 Ctrl-Q 时退出游戏。
#!/usr/bin/env python
"""minimal_pygame.py"""
import pygame
def minimal_pygame(testing: bool=False):
pygame.init()
game_window_sf = pygame.display.set_mode(
size=(400, 300),
)
pygame.display.flip()
game_running = True
while game_running:
# Main game loop:
# the following hook to inject events from pytest does not work:
# if testing:
# test_input = (yield)
# pygame.event.post(test_input)
for event in pygame.event.get():
# React to closing the pygame window:
if event.type == pygame.QUIT:
game_running = False
break
# React to keypresses:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
# distinguish between Q and Ctrl-Q
mods = pygame.key.get_mods()
# End main loop if Ctrl-Q was pressed
if mods & pygame.KMOD_CTRL:
game_running = False
break
# Draw a white square when key J is pressed:
if event.key == pygame.K_j:
filled_rect = game_window_sf.fill(pygame.Color("white"), pygame.Rect(50, 50, 50, 50))
pygame.display.update([filled_rect])
pygame.quit()
if __name__ == "__main__":
minimal_pygame()
我想编写一个pytest 模块来自动测试它。我有read 可以将事件注入到运行pygame 中。 Here 我读到yield from 允许双向通信,所以我认为我必须为从pytest 模块注入的pygame.events 实现某种钩子,但这并不像我想象的那么简单,所以我注释掉了。如果我取消注释while game_running 下的测试挂钩,pygame 甚至不会等待任何输入。
这里是 pytest 的测试模块:
#!/usr/bin/env python
"""test_minimal_pygame.py"""
import pygame
import minimal_pygame
def pygame_wrapper(coro):
yield from coro
def test_minimal_pygame():
wrap = pygame_wrapper(minimal_pygame.minimal_pygame(testing=True))
wrap.send(None) # prime the coroutine
test_press_j = pygame.event.Event(pygame.KEYDOWN, {"key": pygame.K_j})
for e in [test_press_j]:
wrap.send(e)
【问题讨论】: