V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
itskingname
V2EX  ›  问与答

咨询 Python 单元测试中的一些细节问题

  •  
  •   itskingname · 2018-12-19 18:47:13 +08:00 · 988 次点击
    这是一个创建于 2151 天前的主题,其中的信息可能已经有所发展或是发生改变。

    假设我有一个类:

    class SqlUtil(object):
        def __init__(self):
            self.conn = pymysql.connect(......)
    
        def method_1(self)
        def method_2(self)
        def method_3(self)
        def method_4(self)
        def method_5(self)
        def method_6(self)
        def method_7(self)
        def method_8(self)
        def method_9(self)
    

    我需要测试这个类的每一个方法。那么问题来了,如果我的测试代码这样写,我每一个测试案例都需要实例化这个类,那么就要连接很多次数据库。

    TestSql(object):
        def test_method1(self):
            ins = SqlUtil()
            result = ins.method_1()
            assert result == 1
    

    如果其中的只有 method_1~7 需要使用数据库连接,method_8, method_9 实际上不需要数据库,我初始化被测试类,就白白浪费了数据库连接。

    所以请问,这种场景下,是否只初始化 1 次被测试类会更好?

    如果被测试的方法需要向数据库写入数据,那么 MySQL 的写入操作是 mock 一下更好,还是真的需要读取 MySQL 来确定数据是否真的写入成功了?

    12 条回复    2018-12-20 10:49:55 +08:00
    virusdefender
        1
    virusdefender  
       2018-12-19 18:52:27 +08:00
    白白浪费了数据库连接,测试场景下感觉可以接受吧
    itskingname
        2
    itskingname  
    OP
       2018-12-19 19:00:48 +08:00
    @virusdefender #1 就是有点奇怪
    xavierskip
        3
    xavierskip  
       2018-12-19 19:58:00 +08:00
    如果你觉得这是浪费数据库连接的话,这也是你写的类的问题而不是单元测试的问题。
    itskingname
        4
    itskingname  
    OP
       2018-12-19 20:06:26 +08:00 via iPhone
    @xavierskip 嗯,是的,如果确实有必要在每个测试案例里面都实例化类,那我可以修改类。
    snBDX1b0jJM4ogKd
        5
    snBDX1b0jJM4ogKd  
       2018-12-19 21:43:24 +08:00 via Android
    不是有 setupClass 吗
    megachweng
        6
    megachweng  
       2018-12-20 09:29:07 +08:00 via iPhone
    Pytest 安利一下 数据库连接放到 Fixture 里面 scope=module 或 session,测试太美好了
    itskingname
        7
    itskingname  
    OP
       2018-12-20 09:56:08 +08:00
    @megachweng #6 我现在就在使用 pytest
    itskingname
        8
    itskingname  
    OP
       2018-12-20 09:57:07 +08:00
    @megachweng #6 我的数据库连接是在被测试的类的__init__方法里面的。你是指我在 fixture 里面初始化这个类吗?
    megachweng
        9
    megachweng  
       2018-12-20 10:24:43 +08:00 via iPhone
    @itskingname @pytest.fixture(scope=“ session ”)
    def db():
    return SqlUtil()
    @pytest.parametrize(‘ n ’,[1,2,3,4,])
    def test_xxx(db):
    assert greattr(f ’ method_{n}’)()
    megachweng
        10
    megachweng  
       2018-12-20 10:25:39 +08:00 via iPhone
    @megachweng 补充一下测试函数少了个 n 参数
    megachweng
        11
    megachweng  
       2018-12-20 10:27:31 +08:00 via iPhone
    @megachweng 手机上打字,有些错误,思想就是把耗时的工作放到 fixture 里面,一次初始化多处使用
    itskingname
        12
    itskingname  
    OP
       2018-12-20 10:49:55 +08:00
    @megachweng #11 明白。感谢~如此甚好,如此甚好
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2503 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:28 · PVG 09:28 · LAX 17:28 · JFK 20:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.