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

如何为Flask应用编写单元测试?满足Sonar扫描覆盖要求

Flask应用单元测试问题

我是Python脚本单元测试的新手,想了解如何为自己的Flask应用编写测试用例,同时Sonar扫描要求覆盖所有场景,包括sys、os等模块导入的测试,但我不确定该如何着手。

我的Flask应用代码(run.py)

import sys , os , os.path , time , datetime , json , logging, warnings
from os import listdir
from os.path import isfile, join


from flask import Flask
from flask import render_template
from flask import request
from flask import url_for
from flask import request

from datetime import datetime
from logging import FileHandler
from logging import Formatter


## --> Create another function from a different .python file to import data

host_url="localhost"
port_number=1234
app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    server='Development_Sandbox'
    return render_template('index.html',server=server)


@app.route('/information/')
@app.route('/information/<name>')
def information():
    name='summary_report'
    return render_template('information.html',name=name)

app.run(host='localhost', port=1234, debug=True)

我编写的初步测试用例(test_flask.py)

import unittest
import test
import sys
# from unittest import TestCase, mock

sys.path.insert(1, 'C:/Users/mm13854/Desktop/Python Project/subscription_app')
import run as flk

class Test_Flask(unittest.TestCase):
    def test_checkURL(self):
        result=flk.host_url
        self.assertEqual(result, 'localhost')

    def test_checkPortNumber(self):
        result=flk.port_number
        self.assertEqual(result, 1234)
    
    def test_importModules(self):
        #how do i test if import is succesful for example 
        #import sys ,import os , os.path , time , datetime , json , logging, warnings
        #from os import listdir
        #from os.path import isfile, join


if __name__=='__main__':
    unittest.main()

我不确定当前的测试方法是否正确,尤其不知道如何验证这些模块导入是否成功。


解决方案

一、Flask核心功能测试优化

Flask应用测试的核心是验证路由响应逻辑,而非仅变量值。可以利用Flask内置的测试客户端模拟请求:

  1. 改造测试文件,初始化测试客户端:
import unittest
import sys
sys.path.insert(1, 'C:/Users/mm13854/Desktop/Python Project/subscription_app')
import run as flk
from unittest.mock import patch

class Test_Flask(unittest.TestCase):
    def setUp(self):
        # 开启测试模式,避免启动调试服务器线程
        flk.app.config['TESTING'] = True
        self.client = flk.app.test_client()

    def test_checkURL(self):
        self.assertEqual(flk.host_url, 'localhost')

    def test_checkPortNumber(self):
        self.assertEqual(flk.port_number, 1234)

    # 测试根路由与/index路由
    def test_index_route(self):
        # 模拟访问根路径
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)
        # 验证响应包含预期内容(需确保模板存在)
        self.assertIn('Development_Sandbox', response.data.decode())

        # 测试/index路由
        response = self.client.get('/index')
        self.assertEqual(response.status_code, 200)
        self.assertIn('Development_Sandbox', response.data.decode())

    # 用Mock跳过模板依赖测试路由逻辑
    @patch('run.render_template')
    def test_index_route_mocked(self, mock_render):
        mock_render.return_value = 'Mocked Response'
        response = self.client.get('/')
        self.assertEqual(response.data.decode(), 'Mocked Response')
        # 验证render_template被正确调用
        mock_render.assert_called_once_with('index.html', server='Development_Sandbox')

    # 测试information路由
    def test_information_route(self):
        # 无参数路径测试
        response = self.client.get('/information/')
        self.assertEqual(response.status_code, 200)
        self.assertIn('summary_report', response.data.decode())

        # 带参数路径测试(即使函数未使用参数,也要覆盖路由分支)
        response = self.client.get('/information/test_name')
        self.assertEqual(response.status_code, 200)
        self.assertIn('summary_report', response.data.decode())

二、模块导入的验证方法

Sonar要求的导入覆盖,其实无需复杂测试:只要测试文件能成功导入run模块,就说明run.py内的所有导入均成功——若导入失败,测试会直接抛出ImportError终止。

如果要显式验证,可添加以下测试:

def test_importModules(self):
    # 验证顶级模块已导入
    self.assertIn('sys', sys.modules)
    self.assertIn('os', sys.modules)
    self.assertIn('time', sys.modules)
    self.assertIn('datetime', sys.modules)
    self.assertIn('json', sys.modules)
    self.assertIn('logging', sys.modules)
    self.assertIn('warnings', sys.modules)

    # 验证从模块导入的对象存在于run模块中
    self.assertTrue(hasattr(flk, 'listdir'))
    self.assertTrue(hasattr(flk, 'isfile'))
    self.assertTrue(hasattr(flk, 'join'))
    self.assertTrue(hasattr(flk, 'Flask'))
    self.assertTrue(hasattr(flk, 'render_template'))

注:这类测试属于冗余验证,但可满足Sonar的覆盖要求。

三、代码优化建议

  1. 修改run.py的启动逻辑,避免测试时自动启动服务器:
if __name__ == '__main__':
    app.run(host='localhost', port=1234, debug=True)
  1. 清理重复导入,比如from flask import request重复出现两次,减少不必要的冗余。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 15:35:40