开发环境: pycharm + python3.6 + requests +pyunit
解决方案: 在XML里面配置每一个API接口的测试用例,url,httpmethod,可配置多组测试数据,断言等等。工具解析XML里的测试数据,并将每个testcase的相关数据传递给统一的接口执行测试。这样无论是修改或者新增API测试用例,只需要维护XML文件即可。
相关源码:
xml文件示例:
<testcases>
<testcase name="kuaidi100">
<url>http://www.kuaidi100.com/query</url>
<method>get</method>
<data>
<type>shentong</type>
<postid>123124241</postid>
</data>
<data>
<type>ems</type>
<postid>123124241</postid>
</data>
</testcase>
<testcase name="GetIpInfo">
<url>http://ip.taobao.com/service/getIpInfo.php</url>
<method>get</method>
<data>
<ip>14.215.177.38</ip>
</data>
<data>
<ip>14.215.177.39</ip>
</data>
</testcase>
</testcases>
解析XML相关代码:
def parseTestCasesFromXML(self,xmlFilePath):
#开始解析XML内容,并组装测试数据
doc = ElementTree.parse(xmlFilePath)
#遍历xml文件中的所有testcase节点
testcases = doc.findall("/testcase")
test_cases_data=[]
for test_case in testcases:
url=None;method=None;data=[]
for child in test_case:
if child.tag =='url':
#获取API的URL
url=child.text
if child.tag == 'method':
#获取HTTP的访问方法。如:get,post,input.del等
method = child.text
if child.tag == 'data':
#读取测试数据,一个case可以组装多组测试用例
#Need do: 支持断言
test_data={}
for dataNode in child:
key = dataNode.tag
value = dataNode.text
test_data[key]=value
data.append(test_data)
test_case_data ={}
test_case_data['url']=url
test_case_data['method']=method
test_case_data['data']=data
test_cases_data.append(test_case_data)
return test_cases_data
unitTestCase:
class BaseTest(unittest.TestCase):
"""
需要参数化的TestCase类必须继承BaseTest这个类
"""
def __init__(self, methodName='runTest', param=None):
super(BaseTest, self).__init__(methodName)
self.param = param
@staticmethod
def parametrize(testcase_classname, param=None):
"""
将所有的测试用例装载到用一个Suite里面
"""
testloader = unittest.TestLoader()
testnames = testloader.getTestCaseNames(testcase_classname)
suite = unittest.TestSuite()
for name in testnames:
suite.addTest(testcase_classname(name, param=param))
return suite
class TestAPI(BaseTest):
def do_get(self,url,data):
"""
执行HTTP get请求
:param url:
:param data:
:return:
"""
res = requests.get(url, params=data)
def do_post(selfsef,url,data):
"""
执行HTTP Post请求
:param url:
:param data:
:return:
"""
res = requests.post(url,data)
def test_run_testcase(self):
"""
所有的测试用例统一执行这一个测试用例
:return:
"""
test_data = self.param
url = test_data['url']
method = test_data['method']
test_datas= test_data['data']
for data in test_datas:
if 'get' == method:
self.do_get(url,data)
def suite(test_data_list):
"""
组装测试用例
:param test_data_list:
:return:
"""
suite = unittest.TestSuite()
for test_data in test_data_list:
suite.addTest(BaseTest.parametrize(TestAPI, param=test_data))
#执行测试
#Need do: 生成可视化Report
unittest.TextTestRunner(verbosity=2).run(suite)
if __name__=='__main__':
test_data_file_path = os.getcwd() + "/data.xml"
test_data_list = xmlutil.ParseXML().parseTestCasesFromXML(test_data_file_path)
suite(test_data_list)
优点: 不用写测试用例,减少维护成本。
缺点:因为执行的是统一的接口(TestAPI.test_run_testcase),测试报告不够直观,需要优化。