我正在制作一个超级简单和哑巴的终端文字游戏,以尝试统一测试在蟒蛇。我遇到了一个问题。当我运行测试时,游戏循环被运行,我必须手动插入输入才能继续测试。
在我运行测试时,是否有一种方法可以不运行游戏循环,以便只测试类方法?
任何其他关于代码的建议也将是有帮助的。
游戏概念:玩家被提示建立,收集,招募,或攻击每一个回合,当某人的城堡生命值是<= 0,游戏结束。
import os, random
class Player():
def __init__(self):
self.castle = 1
self.villagers = 1
self.warriors = 0
self.food = 0
self.stone = 0
def takeTurn(self):
action = 0
action = int(input("1) Build\n2) Gather\n3) Recruit\n4) Attack\n"))
if action == 1:
self.build()
elif action == 2:
self.gather()
elif action == 3:
self.recruit()
elif action == 4:
self.attack()
else:
self.takeTurn()
def build(self):
if self.stone >= 1:
self.castle += 1
self.stone -= 1
else:
os.system('clear')
if self.__class__.__name__ == "Player":
print("You don't have enough stone!\n")
printMenu()
self.takeTurn()
def gather(self):
self.food += self.villagers
self.stone += self.villagers
def recruit(self):
if self.food >= 1:
self.warriors += 1
self.food -= 1
else:
os.system('clear')
if self.__class__.__name__ == "Player":
print("You don't have enough food!\n")
printMenu()
self.takeTurn()
def attack(self):
if self.warriors >= 1:
if self.__class__.__name__ == "Player":
ai.castle -= self.warriors
elif self.__class__.__name__ == "AI":
player.castle -= self.warriors
class AI(Player):
def __init__(self):
super().__init__()
def makeMove(self):
action = 0
# Win if player castle weak
if player.castle == self.warriors:
player.castle -= self.warriors
# Build if castle weak
elif self.castle == player.warriors:
if self.stone >= 1:
self.castle += 1
else:
action = random.randint(2, 4)
else:
action = random.randint(1, 4)
if action == 1:
super().build()
if action == 2:
super().gather()
if action == 3:
super().recruit()
if action == 4:
super().attack()
player = Player()
ai = AI()
def printMenu():
print("You:\nCastle: " + str(player.castle) + " Food: " + str(player.food) + " Stone: " + str(player.stone) + " Villagers: " + str(player.villagers) + " Warriors: " + str(player.warriors) + "\n")
print("Computer:\nCastle: " + str(ai.castle) + " Food: " + str(ai.food) + " Stone: " + str(ai.stone) + " Villagers: " + str(ai.villagers) + " Warriors: " + str(ai.warriors) + "\n")
def gameLoop():
# MAIN LOOP
playing = False
if playing:
printMenu()
player.takeTurn()
ai.makeMove()
if ai.castle <= 0:
playing = False
print("You Win!\n")
elif player.castle <= 0:
playing = False
print("You Lose!")
else:
os.system('clear')
gameLoop()import unittest
from game.main import Player
class TestPlayer(unittest.TestCase):
def setUp(self):
self.player = Player()
def test_build(self):
# Should fail
self.player.castle = 2
self.player.stone = 1
self.player.build()
self.assertEqual(self.player.castle, 1)
if __name__ == '__main__':
unittest.main()发布于 2020-03-26 18:28:06
您已经在评论中给出了您的"bug“的答案,但我将尝试给您一个更深入的回顾。不过,我将重复前面提到的解决方案:避免程序在导入时自动运行,但您的主要调用在if __name__ == "__main__"中(如果有兴趣,请阅读更多的这里 )。
对于您的__init__方法,将您的方法初始化器作为(默认)参数会随着项目的发展而提供更大的灵活性:
def __init__(self, castle=1, villagers=1, warriors=0, food=0, stone=0):
self.castle = castle
self.villagers = villagers
self.warriors = warriors
self.food = food
self.stone = stone对于第一个真正的方法,我建议您继续使用snake_case over camelCase的Python标准。此外,将变量action初始化为0实际上并没有起到任何作用,因为您在下面的行中覆盖了它。而且,由于您依赖于这个输入,所以我认为,当您没有得到一个int时,或者如果您得到类似于11的东西,您应该知道该做什么(考虑到选项,这里的11可能是一个错误)。
这很自然地导致了测试的目的(耶!)。测试的一个好处是,它允许您考虑在创建对象或调用函数时到底想要发生什么。对于您的takeTurns函数,这可能是只允许输入数字,如果不输入0-5范围内的单个数字,则会引发异常或请求另一个输入。然后,您将基本上实现您的功能(在测试之后),以满足您在开始时提出的所有要求。然后,您可能还会发现,您可能是以错误的方式考虑它;在这种情况下,可能是take_turns (我为您重命名了它)。应该不是要求input(),而是接受一个论点,take_turns(user_choice)。
最后,我将添加一些较小的建议。
self.__class__.__name__ == "Player":,您可以(而且应该)使用isinstance(self, Player)。action = random.randint(1, 4)与4 if-statements耦合,random中有一个名为choice的方便的小函数(请看这里)。您还可以通过重新考虑AI与Player的区别(或不不同),使您的D24类更小。print("You:\nCastle: " + str(player.castle) + " Food: " + str(player.food) + " Stone: " + str(player.stone) + " Villagers: " + str(player.villagers) + " Warriors: " + str(player.warriors) + "\n")不同,您可以使用(并且注意到我删除了str(),因为您不需要它):print(“f”“you :player.castle:{player.castle} Food:{player.food} Stone:{player.stone}村民:{player.villagers}勇士:{player.warriors}”)https://codereview.stackexchange.com/questions/239408
复制相似问题