通过执行发现,我们在用例03中没有加入fixture,所有他没有执行一些用例的前置和后置操作。
测试报告
unittest:unittest中没有自带的测试报告,需要下载第三方的插件HTMLTestRunner和BeautifulReport来生成详细的测试报告。
pytest:pytest中也没有自带的测试报告,需要下载第三方插件pytest-html或者allure-pytest进行生成详细的测试报告。
class Test01: def test_01(self): print('登录用例01') def test_02(self): print('编写用例02') def test_03(self): print('删除用例03')
通过在命令中输入命令:pytest --html=report.html进行生成报告。
参数化功能
unittest:unittest本身不支持参数化功能,需要通过第三方库DDt来进行完成参数化功能。
pytest:pytest的参数化有两种方式,一种通过@pytest.mark.pyparametrize的方法,也可以通过@pytest.fixture()中的方法params来完成参数化内容。
失败重跑
unittest:目前unittest暂时不支持用例失败重跑机制
pytest:可以依赖第三方插件pytest-rerunfailures来进行用例失败重跑
import pytest import random class Test01: @pytest.mark.flaky(reruns=3, reruns_delay=2) def test_01(self): a = random.randint(0, 3) print('通过随机数来确保用例会有几率失败') print('随机数是:{}'.format(a)) assert a == 2 if __name__ == '__main__': pytest.main(['-vs'])
执行代码,发现断言失败后会进行重新执行。
跳过用例
当明知测试用例存在bug或者说该用例进行修改过了,本次执行用例时候,不想执行用例,我们可以进行跳过用例。unittest和pytest都有自带的跳过用例方法。安静通过代码实例进行介绍
unittest中可以通过装饰器skip的方法进行强制跳过,通过skipif的方法加上条件进行跳过,当条件达到是,进行跳过,条件未达到,不进行跳过用例
pytest中的跳过和unittest基本相似,跳过用例,一样要输入一些条件。
实战演示
上面简单的列举了使用的各个方法,其中有一些区别没有举例给大家说明,安静这里简单的通过请求天气和查询身份证接口的形式,编写一些测试用例,将上述没有介绍的内容,给大家通过实例的方式进行连接起来。
unittest
这里安静使用到unittest的参数化是通过ddt的形式,测试数据没有单独存放,直接放到了类外面,安静这里创建了两个接口(查询天气和查询身份证)使用了跳过用例的方法,并对测试接口进行了断言操作,并通过HTMLTestRunner的方法生成了测试报告:
import unittest import requests import HTMLTestRunner_cn import ddt # 天气接口的参数化数据 data = [{"city": '上海', "key": "331eab8f3481f37868378fcdc76cb7cd", 'result':"查询成功!"}, {"city": "上海", "key": "331eab8f3481f37868378fcdc76cb7c", 'result':"错误的请求KEY"}, {"city": "上", "key": "331eab8f3481f37868378fcdc76cb7cd", 'result':"暂不支持该城市"}] @ddt.ddt class Test_(unittest.TestCase): def tianqi(self,city,key): '''天气接口''' data = { "key":key, "city":city } r = requests.post(url='http://apis.juhe.cn/simpleWeather/query',data=data) return r.json() def shenfenzheng(self,cardno,key): '''身份证查询接口''' data = { "cardno":cardno, "key":key } r = requests.post('http://apis.juhe.cn/idcard/index',data= data) return r.json() @ddt.data(*data) def test_01(self,data): '''参数化的天气接口''' x = self.tianqi(city=data['city'], key=data['key']) self.assertEqual(x['reason'], data['result']) def test_02(self): '''正确的身份证号正确的key''' cardno = '130428197411155947' # 身份证信息通过Faker随机创建 key = "f40a75704fac353952a6534a18f9f437" # 请求查询身份证接口 a = self.shenfenzheng(cardno,key) self.assertIn(a['reason'], '成功的返回') @unittest.skip('强制跳过,不需要条件') def test_03(self): '''正确的身份证号错误的key(跳过用例)''' cardno = '130428197411155947' key = "f40a75704fac353952a6534a18f9f43" a = self.shenfenzheng(cardno, key) self.assertEqual(a['reason'], '错误的请求KEY') @unittest.skipIf(True, '条件成立时候,进行跳过') def test_04(self): '''错误的身份证号正确的key(跳过用例)''' cardno = '42082120031108929' key = "f40a75704fac353952a6534a18f9f437" a = self.shenfenzheng(cardno, key) self.assertEqual(a['reason'], '请输入正确的15或18位身份证') if __name__ == '__main__': report_path = 'report.html' # 打开报告 fp = open(report_path, 'wb') # 报告详情 runner = HTMLTestRunner_cn.HTMLTestRunner(stream=fp, title=u'自动化测试报告,测试结果如下:', description=u'用例执行情况:') # 实例化 testunit = unittest.TestSuite() # 加载用例 testunit.addTests(unittest.TestLoader().loadTestsFromTestCase(Test_)) # 执行用例 runner.run(testunit) # 关闭报告 fp.close()
通过执行代码后发现已经可以成功的生成测试报告。
pytest
pytest这里安静也是通过上述的内容进行了修改,只是这里使用的框架是pytest。但是实现内容是一样的。天气接口进行参数化,身份证接口中2个跳过。在生成测试报告,这里安静生成的测试报告是通过allure来生成的:
import requests import json import pytest # 参数不同值 # 天气接口的参数化数据 data = [({"city": '上海', "key": "331eab8f3481f37868378fcdc76cb7cd", 'result':"查询成功!"}), ({"city": "上海", "key": "331eab8f3481f37868378fcdc76cb7c", 'result':"错误的请求KEY"}), ({"city": "上", "key": "331eab8f3481f37868378fcdc76cb7cd", 'result':"暂不支持该城市"})] class TestCase: def weather(self, city, key): url = 'http://apis.juhe.cn/simpleWeather/query' # 查询天气接口参数 data = { 'city': city, 'key': key } r = requests.post(url, data=data) return r.json() def shenfenzheng(self,cardno,key): '''身份证查询接口''' data = { "cardno":cardno, "key":key } r = requests.post('http://apis.juhe.cn/idcard/index',data= data) return r.json() @pytest.mark.parametrize('data',data) def test_01(self,data): # 调用天气预报接口 r = TestCase().weather(city= data['city'],key = data['key']) assert r['reason'] == data['result'] def test_02(self): '''正确的身份证号正确的key''' cardno = '130428197411155947' # 身份证信息通过Faker随机创建 key = "f40a75704fac353952a6534a18f9f437" # 请求查询身份证接口 a = self.shenfenzheng(cardno,key) assert a['reason'] == '成功的返回' @pytest.mark.skip('强制跳过,不需要条件') def test_03(self): '''正确的身份证号错误的key(跳过用例)''' cardno = '130428197411155947' key = "f40a75704fac353952a6534a18f9f43" a = self.shenfenzheng(cardno, key) assert a['reason'] =='错误的请求KEY' @pytest.mark.skipif(True, reason='条件成立时候,进行跳过') def test_04(self): '''错误的身份证号正确的key(跳过用例)''' cardno = '42082120031108929' key = "f40a75704fac353952a6534a18f9f437" a = self.shenfenzheng(cardno, key) assert a['reason'] in '请输入正确的15或18位身份证' if __name__ == '__main__': pytest.main(['-s'])
这里我们通过在cmd中先执行pytest --alluredir report进行打开报告,然后在通过allure serve report打开测试报告。从报告中就能看到已经全部都执行成功了,且用例跳过了2条。
总结
安静简单的列举出来了几点并通过项目实例进行对比两种框架的情况。其中我们可以看出来unittest编写用例比pytest复杂,最最最主要的一点是unittest没有较多的第三方插件支持,但是pytest可以支持更多的第三方插件,这样可以更加方便的进行投入到编写测试用例的过程中。当然对于新手来说,安静还是推荐先使用unittest,看看unittest的源码内容,当unittest学会之后在去接触pytest,这样就更加容易上手。其次unittest作为Python中的内置框架,也是值得大家进行学习的。
作者:测试安静
来源:http://www.51testing.com/html/97/n-4480397.html