jiazurongyu 发表于 2021-3-27 14:04:22

python unittest 上下文使用

unittest核心是通过文件夹等模式把一个个测试对象给添加到测试套件里面,然后进行驱动。

unittest框架性提供了一些便利,会导致平时写代码根据函数和函数调用顺序,触发的对象在其他测试对象(成员函数内)是不可识别的。

context是上下文,这里先不考虑使用db例如Redis做缓存和全局对象这种方式,先看看普通类的实现。

# 加了类名Test,除非用命令行执行,ide里面会判断是一个测试类对象
class Demo():
   def test_login(self):
      self.user = "maomao"

   def test_start_task(self):
      print(f"{self.user}开始任务")

if __name__ == '__main__':
   t = Demo()
   t.test_login()
   t.test_start_task()
可见,只要先调用了test_login(),等于激活了self.user,下面的test_start_task里面的self.user就等于maomao。

把上面的Demo改成TestDemo,支持unittest来测试下。

import unittest

class Demo(unittest.TestCase):
   def test_login(self):
      self.user = "maomao"
   def test_start_task(self):
      print(f"{self.user}开始任务")

if __name__ == '__main__':
   unittest.main()
这个会输出 AttributeError: 'Demo' object has no attribute 'user'

熟悉unittest的都知道他有每个模块,每个类,每个方法(最小测试对象)的前后置函数,每个方法之间的对象是隔离的。

只要是语言在计算机原理没有变化的情况下,白话来说,往上访问对于当前来说都是共享内存的区域,在方法层面往上访问就是类,共享区域就是类变量,类变量是晚于classmethod需要注意。

类层面往上访问就是模块,模块共享区域就是模块的__init__.py。

unittest的函数对象访问顺序是遵循ascii码规则,函数对象名称前面test_a_xxx,test_b_xxx...依次往下就行。

使用unittest.main()方式去驱动。

===================================================

如果想让test_start_task可以识别到user,就需要把user添加到类变量区域。

class Demo(unittest.TestCase):
    temp = []
    def test_a_login(self):
       self.user = "maomao"
       self.temp.append(self.user)
    def test_b_start_task(self):
      # 不推荐使用print(f"{self.temp}开始任务1")
       self.user = self.temp.pop()
       print(f"{self.user}开始任务1")
       print(self.temp) #长度为0
不推荐的原因是毕竟是魔术,可读性低,是不是觉得pop()返回并且清除列表内部的,更像一锤子买卖。

pop的源码描述,remove and return item at index (default last) 默认是删除最后一个并且返回

# 上面代码下添加这个
def test_c_replay_start_task(self):
      print(f"{self.temp}开始任务2")
结果会发现依然可以识别,由此可见temp在经过test_login()被添加后,temp里面就有了user。

下标是不符合可读性的,那么Python的字典具备可读性,查询是O(1)的行为,是最合适的,这里完成修改下代码。

以后包含上下文的都可以用以下代码使用。

class Demo(unittest.TestCase):
   # 如果上下文需要用到的
   temp = {}

   def test_a_login(self):
      self.user = "maomao"
      self.temp["user"] = self.user

   def test_b_start_task(self):
      print(f'{self.temp["user"]}开始任务1')

   def test_c_replay_start_task(self):
      print(f'{self.temp["user"]}开始任务2')

if __name__ == '__main__':
   unittest.main()
PS:unittest也是支持命令行的,-m代表import导入,后面跟着unittest就是导入ut。

py -3 -m unittest xxx.py

z00100 发表于 2022-5-4 13:17:37

谢谢啦
页: [1]
查看完整版本: python unittest 上下文使用