python自动化测试(2)——python自动化测试概念整理

1.python及django编写单元测试。

测试驱动开发: 我们知道自己需要的功能,但是代码不知道怎么写。可以利用测试驱动开发,先写出我们期待的结果,再去完善代码。

《改善Python的91个建议》一书中说:单元测试绝不是浪费时间的无用功,它是高质量代码的保障之一,在软件开发的一节中值得投入精力和时间去把好这一关。

这里先不说django.

python里面的单元测试应该怎么写?

用unittest
先写个除法功能

先写一个简单的除法 命名为divi.py

def divi(a, b):
    if isinstance(a, (float, int)) and isinstance(b, (float, int)):
        if b == 0:
            return False
        else:
            return a / b
    else:
        return False

代码写完之后需要测,怎么测?

测试用例编写
# ddt need install. use pip3 install ddt
import ddt
import unittest
from divi import divi
import time, os
#import HTMLTestRunner
 
# 来一篇unitest。
# 后面再来一篇pytest的讲解.
 
data = [
    {'num_a': 1, 'num_b': 2, 'result': 0.5},
    {'num_a': 1, 'num_b': 0, 'result': False},
    {'num_a': '4', 'num_b': 2, 'result': False},
    {'num_a': 5.2, 'num_b': 2,  'result': 2.6},
    {'num_a': 2.724, 'num_b': 10, 'result': 0.2724},
]
 
@ddt.ddt
class Test(unittest.TestCase):
    def setUp(self):
        # 这里是干嘛的?用于测试用例执行前的初始化操作。
        # 连接数据库,初始化浏览器
        print('======test start======')

    @ddt.data(*data)
    def test_01(self, data1):
        self.assertEqual(divi(data1['num_a'], data1['num_b']), data1['result'])

    def tearDown(self):
        # 用于测试用例执行之后的善后工作。
        # 关闭数据库,关闭浏览器之类的
        print('======test end======')
 
    

# TestDivi().test_divi(data)

if __name__ == "__main__":
    unittest.main()
这里面有个ddt, ddt是什么?

ddt包含类装饰器ddt和两个方法装饰器data(直接输入测试数据),file_data(可以从json或yaml中获取测试数据)
通常情况下,data中的数据按照一个参数传递给测试用例,如果data中含有多个数据,以元组,列表,字典等数据,需要自行在脚本中对数据进行分解或者使用unpack分解数据。
@data(a,b) # a, b 各运行一次用例
@data([a,d][c,b] # 如果没有@unpack, 那么[a,b]会被当作一个参数传入用例运行。
如果有unpack,那么[a,b]会被分解开,按照用例中的两个参数传递。
@file_data(filename) 对于json文件,每个json元素按照一个用例运行。

import unittest
from ddt import ddt,data,file_data,unpack

@ddt
class demotest(unittest.TestCase):
    def setup(self):
        print "this is the setup"

    @data(2,3)
    def testb(self,value):
        print value
        print "this is test b"

    @data([2,3],[4,5])
    def testa(self,value):
        print value
        print "this is test a"

    @data([2, 3], [4, 5])
    @unpack
    def testc(self, first,second):
        print first
        print second
        print "this is test c"

    @file_data('d:/data_dic.json')
    def test_dic(self,value):
        print value
        print 'this is dic'

    @file_data('d:/data.yml')
    def test_yml(self, value):
        print value
        print 'this is yml'

    def teardown(self):
        print "this is the down"

if __name__ == '__main__':
    unittest.main()
    #suite=unittest.TestLoader.getTestCaseNames(demotest)
    #suite = unittest.TestLoader().loadTestsFromTestCase(demotest)
    #unittest.TextTestRunner(verbosity=2).run(suite)
用pytest
TODO

django编写测试用例

1.引用的是TestCase基类

django 测试用例:django.test继承了python标准库unittest. 所以测试用例类继承django.test.TestCase即可:

from django.test import TestCase
class MyClassTestCase(TestCase):
    def SetUp(self):
        pass
    def test_my_func(self):
        pass
2.用例执行:
./manage.py test

默认用例执行语句:会发现当前目录下的所有以test开头的py文件,并执行;此外用户还可以自己指定用例所在目录以及用例文件名匹配规则。

3.Client使用:

主要用于模仿url请求,调用并返回请求结果。

response = self.client.get("/vpc/list")
self.assertEquals(response.status_code, 302)
4. RequestFactory使用:

主要用于构造request对象,与Client相比,没有发生url接口的调用。

request = self.request_factory.post('vpc/list', data={'start': 0, 'length': 10})
vpc_manage = VpcManage(request)
5.断言(Assertions):

判断用例执行结果的主要手段,断言测试函数返回结果跟预计结果的一致性。

self.assertEquals(res['recordsTotal'], 0)
6.mock的使用

单元测试主要测试的是函数级功能,所以需要通过mock对待测函数中调用到的方法进行打桩,返回便于测试的值。

vpc_manage.get_user_info = mock.Mock(return_value=mock.Mock(**self.user_info_attrs))
res = vpc_manage.vpc_list()
res = json.loads(res)
7.仅仅执行用例:
python manage.py test -v 2

更多信息参考:
https://docs.djangoproject.com/zh-hans/2.2/topics/testing/overview/ 官网
https://code.ziqiangxuetang.com/django/django-test.html
https://www.jianshu.com/p/b2a8665018e1 django单元测试需要指定mysql测试数据库
https://juejin.im/post/5d8593f1e51d453bb13b66fa 掘金测试方法总结

2.文件代码覆盖率问题。

什么是代码覆盖率?

我们自己写代码的时候,会尝试写一些测试用例来测试代码的每个分支是否都走到了。有可能有的分支走到了,而有的分支一直都没有走到。走到的分支是覆盖到的,没有走到的分支是没有覆盖的。

要实现代码覆盖,需要安装coverage 这个可以实现代码覆盖率的检测。

如何测试代码覆盖率呢?这里需要安装coverage模块。 pip3 install coverage

如果只是简单的python文件,比如我上面举到的例子,执行coverage run test_divi.py即可。
如果是django项目。

coverage run --source '.' manage.py test -v 2

执行之后可以根据coverage report -m来获取代码的覆盖率。这个不能生成覆盖率html图。

如果完全覆盖了,可以使用coverage html来生成代码覆盖率html图
coverage erase可以删除创建的.coverage.

需要注意的是,覆盖率数据只能代表你测试过哪些代码,不能代表你是否测试好这些代码。
重构那本书的作者曾经写过一篇博客来讨论这个问题,他指出:把测试覆盖作为质量目标没有任何意义,而我们应该把它作为一种发现未被测试覆盖的代码的手段。

关于django有一个插件django_coverage_plugin
更多coverage信息参考:
https://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html
https://www.bedjango.com/blog/package-week-coverage-django/
https://coverage.readthedocs.io/en/v4.5.x/

3.关于测试报告

如果想生成测试报告,不考虑框架的情况下,可以使用HTMLTestRunner.py 这个不适合直接安装,python3可以参考
https://github.com/defnngj/HTMLTestRunner
当然,我们项目要采用下面的持续集成,因为代码仓库用的是gitlab, 所以就不添加测试报告,直接测完之后看结果。

4.CI里面搭建持续集成环境

TODO

参考:
https://www.jianshu.com/p/705428ca1410
http://py3study.com/Article/details/id/139.html

发布了199 篇原创文章 · 获赞 62 · 访问量 21万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览