如何从pytest测试模块向正在运行的pyplay注入事件?
下面是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
模块来自动测试它。我读到过,一个人可以在运行pyplay
时注入事件。在这里,我读到从
产生允许双向通信,所以我想我必须实现某种钩子,用于从pytest
模块注入的pygame.events
,但它并不简单正如我所想,所以我评论了它。如果我在下取消注释测试钩子,而game_running
,pyplay
甚至不等待任何输入。
下面是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)
PyGame可以响应自定义用户事件,而不是按键或鼠标事件。下面是一个工作代码,其中pytest
向pyplay
发送一个用户请求,pyplay
对此做出反应,并将响应发送回pytest
进行评估:
#!/usr/bin/env python
"""minimal_pygame.py"""
import pygame
TESTEVENT = pygame.event.custom_type()
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:
# Hook for testing
if testing:
attr_dict = (yield)
test_event = pygame.event.Event(TESTEVENT, attr_dict)
pygame.event.post(test_event)
# Main game loop:
pygame.time.wait(1000)
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
# React to TESTEVENTS:
if event.type == TESTEVENT:
if event.instruction == "draw_rectangle":
filled_rect = game_window_sf.fill(pygame.Color("white"), pygame.Rect(50, 50, 50, 50))
pygame.display.update([filled_rect])
pygame.time.wait(1000)
if testing:
# Yield the color value of the pixel at (50, 50) back to pytest
yield game_window_sf.get_at((50, 50))
pygame.quit()
if __name__ == "__main__":
minimal_pygame()
以下是测试代码:
#!/usr/bin/env python
"""test_minimal_pygame.py"""
import minimal_pygame
import 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
# Create a dictionary of attributes for the future TESTEVENT
attr_dict = {"instruction": "draw_rectangle"}
response = wrap.send(attr_dict)
assert response == pygame.Color("white")
但是,pytest
作为无状态单元测试而不是集成测试的工具,使得pyplay在得到第一个响应(拆卸测试)后退出。这是不可能继续和做更多的测试和断言在当前pyplay会话。(只要尝试复制测试代码的最后两行来重新发送事件,就会失败。)pytest不是一个合适的工具,它可以向pyplay注入一系列指令,使其达到一个先决条件,然后执行一系列测试。
这至少是我从pyplay不和谐频道的人那里听到的。对于自动化集成测试,他们建议使用像Cucumber(或python行为)这样的BDD工具。
主要内容:事件类型,事件处理方法,处理键盘事件,处理鼠标事件事件(Event)是 Pygame 的重要模块之一,它是构建整个游戏程序的核心,比如鼠标点击、键盘敲击、游戏窗口移动、调整窗口大小、触发特定的情节、退出游戏等等,这些都可以看做是“事件”,Pygame 会接受用户产生的各种操作(或事件),这些操作随时产生,并且操作量可大可小,那么 Pygame 是如何处理这些事件的呢? 事件类型 Pygame 定义了一个专门用来处理事件的结构,即事件队列,该结构遵
问题内容: 如何从用户进行pygame打印输入: 我试图让用户键入一些内容,然后pygame将其打印在屏幕上。 这是我当前的程序: 我想要这样,当用户点击Enter时,它将清空屏幕。 帮我! 问题答案: 这是一个示例脚本,可将输入切换到屏幕。它显示了如何在遍历pygame事件队列时修改字符串。每帧都将清除屏幕,并重建名称表面并使其变白。 这是要点版本
我对Spring交易非常陌生。由于我的组织使用的一些代码标准,我要求在调用任何方法时加入父事务(如果存在)。 我的应用程序是一个SpringMVC应用程序,有三层 Web层(控制器类) 服务层(包含业务逻辑的服务类) DAO Layer(数据库相关查询的DAO(数据访问层)类) 现在,在服务层上的一个方法中使用了dao层的三种不同方法。我使用@transactional将此服务方法注释为事务性的。
所以我正在用pygame做一个游戏,我也想用tkinter。我在tkinter窗口中嵌入了一个pygame窗口,但我似乎什么都做不了。 对于上下文,以下是完整的代码: 当我使用时,什么都不会发生。在类中使用pyplay是有效的,但是在我更复杂的游戏中,为所有变量使用self.variable似乎是不必要的。 如何在window类之外的pygame窗口中运行代码?
我正在做一个简单的pygame项目,它目前有从屏幕顶部落到屏幕底部的炸弹。如果玩家击中炸弹他们就会死。到现在为止一切正常。问题是当炸弹已经经过玩家,但还没有离开屏幕时,它仍然会杀死玩家。也就是说,炸弹将会通过玩家的下部,但如果你越过,在它越过屏幕的下部之前,你将会死亡。他是我的代码: 数值如下: player.rect.x的值范围为120到500,具体取决于播放机在屏幕上的位置。(当您移动时,屏幕
我正在测试一个(Eclipse 4)应用程序(我不是在谈论单元测试,而是更多的集成和系统测试)。 我有一个反复出现的问题需要解决。我必须将测试中的上下文“注入”(@inject)到被测试的类中。换句话说,我需要测试做应用程序通常做的事情。 我所做的是创建一个私有方法: 我(错误地)期望刚才在这里创建的上下文可以在测试中的一个类中使用。例如。: 肯定少了些什么!我也创建了activator(为简洁起