V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iyaozhen
V2EX  ›  pytest

请教个 py.test 的使用问题( case 间参数依赖)

  •  1
     
  •   iyaozhen · 2016-12-24 21:29:02 +08:00 · 5921 次点击
    这是一个创建于 2919 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大概的代码是这样:

    import requests
    import pytest
    
    class TestRestApi():
        url = 'http://xxx.com'
    
        @pytest.fixture(scope="session")
        def http_session(self):
            # 省略设置 cookie 等步骤,返回一个 request.session 对象
            return requests.Session()
    
        def test_api_a(self, http_session):
            response = http_session.post(self.url + '/app/sessioncontextget', json=body)
            assert response.status_code == 200
            data = response.json()
            # 我想保存此 api 的一个返回值
            self.session_id = data['data']['session_id']
            assert data['code'] == 200
    
        def test_api_b(self, http_session):
            body = {
                # 请求参数依赖前一个 api 的返回值
                "sessionid": self.session_id,
            }
            response = http_session.post(self.url_ge + '/api/taskcreate', json=body)
            assert response.status_code == 200
            data = response.json()
            assert data['errcode'] == 0
    
    

    断点调试发现 session_id 是设置成功了的, test_api_a 也测试通过

    但运行到 test_api_b 时却提示:AttributeError: 'TestRestApi' object has no attribute 'session_id'。不过这也很好理解,单测本来就是每个 case 独立的,每次相当于都是重新运行。

    那么问题来了,这个需求怎么解决?

    还有一个问题, pytest.fixture 的特性感觉不是很方便, http_session 变量无法被 IDE 识别,没有代码提示了(不过这个影响很小),关键是每个测试 case 都要传入 http_session 参数,感觉不够简洁。

    初次使用 py.test ,可能理解不是很透彻,还请见谅。

    第 1 条附言  ·  2016-12-24 23:42:09 +08:00

    解决了。再增加一个fixture

    @staticmethod
    @pytest.fixture(scope="session")
    def global_values():
        return {}
    

    然后test case变成:

    def test_api_a(self, http_session: requests.Session, global_values: dict):
        ……
        global_values['session_id'] = data['data']['session_id']
    
    def test_api_b(self, http_session: requests.Session, global_values: dict):
        ……
        "sessionid": global_values['session_id'],
    

    因为使用的是Python3,还是选择了把fixture设置的变量写进参数里面,再加上类型声明,这样IDE就能自动提示了

    2 条回复    2016-12-24 22:33:40 +08:00
    jerry14
        1
    jerry14  
       2016-12-24 22:15:56 +08:00 via iPhone
    1. 既然有个 case 需要两步,有个依赖,那就放到一起。之前的那个 case 不变
    2. 你可以在 setup 方法里初始化 http_session ,然后作为一个实例属性
    iyaozhen
        2
    iyaozhen  
    OP
       2016-12-24 22:33:40 +08:00
    @jerry14 非常感谢。
    1. 你说的这个方法也行。但是不符合我的其它需求,我需要最终出一个报告,所以需要每个 api 在单独的 test case 中。
    2. 嗯,这样可以。现在这样做了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1784 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:23 · PVG 00:23 · LAX 08:23 · JFK 11:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.