Python pytest 中如果解决数据依赖问题?

学学看看 · 2022年08月17日 · 最后由 5_shuai 回复于 2022年08月25日 · 6568 次阅读
import pytest

class TestCase:
    test_dict = {}
    def test_one(self):
        self.test_dict = self.login("user","password")
        assert self.test_dict["cookie"] == '1234'

    def test_two(self, request):
        print("当前内容:", self.test_dict)
        assert self.test_dict["cookie"] == "1234"

    def login(self,user,password):
        return {"cookie":"1234",user:password}

if __name__ == "__main__":
    pytest.main(["-s", "testcase.py"])

其中代码如上,但执行 test_two 方法时会报错,此时 test_one 修改字典后,在 test_two 后获取的字典值仍然为空。
类似这种情况,如果在同一个 pytest 的测试文件中,如果 test_two 想要 test_one 执行登录后生成的某个数值,有什么好的方法?

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 10 条回复 时间 点赞

你写得就有问题。类变量和实例变量是不一样的。

  1. 为什么报错的原因楼上说了。我理解把 test_dict = {} 改成 self.test_dict = {} 才是同一个变量的方向。
  2. 测试用例的独立性是很重要的,不同用例直接应该减少依赖。以你的登录例子为例,相信绝大部分的用例都是需要登录的,所以你需要考虑一下 setup 方法,或者 pytest 的 fixture,把登录提取出来共享给对应的用例,达到登录一次,所有用例都能共享使用的效果。

这和 pytest 没有半点关系

建议使用前置条件,避免依赖

把 self.test_dict 换成 TestCase.test_dict

pytest 在执行过程中会把每个 test 方法拆分到不同的实例 feature 里面去执行,所以每一个 test 方法中的 self 实例变量已经不是同一个了。这点真的很变态。我猜 pytest 应该是为了做参数注入、depends 依赖顺序而这样做的。反正,你现在书写的 pytest 类已经仅仅成为了一种格式化的书写规范了,self 也没有了上下文的功能了。

Jerry li 回复

如何达到登录一次,所有用例都能共享 token 呢。使用 fixture 中的哪一个方法,请指教。如果可以,可以上个代码看看嘛。谢谢~

5_shuai 回复

思路就是封装一个登录的方法,然后把登录结果通过一个 pickle 的库,存到一个文件里面。
通过 fixture 去尝试读取这个文件,如果能拿到就返回已登录的结果;如果这个文件不存在,就说明还没有登录,就去登录一次,并且保存登录结果。

pytest 执行依赖及 test 之间传值一种处理方式:

  1. pytest 框架的 test 之间的传值:利用 fixture 即可
    conftest.py 中定义全局参数:

    @pytest.fixture(scope='session') # session是大家全局共享变量,其他仅限于各自范围内有影响
    def xGlobalArgs():
          return {}
    
  2. pytest 的 test 依赖及传值,这里 testCASE2 会等待 testCASE1 测试通过再执行

    @pytest.mark.dependency(name="test1")
    def testCASE1(xGlobalArgs):
        xGlobalArgs["token"]="123123123123123"
       pass
    @pytest.mark.dependency(depends=["test1"])
    def testCASE2(xGlobalArgs):
        print(xGlobalArgs.get("token"))
        pass
    
Jerry li 回复

好滴,这确实是个办法,我尝试下

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册