提交 bc4717f7 编写于 作者: 泰斯特Test's avatar 泰斯特Test

Lets go

上级 70693450
# testcase-automaker # testcase-automaker
测试用例自动生成器 测试用例自动生成器
testcase-automaker can be used to create interface testcase with different params combo base on pairwise strategy.
installation
pip install allpairspy
best practice
from src.autotest_tools.interface.http_params_generator import http_params_generator
params_structure = {
'name': {
'type': 'string',
'value': '',
'range': ['张三', '李四'],
'iscompulsory': True
},
'phone': {
'type': 'number',
'value': '',
'iscompulsory': True
},
'claimant': {
'type': 'object',
'value': {
'name': {
'type': 'string',
'value': '',
'iscompulsory': True
},
'phone': {
'type': 'number',
'value': '',
'iscompulsory': True
}
},
'iscompulsory': True
},
'informations': {
'type': 'array',
'value': [{
'claimant': {
'type': 'object',
'value': {
'name': {
'type': 'string',
'value': '',
'iscompulsory': True
},
'phone': {
'type': 'number',
'value': '',
'iscompulsory': True
}
},
'iscompulsory': True
}
},
{
'name': {
'type': 'string',
'value': '',
'iscompulsory': True
}
}
],
'iscompulsory': True
}
}
if __name__ == '__main__':
params_generator = http_params_generator(parameters_structure=params_structure)
params_list = params_generator.generate_params_list()
print(params_generator.generated_params_list)
run the script then u may get output like this:
[{'name': '李四', 'phone': 15746159038, 'claimant': {'name': '华蔹绍', 'phone': 15698064521}, 'informations': [{'claimant': {'name': '齐檠', 'phone': 18912976530}}, {'name': '翟伽硝'}]}, {'name': '张三', 'phone': None, 'claimant': {'name': None, 'phone': None}, 'informations': [{'claimant': {'name': None, 'phone': None}}, {'name': '莫僖烹'}]}, {'name': '李四', 'phone': 18557203961, 'claimant': {'name': None, 'phone': 13736054179}, 'informations': [{'claimant': {'name': None, 'phone': 18810456792}}, {'name': None}]}, {'name': '李四', 'phone': None, 'claimant': {'name': '浦农', 'phone': None}, 'informations': [{'claimant': {'name': '阴桎煅', 'phone': None}}, {'name': None}]}, {'name': '张三', 'phone': None, 'claimant': {'name': None, 'phone': 18238590241}, 'informations': [{'claimant': {'name': '弓肓', 'phone': None}}, {'name': None}]}, {'name': '张三', 'phone': 18265714928, 'claimant': {'name': '昝胀噎', 'phone': None}, 'informations': [{'claimant': {'name': '应兰仓', 'phone': None}}, {'name': None}]}, {'name': '李四', 'phone': None, 'claimant': {'name': '毋羹', 'phone': None}, 'informations': [{'claimant': {'name': None, 'phone': 15701289735}}, {'name': None}]}]
Process finished with exit code 0
which is a list that contains the params combo base on pairwise and the given params structure
Contact me
523314409@qq.com
\ No newline at end of file
# -*- coding: UTF-8 -*-
import string
import random
def get_random_phone_num():
num_start = ['134', '135', '136', '137', '138', '139', '150', '151', '152', '158', '159', '157', '182', '187', '188',
'147', '130', '131', '132', '155', '156', '185', '186', '133', '153', '180', '189']
start = random.choice(num_start)
end = ''.join(random.sample(string.digits, 8))
phone_num = start+end
return phone_num
def get_random_chinese_word():
head = random.randint(0xb0, 0xf7)
body = random.randint(0xa1, 0xfe)
val = f'{head:x}{body:x}'
random_chinese_word = bytes.fromhex(val).decode('gbk')
return random_chinese_word
def get_random_str(length=8, str_type='default'):
if str_type.lower() == 'default':
random_str = ''.join(random.sample(string.ascii_letters + string.digits, length))
return str(random_str)
if str_type.lower() == 'chinese_word':
random_chinese_word = []
for i in range(length):
random_chinese_word.append(get_random_chinese_word())
return ''.join(random_chinese_word)
if str_type.lower() == 'chinese_name':
chinese_last_name_list = ['赵', '钱', '孙', '李', '周', '吴', '郑', '王', '冯', '陈', '褚', '卫', '蒋', '沈', '韩', '杨', '朱', '秦', '尤', '许', '何', '吕', '施', '张', '孔', '曹', '严', '华', '金', '魏', '陶', '姜', '戚', '谢', '邹', '喻', '柏', '水', '窦', '章', '云', '苏', '潘', '葛', '奚', '范', '彭', '郎', '鲁', '韦', '昌', '马', '苗', '凤', '花', '方', '俞', '任', '袁', '柳', '酆', '鲍', '史', '唐', '费', '廉', '岑', '薛', '雷', '贺', '倪', '汤', '滕', '殷', '罗', '毕', '郝', '邬', '安', '常', '乐', '于', '时', '傅', '皮', '卞', '齐', '康', '伍', '余', '元', '卜', '顾', '孟', '平', '黄', '和', '穆', '萧', '尹', '姚', '邵', '湛', '汪', '祁', '毛', '禹', '狄', '米', '贝', '明', '臧', '计', '伏', '成', '戴', '谈', '宋', '茅', '庞', '熊', '纪', '舒', '屈', '项', '祝', '董', '粱', '杜', '阮', '蓝', '闵', '席', '季', '麻', '强', '贾', '路', '娄', '危', '江', '童', '颜', '郭', '梅', '盛', '林', '刁', '钟', '徐', '邱', '骆', '高', '夏', '蔡', '田', '樊', '胡', '凌', '霍', '虞', '万', '支', '柯', '昝', '管', '卢', '莫', '经', '房', '裘', '缪', '干', '解', '应', '宗', '丁', '宣', '贲', '邓', '郁', '单', '杭', '洪', '包', '诸', '左', '石', '崔', '吉', '钮', '龚', '程', '嵇', '邢', '滑', '裴', '陆', '荣', '翁', '荀', '羊', '於', '惠', '甄', '麴', '家', '封', '芮', '羿', '储', '靳', '汲', '邴', '糜', '松', '井', '段', '富', '巫', '乌', '焦', '巴', '弓', '牧', '隗', '山', '谷', '车', '侯', '宓', '蓬', '全', '郗', '班', '仰', '秋', '仲', '伊', '宫', '宁', '仇', '栾', '暴', '甘', '钭', '厉', '戎', '祖', '武', '符', '刘', '景', '詹', '束', '龙', '叶', '幸', '司', '韶', '郜', '黎', '蓟', '薄', '印', '宿', '白', '怀', '蒲', '邰', '从', '鄂', '索', '咸', '籍', '赖', '卓', '蔺', '屠', '蒙', '池', '乔', '阴', '欎', '胥', '能', '苍', '双', '闻', '莘', '党', '翟', '谭', '贡', '劳', '逄', '姬', '申', '扶', '堵', '冉', '宰', '郦', '雍', '舄', '璩', '桑', '桂', '濮', '牛', '寿', '通', '边', '扈', '燕', '冀', '郏', '浦', '尚', '农', '温', '别', '庄', '晏', '柴', '瞿', '阎', '充', '慕', '连', '茹', '习', '宦', '艾', '鱼', '容', '向', '古', '易', '慎', '戈', '廖', '庾', '终', '暨', '居', '衡', '步', '都', '耿', '满', '弘', '匡', '国', '文', '寇', '广', '禄', '阙', '东', '殴', '殳', '沃', '利', '蔚', '越', '夔', '隆', '师', '巩', '厍', '聂', '晁', '勾', '敖', '融', '冷', '訾', '辛', '阚', '那', '简', '饶', '空', '曾', '毋', '沙', '乜', '养', '鞠', '须', '丰', '巢', '关', '蒯', '相', '查', '後', '荆', '红', '游', '竺', '权', '逯', '盖', '益', '桓', '公', '万俟', '司马', '上官', '欧阳', '夏侯', '诸葛', '闻人', '东方', '赫连', '皇甫', '尉迟', '公羊', '澹台', '公冶', '宗政', '濮阳', '淳于', '单于', '太叔', '申屠', '公孙', '仲孙', '轩辕', '令狐', '钟离', '宇文', '长孙', '慕容', '鲜于', '闾丘', '司徒', '司空', '亓官', '司寇', '仉', '督', '子车', '颛孙', '端木', '巫马', '公西', '漆雕', '乐正', '壤驷', '公良', '拓跋', '夹谷', '宰父', '谷梁', '晋', '楚', '闫', '法', '汝', '鄢', '涂', '钦', '段干', '百里', '东郭', '南门', '呼延', '归', '海', '羊舌', '微生', '岳', '帅', '缑', '亢', '况', '后', '有', '琴', '梁丘', '左丘', '东门', '西门', '商', '牟', '佘', '佴', '伯', '赏', '南宫', '墨', '哈', '谯', '笪', '年', '爱', '阳', '佟']
random_chinese_name = []
random_chinese_name.append(random.choice(chinese_last_name_list))
for i in range(random.choice([1, 2])):
random_chinese_name.append(get_random_chinese_word())
return ''.join(random_chinese_name)
def get_random_num(length=8, num_type='default', eliminated_nums=None):
if length < 1:
raise ValueError
if eliminated_nums is None:
eliminated_nums = []
if num_type.lower() == 'chinese_mobile_phone':
return int(get_random_phone_num())
num_list = list(map(int, list(string.digits)))
for num in eliminated_nums:
num_list.remove(num)
seed = num_list
random_num = []
for i in range(length):
random_num.append(random.choice(seed))
if num_type.lower() == 'default':
return int(''.join([str(num) for num in random_num]))
def get_random_boolean():
random_boolean = random.choice([True, False])
return random_boolean
if __name__ == '__main__':
print(get_random_num(length=5, eliminated_nums=[0,1,2,3,4,5]))
print(get_random_str(str_type='chinese_word'))
print(get_random_str(str_type='chinese_name'))
print(get_random_boolean())
from ptest.assertion import assert_equals, fail
from ptest.plogger import preporter
import json
def request(url, method, json_data=None, session=None, headers=None, assertion=None):
data = ''
status_code = ''
req_json = ''
try:
text = session.request(url=url, method=method, json=json_data, headers=headers).text
if len(text) <= 1000:
preporter.info(text)
req_json = json.loads(text)
status_code = req_json["status"]
data = req_json["data"]
preporter.info('接口返回status为:' + str(status_code))
if len(str(data)) >= 3000:
preporter.info('接口返回data为(限制长度为3000):' + str(data)[0:3000])
else:
preporter.info('接口返回data为:' + str(data))
except BaseException:
if not assertion:
fail('无法获取status或data!')
else:
key = assertion.keys()
assert_equals(assertion[key], req_json[key])
finally:
if not assertion:
if not status_code == 'ok':
preporter.error('接口响应:' + str(req_json))
else:
assert_equals(status_code, 'ok')
assert_equals(status_code, 'ok')
if data is not None:
return data
import sys
sys.path.append("../..")
from Utils.amazingutils import randoms
from allpairspy import AllPairs
import random
import copy
class http_params_generator(object):
'''
>>> params_generator = http_params_generator(parameters_structure={'name': {'type': 'string', 'value': '','range':['张三','李四'], 'iscompulsory': True},\
'phone': {'type': 'number', 'value': '', 'iscompulsory': True},\
'claimant': {'type': 'object', 'value': {'name': {'type': 'string', 'value': '', 'iscompulsory': True}\
,'phone': {'type': 'number', 'value': '', 'iscompulsory': True}}, 'iscompulsory': True},\
'informations': {'type': 'array', 'value': [{'claimant': {'type': 'object', 'value': {'name': {'type': 'string', 'value': '', 'iscompulsory': True}\
,'phone': {'type': 'number', 'value': '', 'iscompulsory': True}}, 'iscompulsory': True}},\
{'name': {'type': 'string', 'value': '', 'iscompulsory': True}}], 'iscompulsory': True}})
>>> params_generator.get_params_num()
7
>>> params_generator.generate_params_list()
>>> type(params_generator.generated_params_list)
<class 'list'>
>>> type(random.choice(params_generator.generated_params_list))
<class 'dict'>
>>> len(params_generator.generated_params_list)
7
>>> params_generator = http_params_generator(parameters_structure={})
>>> params_generator.get_params_num()
0
>>> params_generator.generate_params_list()
>>> type(params_generator.generated_params_list)
<class 'list'>
>>> len(params_generator.generated_params_list)
0
'''
def __init__(self, parameters_structure, generated_params_list=None):
self.parameters_structure = parameters_structure
self.generated_params_list = generated_params_list
# 生成参数组合列表
def generate_params_list(self):
parameters = http_params_generator.get_pairwise_list(self.get_params_num())
params_usage_2d_list = []
params_combo_list = []
if len(parameters) > 1:
for pairs in AllPairs(parameters):
params_usage_2d_list.append(pairs)
for params_usage_list in params_usage_2d_list:
yield_params_usage_list = http_params_generator.yield_list(params_usage_list)
raw_params_list = self.generate_params(parameters_usage_list=yield_params_usage_list)
prepared_params_list = http_params_generator.get_value_dic(raw_params_list)
params_combo_list.append(prepared_params_list)
elif len(parameters) == 1: # 当只有一个参数的时候第三方库ALLPAIRS不支持
yield_params_usage_list_true = http_params_generator.yield_list([True])
yield_params_usage_list_false = http_params_generator.yield_list([False])
raw_params_list_true = self.generate_params(parameters_usage_list=yield_params_usage_list_true)
prepared_params_list_true = http_params_generator.get_value_dic(raw_params_list_true)
raw_params_list_false = self.generate_params(parameters_usage_list=yield_params_usage_list_false)
prepared_params_list_false = http_params_generator.get_value_dic(raw_params_list_false)
params_combo_list.append(prepared_params_list_true)
params_combo_list.append(prepared_params_list_false)
# params_combo_set = [el.replace("'", "\"") for el in set(map(str, params_combo_list))]
# print(params_combo_set)
# params_combo_set = list(map(json.loads, params_combo_set))
self.generated_params_list = params_combo_list
# 生成参数
def generate_params(self, parameters_usage_list, parameters_structure=None):
if parameters_structure is None:
parameters_structure = copy.deepcopy(self.parameters_structure)
for key, attribute in parameters_structure.items():
type_name = attribute['type']
if type_name.lower() == 'object':
self.generate_params(parameters_structure=attribute['value'],
parameters_usage_list=parameters_usage_list)
continue
if type_name.lower() == 'array':
for value in attribute['value']:
self.generate_params(parameters_structure=value,
parameters_usage_list=parameters_usage_list)
continue
type_category = self.get_type_category(key)
if 'range' in attribute and attribute['range']:
generated_value = random.choice(attribute['range'])
else:
generated_value = self.get_parameter_random_value(type_name, type_category)
if next(parameters_usage_list) or ('range' in attribute and attribute['range']):
parameters_structure[key]['value'] = generated_value
else:
parameters_structure[key]['value'] = None
return parameters_structure
def get_params_num(self, parameters_structure=None, num=0):
if parameters_structure is None:
parameters_structure = copy.deepcopy(self.parameters_structure)
for key, attribute in parameters_structure.items():
type_name = attribute['type']
if type_name.lower() == 'object':
num += self.get_params_num(attribute['value'])
continue
if type_name.lower() == 'array':
for value in attribute['value']:
num += self.get_params_num(value)
continue
else:
num += 1
return num
# 比较两个字典部分是否相等
@staticmethod
def remove_duplicated_dict_in_list(dic_list):
for dic in dic_list:
pass
@staticmethod
def yield_list(input_list):
for i in input_list:
yield i
@staticmethod
def get_pairwise_list(params_num):
parameters = []
for i in range(params_num):
parameters.append([True, False])
return parameters
# 返回仅提取输入字典值中的value的值作为当前键的值的字典
@staticmethod
def get_value_dic(dic):
new_dic = dict()
for key, attribute in dic.items():
if attribute['type'].lower() == 'object':
new_dic[key] = http_params_generator.get_value_dic(attribute['value'])
continue
if attribute['type'].lower() == 'array':
new_dic[key] = []
for value in attribute['value']:
new_dic[key].append(http_params_generator.get_value_dic(value))
continue
new_dic[key] = attribute['value']
return new_dic
# 根据键名生成数据类别
@staticmethod
def get_type_category(key):
if key == 'phone':
return 'chinese_mobile_phone'
if key == 'name':
return 'chinese_name'
else:
return 'default'
# 根据数据类型以及数据类型的类别生成随机数据
@staticmethod
def get_parameter_random_value(type_name, type_category='default'):
if type_name.lower() == 'boolean':
return randoms.get_random_boolean()
if type_name.lower() == 'number':
return randoms.get_random_num(num_type=type_category)
if type_name.lower() == 'string':
return randoms.get_random_str(str_type=type_category)
if type_name.lower() == 'date':
return randoms.get_random_num(length=9)
else:
return None
if __name__ == '__main__':
import doctest
doctest.testmod()
import sys
sys.path.append("../..")
from src.autotest_tools.interface.http_params_generator import http_params_generator
from Utils import httptools
from ptest.plogger import preporter
import requests
import copy
import random
class http_tester(object):
'''
>>> tester = http_tester(url='http://www.baidu.com', method='get',\
parameters_structure={'name': {'type': 'string', 'value': '', 'iscompulsory': True},\
'phone': {'type': 'number', 'value': '', 'iscompulsory': True}})
>>> type(tester.pre_send_params_list)
<class 'list'>
>>> type(random.choice(tester.pre_send_params_list))
<class 'dict'>
>>> type(tester.url_list_for_method_get)
<class 'list'>
>>> tester.url in random.choice(tester.url_list_for_method_get)
True
>>> tester = http_tester(url='http://www.baidu.com', method='get',parameters_structure={})
>>> len(tester.url_list_for_method_get)
1
>>> tester.url_list_for_method_get[0] == tester.url
True
'''
def __init__(self, url, method, parameters_structure=None, session=None, headers=None):
self.url = url
self.method = method
self.parameters_structure = parameters_structure
self.session = session
self.headers = headers
if session is None:
self.session = requests.Session()
if parameters_structure is None:
self.parameters_structure = dict()
if isinstance(self.parameters_structure, dict):
params_generator = http_params_generator(parameters_structure=self.parameters_structure)
params_generator.generate_params_list()
self.pre_send_params_list = params_generator.generated_params_list
else:
self.pre_send_params_list = None
raise Exception('parameters_structure is not a dict!')
# 若方法为get, 则构建请求url列表
if self.pre_send_params_list is not None and self.method.lower() == 'get':
url_list = []
if self.pre_send_params_list:
for pre_send_params in self.pre_send_params_list:
url = copy.deepcopy(self.url)
url += '?'
for key, value in pre_send_params.items():
if value is not None:
url += str(key) + '=' + str(value) + '&'
url = url[0:(len(url) - 1)]
url_list.append(url)
else:
url_list.append(self.url)
self.url_list_for_method_get = url_list
# 执行测试, 目前依附于ptest测试框架
def exec_test(self, assertion=None):
self.returned_data = []
if self.method.lower() == 'get':
for url in self.url_list_for_method_get:
preporter.info('\n\n正在请求: ' + url + '\n\n')
self.returned_data.append(httptools.request(url=url, method=self.method, session=self.session, headers=self.headers,
assertion=assertion))
else:
if len(self.pre_send_params_list) > 0:
for pre_send_params in self.pre_send_params_list:
preporter.info('\n\n正在请求: ' + self.url + '\n\n' + '当前请求参数: ' + str(pre_send_params) + '\n\n')
self.returned_data.append(httptools.request(url=self.url, method=self.method, json_data=pre_send_params,
session=self.session, headers=self.headers, assertion=assertion))
else:
preporter.info('\n\n正在请求: ' + self.url + '\n\n')
self.returned_data.append(httptools.request(url=self.url, method=self.method,
session=self.session, headers=self.headers, assertion=assertion))
if __name__ == '__main__':
import doctest
doctest.testmod()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册