You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用pytest-cov覆盖server.py中if __name__ == '__main__'代码块?

解决server.py中if __name__ == '__main__'代码块的覆盖率问题

问题原因

测试执行时,server.py是以模块形式被import的,此时__name__的值为'server',而非'__main__',因此该代码块不会被执行,导致覆盖率工具无法统计到这部分代码。

解决方案

方案一:直接在测试中触发main代码块执行

在testing.py中新增测试用例,通过修改模块名并结合mock避免服务阻塞的方式触发该代码块:

def test_main_block():
    # 保存原模块名
    original_name = server.__name__
    # 修改为__main__以触发目标代码块
    server.__name__ = '__main__'
    
    # 用mock跳过app.run的阻塞逻辑,防止测试卡住
    import mock
    with mock.patch('server.app.run') as mock_run:
        import importlib
        importlib.reload(server)
        # 验证app.run被正确调用
        mock_run.assert_called_once_with(port=5000, debug=True)
    
    # 恢复原模块名,避免影响其他测试
    server.__name__ = original_name

方案二:重构server.py代码(推荐)

将if __name__ == '__main__'中的逻辑封装为独立函数,既提升代码可维护性,也便于单独测试:
修改server.py:

def init_database_and_start_server():
    with app.app_context(): 
        db.drop_all()  # 清空现有数据库表
        db.create_all()  # 创建新表
    app.run(port=5000, debug=True)

if __name__ == '__main__':
    init_database_and_start_server()

然后在testing.py中添加对应测试:

def test_init_database():
    # 测试数据库初始化逻辑
    with server.app.app_context():
        # 验证drop_all和create_all的执行效果
        server.db.create_all()
        server.db.drop_all()
        assert not server.db.engine.dialect.has_table(server.db.engine.connect(), 'user')
        
        server.db.create_all()
        assert server.db.engine.dialect.has_table(server.db.engine.connect(), 'user')

def test_main_entry_point():
    # 测试main入口是否正确调用封装函数
    import mock
    with mock.patch('server.init_database_and_start_server') as mock_func:
        server.__name__ = '__main__'
        import importlib
        importlib.reload(server)
        mock_func.assert_called_once()

两种方案对比

  • 方案一无需修改业务代码,但依赖模块重载和mock,逻辑相对繁琐;
  • 方案二通过代码重构提升了可测试性,同时让业务逻辑更清晰,更适合长期维护。

内容的提问来源于stack exchange,提问作者Bart

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:25:21