• 欢迎大家分享资料!前往留言板评论即可!

Flask项目nose单元测试与覆盖率

合宙 模组资料网 2年前 (2021-05-15) 270次浏览 0个评论 扫描二维码

flask项目可用nose进行单元测试,同时给出覆盖率结果。不用额外起http服务,还是挺方便的。
nose文档:https://nose.readthedocs.io/en/latest/usage.html

  1. 安装python包
    nose3
    coverage

  2. 在项目根目录下起一个test目录

  3. 创建init.py
"""
    2020.08.05  zhouzhiran
"""

from app import create_app

app = create_app('testing')
app_ctx = app.app_context()
app_ctx.push()

test_app = app.test_client()

def setUp():
    print('set up')

def tearDown():
    print('tear down')
  1. 创建test_base.py测试基类。在里面实现get、post等请求。可不断对其完善,添加各种请求信息,如form参数、json参数、header等等。cookie的信息要根据自己项目来抠。
import json

from nose.tools import assert_equal
# from werkzeug.http import parse_cookie
from werkzeug.http import parse_cookie

import test

import config.config as config


class BaseTest():

    def __init__(self):
        print('__init__')
        self.client = test.test_app
        self.session = None
        # self.headers = {'content-type': 'application/json'}

    def check_resp_200(self, resp):
        print('check_resp_200')
        print(resp)
        assert_equal(resp.status_code, 200)

    def check_resp_400(self, resp):
        print('check_resp_400')
        assert_equal(resp.status_code, 400)


    def post(self, path, data = None, force_login = True, json_data = None):
        if force_login and self.session is None:
            print('need login session')
            print(self.session)
            self.login()
            print(self.session)
            self.client.set_cookie('localhost', 'session', self.session)
        if json_data is not None:
            return self.client.post(path, content_type='application/json', data=json.dumps(json_data))
        else:
            return self.client.post(path, content_type='multipart/form-data', data=data)

    def post_file(self, path, data, force_login=True):
        if force_login and self.session is None:
            print('need login session')
            print(self.session)
            self.login()
            print(self.session)
            self.client.set_cookie('localhost', 'session', self.session)
        return self.client.post(path, content_type='multipart/form-data', data=data)

    def put(self, path, data, force_login=True):
        if force_login and self.session is None:
            print('need login session')
            print(self.session)
            self.login()
            print(self.session)
            self.client.set_cookie('localhost', 'session', self.session)
        return self.client.put(path, content_type='multipart/form-data', data=data)

    def get(self, path, params, force_login=True):
        print(params)
        if force_login and self.session is None:
            print('need login session')
            print(self.session)
            self.login()
            print(self.session)
            self.client.set_cookie('localhost', 'session', self.session)
        return self.client.get(path, query_string=params)

    def login(self):
        payload = {
            'name': config.TEST_USERNAME,
            'password': config.TEST_PASSWORD
        }
        print(payload)
        resp = self.post('/site/login', data=payload, force_login = False)
        print(resp)
        # print(resp.headers.get('Set-Cookie')

        self.check_resp_200(resp)

        cookies = resp.headers.getlist('Set-Cookie')

        print(cookies)
        print(('wtf2', parse_cookie(cookies[1])))
        self.session = parse_cookie(cookies[1])['erp session']

        print(('wtf2', self.session))
  1. 起测试代码。文件必须以test打头比如test_site_v2.py。
    需创建一个测试类,以Test打头。
    类里定义要测试的函数,以test打头。
    传文件的方法:用form参数,做一个tuple。比如 data['in_label_file'] = (open('./main.py', 'rb'), 'in_label_file')
    取返回数据的方法:order_id = json.loads(resp.data.decode('utf8'))['order_id']
from test.test_base import BaseTest
import json

class TestSiteV2(BaseTest):

    def test_need_to_login(self):
        data = {}
        resp = self.post('/site/v2/role', data = data, force_login = False)

        self.check_resp_400(resp)

    def test_test(self):
        resp = self.get('/site/v2/test', '')

        self.check_resp_200(resp)

    def test_001_post_order(self):
        data = {'customer_id':15926}
        data['payee'] = '上海合宙'
        data['recipient'] = 'xc'
        data['phone'] = '123456788888'
        data['province'] = '上海'
        data['city'] = '上海'
        data['area'] = '海'
        data['address'] = '海合'
        data['info'] = 'test'
        data['express_price'] = 1000
        data['payment_type'] = 1
        data['order_type'] = 0
        data['products'] = json.dumps({'1':{'product_id':53, 'price':1, 'amount':10, 'in_label_file':'in_label_file', 'out_label_file':'out_label_file', 'shipment_file':'shipment_file', 'express_file':'express_file', 'package_file':'package_file', 'module_label_file':'module_label_file'}, '2':{'product_id':483, 'price':2, 'amount':10}}) # total_price_cut 暂时只能用在淘宝订单
        data['in_label_file'] = (open('./main.py', 'rb'), 'in_label_file')
        data['in_label_file'] = (open('./main.py', 'rb'), 'in_label_file')
        data['out_label_file'] = (open('./main.py', 'rb'), 'out_label_file')
        data['shipment_file'] = (open('./main.py', 'rb'), 'shipment_file')
        data['express_file'] = (open('./main.py', 'rb'), 'express_file')
        data['package_file'] = (open('./main.py', 'rb'), 'package_file')
        data['module_label_file'] = (open('./main.py', 'rb'), 'module_label_file')

        resp = self.post('/site/v2/order', data = data)


        order_id = json.loads(resp.data.decode('utf8'))['order_id']
        order_sn = json.loads(resp.data.decode('utf8'))['order_sn']
  1. 在根目录下运行测试命令。
    nosetests –with-coverage –cover-erase –cover-package=app.site
    –cover-package为自定要测的模块。测多个模块的话用逗号隔开,比如–cover-package=app.site,app.open,app.event

  2. 结果
    会按函数名字母顺序执行函数。
    如果assert失败会停止。并打印出log。
    最后给出覆盖率统计。
    依次为测试文件名,代码总行数,未覆盖的总行数,覆盖率,所有未覆盖的代码位置。
    比如下面的结果:测试了app/site/site_v2.py,总行数1233,未覆盖行数295,覆盖率76%。
    之后是所有未覆盖的代码,比如35-36行、114-115行等等等在测试中都没跑到,修改测试代码让它能跑到即可提高覆盖率。

app/site/site_v2.py     1233    295    76%   35-36, 70, 114-115, 124, 152, 155, 220-225, 232-234, 243-244, 249-260, 269, 300, 387, 449, 463, 477, 491, 505, 519, 570, 587, 597, 613, 624-758, 855, 961, 975, 989, 1003, 1017, 1031, 1045, 1174-1178, 1188, 1287-1293, 1299-1344, 1354, 1364, 1424, 1427, 1439, 1476, 1479, 1506, 1509, 1532-1534, 1547, 1656, 1700, 1714, 1804, 1850, 1853, 1859-1860, 1935-1968, 1973-1982, 2293, 2298, 2391-2395, 2415, 2495, 2574, 2593, 2612, 2619-2622, 2627-2630, 2635-2638, 2643-2729, 2740-2741


转载请注明原文链接:Flask项目nose单元测试与覆盖率
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址