类方法的Python单元测试

标签 python unit-testing

初学者级别的问题.. 试图了解如何最好地使用内置的 unittest。在下面的简单示例中,方法 consume_food 选择食物,然后我调用 food.cut() 方法。 将来,此方法可能会返回 Drink 对象的实例。 #commented code 表示一种可能的 future 实现。在这种情况下,self.milk 将不会定义 cut 方法。

我想为 consume_foodpick_food 方法添加单元测试。我想首先对原始实现执行此操作,然后在添加 self.milk 功能后对其进行更改。

编辑: 目的是为现有的 api 编写单元测试,以便我可以捕获任何此类更改(即缺少 Drink.cut 方法)强制我来更新方法和单元测试。

谁能帮我演示一下如何为这个例子编写单元测试?

class Fruit:
    def cut(self):
        print("cut the fruit")

class Drink:
    def pour(self):
       print("pour the drink")


class A:
   def __init__(self):
       self.apple = Fruit()
       self.banana=Fruit()
       #self.milk = Drink()
       #self.liquid_diet = True

   def consume_food(self):
       food = pick_food()
       food.cut()
       print("consuming the food")

   def pick_food(self):
       return self.apple                                 
       #if self.liquid_diet: return self.milk
       #return self.apple

最佳答案

问题是,您的 cut()consume_food() 方法现在并没有真正做很多事情来让您做出有意义的 assertions在测试中执行它们之后。

因此,我建议稍微扩展您的初始代码,让这些方法作用于相应的对象,这样您就可以在调用这些方法后对它们的状态做出有意义的断言。

现在,他们真正做的就是写入 STDOUT,这是一种全局状态 - 这应该是 generally be avoided并且是 always difficult to test . (我并不是说打印输出是一件坏事 - 但如果那是您的代码所做的唯一事情,那么测试将非常棘手)。

所以我引入了一个通用的父类(super class)Food,它有一个consume()方法,并设置了相应的属性。同样,Fruit 上的 cut() 方法现在设置了一个您可以测试的属性。

import unittest


class Food(object):
    def __init__(self):
        self.consumed = False

    def consume(self):
        self.consumed = True


class Fruit(Food):
    def __init__(self):
        super(Fruit, self).__init__()
        self.been_cut = False

    def cut(self):
        print("cut the fruit")
        self.been_cut = True


class Consumer(object):
    def __init__(self):
        self.apple = Fruit()
        self.banana = Fruit()

    def consume_food(self):
        food = self.pick_food()
        food.cut()
        print("consuming the food")
        food.consume()

    def pick_food(self):
        return self.apple

这些测试现在可以在调用相关方法后对对象的状态进行断言。请注意,它们遵循 AAA pattern - Arrange Act Assert :

  • 首先,您按照需要的方式排列被测对象(实例化消费者)。
  • 然后您对被测对象采取行动(调用相关方法)
  • 最后,您对您期望对象所处的结果状态做出断言
class TestConsumer(unittest.TestCase):

    def test_consume_food_consumes_the_apple(self):
        c = Consumer()
        c.consume_food()
        self.assertTrue(c.apple.consumed,
                        "Expected apple to be consumed")

    def test_consume_food_cuts_the_food(self):
        c = Consumer()
        c.consume_food()
        self.assertTrue(c.apple.been_cut,
                        "Expected apple to be cut")

    def test_pick_food_always_selects_the_apple(self):
        c = Consumer()
        food = c.pick_food()
        self.assertEquals(c.apple, food,
                          "Expected apple to have been picked")


if __name__ == '__main__':
    unittest.main()

关于类方法的Python单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32672551/

相关文章:

python - 无法从 CLI 或 pyodbc 连接到 Mac 上 docker 容器中运行的 Mssql 服务器 - Azure DS 可以工作吗?

python - 无法使用 pyenv 安装 : `Python may not be configured for Tk` `ModuleNotFoundError: No module named _tkinter' 运行 IDLE

python - 使用python替换字符串中字符的所有实例

javascript - Selenium - 自动化javascript按钮点击

python - 在 Python 中,是否有直接的方法来过滤 pd.dataframe 以列的 2 个值范围为条件?

c# - 为什么 1 000 000 不等于 1000000.toString ("N", new CultureInfo ("fr-FR"))

android - 如何为 android 仪器测试设置环境并制作示例 Activity UI 测试?

android - 使用 retrofit2 和 rxjava2 对 android 应用程序进行单元测试

xcode - 调用 XCTFail() 后 Swift 单元测试不会停止

django - 如何使用外键在 Django 中测试模型