本文为博主原创,未经授权,严禁转载及使用。
本文链接:https://blog.csdn.net/zyooooxie/article/details/95355201
一过年,zfb的集五福就来了。刚巧,我之前做了个类似的需求,我测了 分享卡片 这一部分,就来说说我的感受。
【实际这篇博客推迟发布N个月】
个人博客:https://blog.csdn.net/zyooooxie
【以下所有内容仅为个人项目经历,如有不同,纯属正常】
需求:分享卡片
活动规则:活动中,用户获得的福卡可向好友赠送、也可以向好友求赠未获得的福卡。
换言之,分享场景就2种:
- 送卡【主态】-领卡【客态】
自己拥有的福卡,选择【送给好友】;好友接受、领取我的福卡;
- 要卡【主态】-赠卡【客态】
自己缺少某种福卡时,选择向好友求助【请好友赠一张】;好友将其福卡 赠送给我;
需求分析
其实我在写 测试分享的博客 https://blog.csdn.net/zyooooxie/category_11185390.html ,从来不会写啥需求分析,我觉得鸡肋【看懂我博客的,不太可能是刚入行的】。
但是这个分享功能,我是真的被绕死了,用例写的我头疼。
要提前说一点:zfb的分享是 以某张卡为维度;我的需求是 以某种卡为维度。
简单说:zfb送卡,送的是某类卡的具体某张;我的需求是 送某类卡;
一般来看,分享功能的测试点:
A分享给B,B可能是一个用户,也可能是一群用户;
A分享给B,分享次数可能是1次,也可能是多次;
A分享给B,可能是送卡,也可能是要卡;
A分享给B,分享的是同一种卡,也可能是多种卡;
换个角度说:
一、用户的状态:
- 未参与活动的;
- 参与活动【初期】,未集齐五类卡;
- 参与活动【中期】,已经集齐五类卡,但未合成福卡;
- 参与活动【后期】,已经集齐五类卡,且已合成福卡;
二、用户分享的情景 - 送卡:
-
1对1 – 主态、客态都是1个用户
情景1:主态分享1种卡;
情景2:主态分享多种卡; -
1对多 – 主态1个用户,客态多位用户
情景3:主态分享1种卡;
情景4:主态分享多种卡; -
多对多 – 主态多个用户,客态多位用户
复杂版的1对多;
再继续往下,就是分享次数了 【分享1次 + 分享多次】。
再继续往下,就是客态 实际访问的分享链接【分享多次时】。
测试用例
以 送卡 – 主态是已集齐、未合成 举例:
其他规则、分享流程
其他规则:每张卡的第一张不允许赠送;每人最多可给5位好友赠送卡片,且每人最多可领取一次好友赠送的卡片。
分享流程:
- 用户 选【送卡】、【送我一张卡】;实际会请求接口genShareUrl,后台生成一条flowId;
- 其他用户访问 此分享链接后,送卡、领卡,实际会请求接口sendCard、receiveCard 【Referer的值 要做定制,传参有flowId】;
代码
(代码有删改)
"""
@blog: https://blog.csdn.net/zyooooxie
"""
class NewYear2(NewYear):
def __init__(self, txt_read_rows: int, txt_skip_row: int):
super().__init__(txt_read_rows=txt_read_rows, txt_skip_row=txt_skip_row)
assert self.use_rows >= 2
self.__db, self.__cur = connect_db(zyooooxie_db='yes')
print(self.__db, self.__cur, '连接')
def __del__(self):
print(self.__db, self.__cur, '关闭')
self.__cur.close()
self.__db.close()
@property
def p_db(self):
"""
:return:
"""
return self.__db
@property
def p_cur(self):
"""
:return:
"""
return self.__cur
def get_flow_id(self, user_id: str, user_session: str, flow_type: int, card_name: str):
"""
:param user_id:
:param user_session:
:param flow_type:1、2
:param card_name:大写
:return:
"""
time.sleep(1)
url = self.join_url(url='https://blog.csdn.net/zyooooxie/genShareUrl')
Log.info('genShareUrl的传参:{}'.format({'cardName': card_name, 'type': flow_type}))
res = self.send_request(url, session=user_session, params_dict={'cardName': card_name, 'type': flow_type})
res = res.json()
if isinstance(res, dict):
if not res.get('success'):
Log.debug('genShareUrl请求返回值 失败:{}'.format(res))
else:
assert res.get('obj').get('shareUrl').find('zyooooxie') != -1
if flow_type == 1:
Log.info('1-送卡')
sql1 = """SELECT id, uuid, circulation_times FROM table_newyear_cr WHERE user_id ='{}' AND card_name = '{}'AND `status` <> 3 ORDER BY id ASC ;""".format(user_id, card_name)
# sql1_data = fetchall_data_no_close(sql1, self.__db, self.__cur)
sql1_data = fetch_sql(sql1, self.__db, self.__cur, fetch_mode='fetchall')
*args, sql1_card_uuid, sql1_circulation_times = sql1_data[1]
sql2 = """SELECT flow_id, circulation_times,create_time FROM table_newyear_csrf WHERE user_id ='{}' AND card_uuid = '{}' and type = 1 AND `status` = 0 ORDER BY create_time DESC;""".format(user_id, sql1_card_uuid)
# sql2_data = fetchone_data_no_close(sql2, self.__db, self.__cur)
sql2_data = fetch_sql(sql2, self.__db, self.__cur, fetch_mode='fetchone')
if sql2_data is None:
Log.error('没有查到对应的flow_id :{}'.format(sql2_data))
raise
Log.debug('flow_id,circulation_times,create_time:{}'.format(sql2_data))
sql2_flow_id, *args = sql2_data
else:
assert flow_type == 2
Log.info('2-要卡')
sql2 = """SELECT flow_id, circulation_times,create_time FROM table_newyear_csrf WHERE user_id ='{}' AND card_name = '{}' and type = 2 AND `status` = 0 ORDER BY create_time DESC;""".format(user_id, card_name)
# sql2_data = fetchone_data_no_close(sql2, self.__db, self.__cur)
sql2_data = fetch_sql(sql2, self.__db, self.__cur, fetch_mode='fetchone')
Log.debug('flow_id,circulation_times,create_time:{}'.format(sql2_data))
sql2_flow_id, *args = sql2_data
Log.info('表里的flow_id:{}'.format(sql2_flow_id))
return sql2_flow_id
else:
raise Exception('res 有异常:{}'.format(res))
@staticmethod
def create_referer(ke_phone: str, ke_user_id: str, ke_session: str, flow_type: int, flow_id: str):
"""
组装Referer
:param ke_phone:
:param ke_user_id:
:param ke_session:
:param flow_type:
:param flow_id:
:return:
"""
redirect = 'https://blog.csdn.net/zyooooxie?redirectUri=/zyooooxie'
mobile = '****'.join([ke_phone[:3], ke_phone[-4:]])
referer = '&'.join([redirect, 'mobile={}'.format(mobile), 'userId={}'.format(ke_user_id), 'token={}'.format(ke_session),
'type={}'.format(flow_type), 'flowId={}'.format(flow_id)])
Log.debug('Referer:{}'.format(referer))
return referer
def request_receive_card(self, flow_id: str, ke_session: str, referer: str):
"""
receiveCard
:param flow_id:
:param ke_session:
:param referer:
:return:
"""
url = self.join_url('https://blog.csdn.net/zyooooxie/receiveCard')
return self.send_request(url, ke_session, {'flowId': flow_id}, {'Referer': referer})
def request_send_card(self, flow_id: str, ke_session: str, referer: str):
"""
sendCard
:param flow_id:
:param ke_session:
:param referer:
:return:
"""
url = self.join_url('https://blog.csdn.net/zyooooxie/sendCard')
return self.send_request(url, ke_session, {'flowId': flow_id}, {'Referer': referer})
def share_card_func(self, zhu_user_id: str, zhu_session: str, flow_type: int, card_name: str,
ke_user_id: str, ke_phone: str, ke_session: str, flow_id: str = None):
"""
卡片分享功能
:param zhu_user_id:
:param zhu_session:
:param flow_type:
:param card_name:大写
:param ke_user_id:
:param ke_phone:
:param ke_session:
:param flow_id:
:return:
"""
# 取到主态的flow_id;组装客态referer;客态发赠卡、领卡的请求;
if flow_id is None:
flow_id = self.get_flow_id(user_id=zhu_user_id, user_session=zhu_session, flow_type=flow_type,
card_name=card_name)
Log.info('{}-{}'.format(flow_id, card_name))
referer = self.create_referer(ke_phone=ke_phone, ke_user_id=ke_user_id, ke_session=ke_session,
flow_type=flow_type, flow_id=flow_id)
if flow_type == 1:
return self.request_receive_card(flow_id=flow_id, ke_session=ke_session, referer=referer)
else:
return self.request_send_card(flow_id=flow_id, ke_session=ke_session, referer=referer)
def user_join_activity(self, user_id: str, user_phone: str, user_session: str = None, join_result: int = None):
"""
用户参加活动 不同状态
:param user_id:
:param user_phone:
:param user_session:
:param join_result:
:return:
"""
if join_result is None:
join_result = random.getrandbits(2)
else:
Log.info('result:{}'.format(join_result))
if user_session is None:
user_session = self.get_session_id(user_id, user_phone)
if join_result == 0: # 不可合成
times = random.randint(1, 6)
Log.info('{} 参加活动、抽奖{}次'.format(user_id, times))
self.draw(times, user_id=user_id, phone=user_phone, db=self.__db, cur=self.__cur, session=user_session)
elif join_result == 1: # 未参与活动
Log.info('{} 清数据、未参加过活动'.format(user_id))
self.delete_data(user_id=user_id, dd_db_info=self.__db, dd_cur_info=self.__cur)
elif join_result == 2: # 集齐、不合成
times = random.randint(35, 39)
Log.info('{} 参加过活动、抽奖{}次'.format(user_id, times))
self.draw(times, user_id=user_id, phone=user_phone, db=self.__db, cur=self.__cur, session=user_session)
self.get_user_cards(user_id=user_id, user_session=user_session, collect_check='YES')
else: # 集齐、已合成
times = random.randint(41, 45)
Log.info('{} 参加过活动、抽奖{}次'.format(user_id, times))
self.draw(times, user_id=user_id, phone=user_phone, db=self.__db, cur=self.__cur, session=user_session)
self.synthetic_func(user_id=user_id, user_session=user_session, no_synthetic_check='YES')
return user_session, join_result
def get_user_cards(self, user_id: str, user_session: str, table_api_data_check: bool = True,
only_send_request: str = None,
collect_check: str = None,
synthetic_check: str = None):
"""
获取用户的卡片dict;
:param user_id:
:param user_session:
:param table_api_data_check: 检查接口返回值 和 表的值;默认 检查;
:param only_send_request: 只发请求-返回 响应dict
:param collect_check:集齐未合成
:param synthetic_check:已合成
:return:
"""
query_url = self.join_url('https://blog.csdn.net/zyooooxie/queryUserInfo')
res = self.send_request(query_url, session=user_session, params_dict={})
res_dict = res.json()
if only_send_request is not None:
return res_dict
obj_dict = res_dict.get('obj')
synthetic = obj_dict.get('synthetic')
if isinstance(obj_dict, dict):
card_dict = {k: v for k, v in obj_dict.items() if k.find('Card') != -1} # key的名字包括Card
if len(card_dict) == 0:
card_dict_all = dict()
else:
card_dict_all = {self.change_card_name(card): card_dict.get(card) for card in card_dict}
Log.info('【接口】卡详情:{}'.format(card_dict_all))
else:
raise Exception('res异常:{}'.format(res_dict))
if table_api_data_check:
sql1 = """SELECT hx_card, ry_card, ky_card, ty_card, fd_card FROM table_newyear_ui WHERE user_id = '{}';""".format(user_id)
# data_sql = fetchone_data_no_close(sql1, self.__db, self.__cur)
data_sql = fetch_sql(sql1, self.__db, self.__cur, fetch_mode='fetchone')
if data_sql is not None:
card_dict_3 = {'HXK_KN': data_sql[0], 'RYK_KN': data_sql[1], 'KYK_KN': data_sql[2],
'TYK_KN': data_sql[3], 'FDK_KN': data_sql[4]}
Log.info('【表】卡详情:{}'.format(card_dict_3))
# sql查询结果 和 接口返回结果 要一致
assert len(card_dict_all) == len(card_dict_3)
for k in card_dict_3.keys() | card_dict_all.keys():
assert card_dict_3.get(k) == card_dict_all.get(k)
else:
Log.info('【表】此用户无数据:{}'.format(data_sql))
card_dict_4 = {}
assert operator.eq(card_dict_4, card_dict_all) is True
# 过滤掉 卡数为0的
card_dict_send = {k: v for k, v in card_dict_all.items() if v != 0}
if collect_check is not None:
assert synthetic == 0
try:
assert len(card_dict_send) == 5
Log.info('用户已集齐、未合成,pass')
except AssertionError:
Log.info('用户未集齐、未合成,pass')
return
if synthetic_check is not None:
assert synthetic == 1
if synthetic == 0:
# 删除 v为1的key 【未合成时,不可以赠送 只有1张的】
for k in card_dict_all:
if card_dict_send.get(k) == 1:
card_dict_send.pop(k)
elif synthetic == 1:
Log.info('synthetic是 1,用户已合成')
else:
Log.info('synthetic是 None,用户未参加活动')
Log.info('用户的卡【删除不可赠送的】:{}'.format(card_dict_send))
# 全部dict、可赠送的dict
return card_dict_all, card_dict_send, synthetic
def check_zhu_ke_card(self, table_card_name: str, dict_card_name: str,
zhu_user: str, zhu_num: int,
ke_user: str, ke_num: int,
zhu_card_dict: dict,
flow_type: int, response: bool):
"""
检查卡片分享后 主、客态卡片的情况;修改卡片dict;
:param table_card_name:hx_card
:param dict_card_name:HXK_KN
:param zhu_user:
:param zhu_num:
:param ke_user:
:param ke_num:
:param zhu_card_dict:要修改的卡片dict
:param flow_type:
:param response:
:return:
"""
Log.info('主态此种卡的数量【前】:{}'.format(zhu_num))
sql_zhu = """SELECT {} FROM table_newyear_ui WHERE user_id = '{}';""".format(table_card_name, zhu_user)
data_zhu = fetch_sql(sql_zhu, db=self.__db, cur=self.__cur, fetch_mode='fetchone')
Log.info('table_newyear_ui 主态的此种卡的数量:{}'.format(data_zhu))
Log.info('客态此种卡的数量【前】:{}'.format(ke_num))
sql_ke = """SELECT {} FROM table_newyear_ui WHERE user_id = '{}';""".format(table_card_name, ke_user)
data_ke = fetch_sql(sql_ke, db=self.__db, cur=self.__cur, fetch_mode='fetchone')
Log.info('table_newyear_ui 客态的此种卡的数量:{}'.format(data_ke))
if response is False:
Log.debug('分享失败,卡数量不变')
assert (data_ke[0] if data_ke is not None else 0) == (ke_num if ke_num is not None else 0)
assert (data_zhu[0] if data_zhu is not None else 0) == (zhu_num if zhu_num is not None else 0)
else:
if flow_type == 1:
assert data_ke[0] == (ke_num if ke_num is not None else 0) + 1
assert data_zhu[0] == zhu_num - 1
else:
assert flow_type == 2
assert data_ke[0] == ke_num - 1
assert data_zhu[0] == (zhu_num if zhu_num is not None else 0) + 1
Log.info('校验主、客态卡片-pass')
# 修改卡片dict
if response is True:
# data_zhu[0] <= 1 依旧key存在
zhu_card_dict.update({dict_card_name: data_zhu[0]})
Log.info('主态卡dict:{}'.format(zhu_card_dict))
"""
@blog: https://blog.csdn.net/zyooooxie
"""
def create_user_data(self, user_session_dict: dict = None,
user_phone_nickname_list: list = None,
zhu_join: int = None,
ke_join: int = None):
"""
生成数据
:param user_session_dict:非必传;传时要和user_list 一起传
:param user_phone_nickname_list:非必传;传时要和user_session_dict 一起传
:param zhu_join:主态join
:param ke_join:客态join
:return:
"""
# 读取txt文件,获取用户list:index=0是主态,其他为客态;
# 主、客态登录、保存session;
# 根据传的zhu_join、ke_join决定 用户的活动状态; 这样做 很大几率 抽奖接口的响应值异常,但是draw()做了处理。
if user_session_dict is None and user_phone_nickname_list is None:
user_phone_nickname_list = self.get_user_phone_nickname_list()
userId_session_dict = dict()
for ul in user_phone_nickname_list:
session = self.get_session_id(user_id=ul[0], user_phone=str(ul[1]))
userId_session_dict.update({ul[0]: session})
else:
# user_session_dict 、ke_user_phone_list 2者必须都传
assert user_session_dict is not None
assert user_phone_nickname_list is not None
userId_session_dict = user_session_dict
Log.info(user_phone_nickname_list)
Log.info(userId_session_dict)
user_phone_dict = {u[0]: str(u[1]) for u in user_phone_nickname_list}
zhu_user_id = user_phone_nickname_list[0][0]
for user_id, session in userId_session_dict.items():
Log.info('------------------')
ph = user_phone_dict.get(user_id)
if user_id == zhu_user_id and zhu_join is not None:
self.user_join_activity(user_id=user_id, user_phone=ph, user_session=session,
join_result=zhu_join)
elif user_id != zhu_user_id and ke_join is not None:
self.user_join_activity(user_id=user_id, user_phone=ph, user_session=session,
join_result=ke_join)
else:
self.user_join_activity(user_id=user_id, user_phone=ph, user_session=session)
time.sleep(1)
return user_phone_nickname_list, userId_session_dict
def test_many_cards(self, user_phone_list: list, user_session_dict: dict, share_card_same: bool = False,
share_many_times: bool = False, flow_id_list_same: bool = False):
"""
送卡-多卡
:param user_phone_list:
:param user_session_dict:
:param share_card_same:分享的卡 是否相同
:param share_many_times:分享的次数
:param flow_id_list_same:
:return:
"""
Log.info('---------')
zhu_user, zhu_phone, *args = user_phone_list[0]
Log.info('主态:{}'.format(zhu_user))
zhu_session = user_session_dict.get(zhu_user)
zhu_card_dict, zhu_card_dict_send, *args = self.get_user_cards(user_id=zhu_user, user_session=zhu_session)
success_time = 0
if share_card_same: # 所有用户都是相同card
if len(zhu_card_dict_send) != 0:
max_card_num = max(zhu_card_dict_send.values())
card = random.choice(list(filter(lambda x: zhu_card_dict_send[x] == max_card_num, zhu_card_dict_send)))
print(card, '卡相同 != 0')
else:
card = random.choice(self.card_name_list)
print(card, '卡相同 == 0')
card_list = [card] * 4
else:
abc = (list(zhu_card_dict_send.keys()) if len(zhu_card_dict_send) != 0 else self.card_name_list) * 5
random.shuffle(abc)
card_list = abc[:3] + abc[:1] # 加个出现过的
print('卡不同')
Log.info('此次分享的card_list:{}'.format(card_list))
random.shuffle(user_phone_list)
for ul in user_phone_list: # 增加 主态用户为客态的情形
# for ul in user_phone_list[1:]:
Log.info('---------')
Log.info('客态:{}'.format(ul[0]))
ke_session = user_session_dict.get(ul[0])
if ul[0] != zhu_user:
ke_card_dict, *args = self.get_user_cards(user_id=ul[0], user_session=ke_session)
else:
Log.info('此客态是 主态用户')
ke_card_dict = zhu_card_dict
Log.info('客态卡详情:{}'.format(ke_card_dict))
for cl in card_list:
Log.info('--{}--'.format(cl))
result = random.getrandbits(1)
print(result)
# 使用相同的flow_id_list 还要留意card是否匹配:很多次校验卡时报错
if flow_id_list_same and locals().get('flow_id_list') is not None and random.choice([True, True, True, False]) is True:
Log.info('使用相同的flow_id_list:{}'.format(flow_id_list))
check_card = True
else:
check_card = False
if share_many_times is False: # flow_id 1条
flow_id = self.func1(result=result, zhu_user=zhu_user, zhu_session=zhu_session, cl=cl, ul=ul,
ke_session=ke_session)
flow_id_list = [flow_id]
else:
flow_id_list = [self.func1(result=result, zhu_user=zhu_user, zhu_session=zhu_session, cl=cl, ul=ul, ke_session=ke_session) for _ in range(2)]
flow_id_list *= 2
random.shuffle(flow_id_list)
Log.info(flow_id_list)
for fil in flow_id_list:
if result:
ft = 1
# res = self.share_card_func(zhu_user_id=zhu_user, zhu_session=zhu_session,
# flow_type=1, card_name=cl,
# ke_user_id=ul[0], ke_phone=str(ul[1]), ke_session=ke_session,
# flow_id=fil)
else:
ft = 2
# res = self.share_card_func(zhu_user_id=ul[0], zhu_session=ke_session,
# flow_type=2, card_name=cl,
# ke_user_id=zhu_user, ke_phone=str(zhu_phone),
# ke_session=zhu_session,
# flow_id=fil)
if check_card and len(set(card_list)) != 1:
sql = """ SELECT card_name FROM table_newyear_csrf WHERE flow_id ='{}'; """.format(fil)
sql_data = fetch_sql(sql=sql, db=self.__db, cur=self.__cur, fetch_mode='fetchone')
Log.info('card_name:{}'.format(sql_data))
cl = (sql_data[0] if sql_data is not None else cl)
Log.info('card_name被修正:{}'.format(cl))
res = self.share_card_func(zhu_user_id=zhu_user, zhu_session=zhu_session,
flow_type=ft, card_name=cl,
ke_user_id=ul[0], ke_phone=str(ul[1]), ke_session=ke_session,
flow_id=fil)
# 'errorCode': 'NO_DATA', 'errorMessage': '记录不存在'
# 很多时候遇到,是因为 后面的result、flow_type不匹配,调错了receiveCard、sendCard
res_dict = res.json()
if isinstance(res_dict, dict) and res_dict.get('success') is False:
Log.error('赠送失败-请求的接口:{}'.format(res.url.split('/')[-1]))
response = False
# raise
else:
response = True
if ft == 1:
success_time += 1
Log.info('成功赠送次数:{}-{}'.format(success_time, fil))
assert success_time <= 5 # 送卡 最多成功赠送5次
table_card = self.change_card_name(cl, reverse='YES')
table_card_2 = '_'.join([table_card.lower()[:-3], table_card.lower()[-3:]])
self.check_zhu_ke_card(table_card_name=table_card_2,
dict_card_name=cl,
zhu_user=zhu_user, zhu_num=zhu_card_dict.get(cl),
ke_user=ul[0], ke_num=ke_card_dict.get(cl),
zhu_card_dict=zhu_card_dict,
flow_type=ft, response=response)
# if bool(zhu_card_dict) is False:
# Log.error('请留意,主态没卡了:{}'.format(zhu_card_dict))
# break
old = ke_card_dict.get(cl)
if response and ft == 1:
ke_card_dict[cl] = (0 if old is None else old) + 1
elif response and ft == 2:
ke_card_dict[cl] = old - 1
def test_one_card(self, flow_type: int, flows_num: int = 1, zhu_join: int = None, ke_join: int = None,
visit_many_flows: str = None, assign_card: str = None):
"""
送卡-1卡
:param flow_type:1、2
:param flows_num:
:param zhu_join:
:param ke_join:
:param visit_many_flows:
:param assign_card:指定某种卡
:return:
"""
# 获取主态、客态的用户信息;确定分享的卡片;
user_phone_nickname_list = self.get_user_phone_nickname_list()
zhu_user, zhu_phone, *args = user_phone_nickname_list[0]
zhu_session, zhu_join_res = self.user_join_activity(user_id=zhu_user, user_phone=str(zhu_phone),
join_result=zhu_join)
zhu_card_dict_all, zhu_card_dict_send, *args = self.get_user_cards(user_id=zhu_user, user_session=zhu_session)
if flow_type == 1:
Log.info('1-送卡')
if len(zhu_card_dict_send) == 0:
card = random.choice(self.card_name_list)
# raise
else:
card = random.choice(list(zhu_card_dict_send.keys()))
Log.info('此次主态赠送的卡:{}'.format(card))
user_phone_list = user_phone_nickname_list[1:]
# user_phone_list = user_phone_nickname_list # 增加 主态用户为客态的情形
else:
Log.info('2-要卡')
card = random.choice(self.card_name_list)
Log.info('此次主态索要的卡:{}'.format(card))
# 每类卡片都是大于2张的
cardSum_user_phone_list = self.get_cardSum10_list()
user_phone_list = [(up[1], up[2]) for up in cardSum_user_phone_list]
user_phone_list.extend(user_phone_nickname_list[1:])
# user_phone_list.extend(user_phone_nickname_list) # 增加 主态用户为客态的情形
random.shuffle(user_phone_list)
user_phone_list = user_phone_list[:self.use_rows] if len(user_phone_list) > self.use_rows else user_phone_list
random.shuffle(user_phone_list)
Log.info(user_phone_list)
if assign_card is not None and assign_card not in self.card_name_list:
Log.error('指定的卡有误:{}'.format(assign_card))
raise
elif assign_card is not None and assign_card in self.card_name_list:
card = assign_card
Log.info('指定卡:{}'.format(assign_card))
if flows_num == 1:
flow_id = self.get_flow_id(user_id=zhu_user, user_session=zhu_session, flow_type=flow_type,
card_name=card)
flow_id = [flow_id]
else:
flow_id = self.one_card_many_flows(zhu_user=zhu_user, zhu_session=zhu_session, card=card,
flow_type=flow_type, flows_num=flows_num)
Log.debug(flow_id)
random.shuffle(flow_id)
self.test_one_card2(ke_user_phone_list=user_phone_list, flow_type=flow_type, card=card,
zhu_user=zhu_user, zhu_session=zhu_session,
zhu_card_dict=zhu_card_dict_all, flow_id_list=flow_id,
ke_join=ke_join, visit_many_flows=visit_many_flows)
def one_card_many_flows(self, zhu_user: str, zhu_session: str, card: str, flow_type: int,
flows_num: int = 5):
"""
1张卡 生成 多条flow_id
:param zhu_user:
:param zhu_session:
:param card:
:param flows_num:
:param flow_type:
:return:
"""
flow_id_list = list()
for _ in range(flows_num):
flow_id = self.get_flow_id(user_id=zhu_user, user_session=zhu_session, flow_type=flow_type,
card_name=card)
flow_id_list.append(flow_id)
return flow_id_list
def test_one_card2(self, ke_user_phone_list: list, flow_type: int, card: str, zhu_user: str,
zhu_session: str, zhu_card_dict: dict, flow_id_list: list, ke_join: int = None,
visit_many_flows: str = None):
"""
:param ke_user_phone_list:
:param flow_type:
:param card:
:param zhu_user:
:param zhu_session:
:param zhu_card_dict:
:param flow_id_list:
:param ke_join:
:param visit_many_flows:
:return:
"""
# if flow_id_list is None:
# raise
success_flow_id = None
for i, upl in enumerate(ke_user_phone_list):
Log.info('----------------')
Log.info('客态:{}'.format(upl[0]))
if zhu_user == upl[0]:
k_s = zhu_session
Log.info('此客态是 主态用户')
else:
k_s, *args = self.user_join_activity(user_id=upl[0], user_phone=str(upl[1]), join_result=ke_join)
ke_card_dict, ke_card_dict_old, *args = self.get_user_cards(user_id=upl[0], user_session=k_s)
ke_num = ke_card_dict.get(card)
Log.info('客态 此种卡数量:{}'.format(ke_num))
# flow_id_list只1条flow_id时,不传visit_many_flows;
# flow_id_list有多条flow_id时,传visit_many_flows,就会用3条;不传visit_many_flows,就会用随机1条;
if visit_many_flows is None:
flow_id_list_new = [random.choice(flow_id_list)]
else:
flow_id_list_new = random.sample(flow_id_list, 3)
Log.info('flow_id_list:{}'.format(flow_id_list_new))
flow_id_list_new = flow_id_list_new * 2 # 实际请求2遍
for flow_id in flow_id_list_new:
res = self.share_card_func(zhu_user_id=zhu_user, zhu_session=zhu_session,
flow_type=flow_type, card_name=card, ke_user_id=upl[0],
ke_phone=str(upl[1]), ke_session=k_s, flow_id=flow_id)
res_dict = res.json()
if flow_id == success_flow_id: # 1条flowId只可以成功一次
assert res_dict.get('success') is False
# 一条flow-id只可以1次成功
if flow_type == 1 and res_dict.get('success') is False:
if res_dict.get('errorMessage') == '已被别人领取':
assert res_dict.get('errorCode') == 'RECEIVED_BY_OTHER'
elif res_dict.get('errorMessage') == '没有可分享的卡片':
assert res_dict.get('errorCode') == 'NO_CARD'
elif res_dict.get('errorMessage') == '好友送卡次数达上限':
assert res_dict.get('errorCode') == 'MAX_FRIEND'
elif res_dict.get('errorMessage') == '记录不存在':
assert res_dict.get('errorCode') == 'NO_DATA'
elif res_dict.get('errorMessage') == '不能领取自己的卡片':
assert res_dict.get('errorCode') == 'NOT_MYSELF'
assert k_s == zhu_session
elif res_dict.get('errorMessage') == '自已领取次数达上限':
assert res_dict.get('errorCode') == 'MAX_MYSELF'
else:
Log.error(res_dict)
raise
Log.info('分享失败')
res_response = False
elif flow_type == 2 and res_dict.get('success') is False:
if res_dict.get('errorMessage') == '超过当天接收卡片最大值':
assert res_dict.get('errorCode') == 'MAX_RECEIVE_TODAY'
elif res_dict.get('errorMessage') == '没有可分享的卡片':
assert res_dict.get('errorCode') == 'NO_CARD'
elif res_dict.get('errorMessage') == '不能送给自己':
assert res_dict.get('errorCode') == 'DENY_SEND_MYSELF'
assert k_s == zhu_session
else:
Log.error(res_dict)
raise
Log.info('分享失败')
res_response = False
elif res_dict.get('success'):
Log.info('分享成功-flow_id:{}'.format(flow_id))
res_response = True
success_flow_id = flow_id
else:
Log.error('{},{}'.format(flow_type, res_dict))
raise
tcn = self.change_card_name(card, reverse='YES').lower()
tcn = '_'.join([tcn[:-3], tcn[-3:]])
self.check_zhu_ke_card(table_card_name=tcn, dict_card_name=card,
zhu_user=zhu_user, zhu_num=zhu_card_dict.get(card),
ke_user=upl[0], ke_num=ke_num,
zhu_card_dict=zhu_card_dict,
flow_type=flow_type, response=res_response)
if res_dict.get('success') and flow_type == 1:
ke_num = 1 if ke_num is None else (ke_num + 1)
elif res_dict.get('success') and flow_type == 2:
ke_num -= 1 # 赠送成功说明: 合成时>=1 、 未合成时>=2
"""
@blog: https://blog.csdn.net/zyooooxie
"""
if __name__ == '__main__':
pass
# 1 未参加活动
# 0 未集齐 不可合成
# 2 集齐 未合成
# 3 集齐 已合成
m_zhu = 2
# m_ke = 0
m_ke = None
ny2 = NewYear2(12, random.randint(5, 99000))
# ny2 = NewYear2(2, random.randint(5, 99000))
m_card = random.choice(ny2.card_name_list + [None])
# m_card = 'zyooooxie'
print(m_card)
# ny2.test_one_card(flow_type=1, zhu_join=m_zhu, ke_join=m_ke, assign_card=m_card)
# ny2.test_one_card(flow_type=2, zhu_join=m_zhu, ke_join=m_ke, assign_card=m_card)
# ny2.test_one_card(flow_type=1, flows_num=5, zhu_join=m_zhu, ke_join=m_ke, assign_card=m_card)
# ny2.test_one_card(flow_type=2, flows_num=5, zhu_join=m_zhu, ke_join=m_ke, assign_card=m_card)
# ny2.test_one_card(flow_type=1, flows_num=5, zhu_join=m_zhu, ke_join=m_ke, visit_many_flows='YES', assign_card=m_card)
# ny2.test_one_card(flow_type=2, flows_num=5, zhu_join=m_zhu, ke_join=m_ke, visit_many_flows='YES', assign_card=m_card)
# ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=True, flow_id_list_same=True)
# ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=True, share_many_times=True)
# ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=False)
# ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=False, share_many_times=True)
ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=False, flow_id_list_same=True)
# ny2.test_many_cards(*ny2.create_user_data(zhu_join=m_zhu, ke_join=m_ke), share_card_same=False, share_many_times=True, flow_id_list_same=True)
执行截图
总结
做这个需求前后,我连续上了12天【第一周的周末加班2天】;
第一周 周三开始介入后,连续9天 正常下班后 在家里远程到11点半,最狠的时候是凌晨1点半才关远程;
真辛苦。
上线后 我始终惴惴不安:
- 一是 临上线的前一天 下午五点 产品砍功能;
- 二是 同一天 下午2点 后台同事在代码评审后 大改多张表、新增表;
- 三是我的问题:思路不清晰,用例写的烂;
- 四是我的问题:分享功能90%是使用脚本来测的,思路不清晰导致脚本写得不完善,测得就有疏漏。
后续改进:还是要锤炼自己的测试思路。
本文链接:https://blog.csdn.net/zyooooxie/article/details/95355201
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie