Python单元测试的类方法

sta*_*kjs 3 python unit-testing

一个初学者级的问题..试图了解我如何才能最好地使用内置的unittest。在下面的琐碎示例中,方法define_food选择一个食物,然后调用food.cut()方法。将来,此方法可能返回Drinkobject的实例。该#commented code指示一个可能的未来的实施。在这种情况下,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
Run Code Online (Sandbox Code Playgroud)

Luk*_*raf 5

事实是,您cut()consume_food()方法现在并没有真正做很多事情,这使您可以在测试中执行有意义的断言之后。

因此,我建议稍微扩展一下初始代码,以使这些方法作用于相应的对象,以便您可以在调用这些方法后对其状态进行有意义的断言。

现在,他们真正要做的只是写入STDOUT,这是一种全局状态- 通常应避免这种状态,并且始终很难进行测试。(我并不是说打印输出是一件坏事-但是,如果这是您的代码唯一要做的事情,则进行测试将非常棘手)。

因此,我介绍了一个Food具有consume()方法并设置相应属性的通用超类。同样,现在的cut()方法会Fruit设置一个您可以测试的属性。

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
Run Code Online (Sandbox Code Playgroud)

现在,这些测试可以在调用相关方法之后对对象的状态进行断言。请注意,它们遵循AAA模式-安排行为声明

  • 首先,按照需要的方式排列测试对象(实例化消费者)。
  • 然后你采取行动的对象测试(调用问题的方法)
  • 最后,对期望对象处于的结果状态进行断言
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()
Run Code Online (Sandbox Code Playgroud)