繁体   English   中英

如何更改我的代码以与此单元测试兼容?

[英]How do I change my code to be compatible with this unittest?

我正在 Exercism 网站上做一个练习,我已经编写了程序,但它没有通过 Exercism 进行的一项测试。 不过,我不太清楚我需要做什么来修复它。 这是我的代码:

import random

ABILITIES = ['strength', 'dexterity', 'constitution',
             'intelligence', 'wisdom', 'charisma']

class Character:
    def __init__(self):
        for ability in ABILITIES:
            setattr(self, ability, roll_ability())
        self.hitpoints = 10 + modifier(self.constitution)


def modifier(constitution):
    return (constitution - 10) // 2


def roll_ability(dice=4, sides=6):
    rolls = []
    for die in range(dice):
        rolls.append(random.randint(1, sides))
    rolls.remove(min(rolls))
    return sum(rolls)

这是测试文件中失败的代码:

def test_random_ability_is_within_range(self):
        score = Character().ability()
        self.assertIs(score >= 3 and score <= 18, True)

这是失败消息:

________________________________ DndCharacterTest.test_random_ability_is_within_range _________________________________

self = <dnd_character_test.DndCharacterTest testMethod=test_random_ability_is_within_range>

    def test_random_ability_is_within_range(self):
>       score = Character().ability()
E       AttributeError: 'Character' object has no attribute 'ability'

dnd_character_test.py:58: AttributeError

我想我需要一个名为“能力”的对象属性? 但是它有什么作用呢? 我不喜欢必须如此特别地编写程序才能通过单元测试! 我想我需要在开始编写代码之前通读单元测试,这样我才能知道该怎么做?

谢谢!

阅读了D&D 角色练习描述后,这只是没有指定 你对不得不依赖这里的测试来为你提供规格感到不安是正确的,这应该在你的作业中更清楚地描述。

该测试当然期望有一个Character().ability()方法,并且它验证该方法返回 3-18 范围内的整数,包括 3-18。 因此,阅读描述告诉您如何计算能力以及测试正在寻找什么的内容之间的行之间,您只需要将roll_ability()函数移动到您的Character类并将其重命名为ability()

class Character:
    def __init__(self):
        for ability in ABILITIES:
            setattr(self, ability, self.ability())
        self.hitpoints = 10 + modifier(self.constitution)

    def ability(self, dice=4, sides=6):
        rolls = []
        for die in range(dice):
            rolls.append(random.randint(1, sides))
        rolls.remove(min(rolls))
        return sum(rolls)

您自己的实现已经产生了 3 到 18 之间的数字,包括 3 和 18(包括 3 个最高骰子的总和),因此应该毫无问题地通过测试。 我已经确认上述实现(加上您的modifier()函数)确实通过了给定的单元测试。

从设计的角度来看,您在这里使用单独的功能是正确的。 ability()不依赖于任何Character状态,也不是角色实例应该执行的功能。 与其让它成为一个方法(带有一个无用的self参数),你可以在这里妥协并使它成为一个@staticmethod

class Character:
    def __init__(self):
        for ability in ABILITIES:
            setattr(self, ability, self.ability())
        self.hitpoints = 10 + modifier(self.constitution)

    @staticmethod
    def ability(dice=4, sides=6):
        rolls = []
        for die in range(dice):
            rolls.append(random.randint(1, sides))
        rolls.remove(min(rolls))
        return sum(rolls)

至于ability()函数的实现,您可能需要查看heapq.nlargest()函数,以便在heapq.nlargest()干净有效地从 4 个骰子中选出前 3 个:

from heapq import nlargest

class Character:
    # ...

    @staticmethod
    def ability(dice=4, sides=6):
        rolls = (random.randint(1, sides) for _ in range(dice))
        return sum(nlargest(dice - 1, rolls))

我只是基于 YAGNI在这里放弃dicesides参数,或者至少将幻数46移动到顶部的大写全局名称中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM