对于后端测试来说,负责的需求大多数都是复杂度较高,构造的测试场景麻烦,需要校验的数据较多,有的时候还得根据不同的规则来判断输出结果,除了负责测试需求之外,有的时候也需要给前端或者其他业务线的同事配置不同的场景供他们使用。有没有想过,我们是不是可以给自己或者他们提供一种能力,让他们自己一键操作,让我们一键操作,然后就可以关机回家(开玩笑的,反正是不可能下班的)。。。
被调到支付项目组三个月了,发现了一些问题,经常把我搞得焦头烂耳
建议选择复用性高、开发周期短、框架成熟、本身封装了很多上层可以使用的类,我 java 薄弱,对 python 相对比较熟悉,前端靠语感,选择前段后分离
根据背景中提到的问题,我对自己需要完成的功能分成三块。
最近需求较多,目前只做了数据评测
按照 django 和 restframwork 框架思路基础上增加了获取外部数据和输出结果规则。前端发起 get 请求。后端根据参数到外部数据库拿去对应信息,并对输出信息进行规则校验,入库自身 models 再返回给前端。
后端
代码不多,django 和 restframwork 已经高度封装底层,功能很好实现,后续规则太多考虑加入 celery。
代码结构
views(继承 mixins.ListModelMixin, viewsets.GenericViewSet)
from rest_framework import mixins, viewsets, filters, status
from django_filters import rest_framework
from rest_framework.response import Response
from .serializers import PaymentPaySerializer
from .filters import PaymentPayFilter
from .models import Payment_pay
from .manipulation import PaymentPayManipulation
class PaymentPayViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
"""
代扣详情
"""
serializer_class = PaymentPaySerializer
filter_backends = (rest_framework.DjangoFilterBackend, filters.OrderingFilter,)
filter_class = PaymentPayFilter
queryset = Payment_pay.objects.all()
ordering_fields = ("id",)
def get_queryset(self):
return Payment_pay.objects.all()
def list(self, request, *args, **kwargs):
serializer = self.get_serializer(data=self.request.query_params)
serializer.is_valid(raise_exception=True)
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
# 从代收中心和交易中心获取数据入库
self.insert_pay_data(self.request)
# 重组和序列化(models我定义是text字段需要转dict给与前端,自定义modelToJson)
trade_order_map = serializer.data[0]["trade_order_map"]
serializer.data[0]["trade_order_map"] = self.modelToJson(trade_order_map)
return Response(serializer.data)
def insert_pay_data(self, request):
"""
插入外部支付数据
:param request:
:return:
"""
order_no = request.query_params["order_no"]
pay_type = request.query_params["pay_type"]
env = request.query_params["env"]
# 从外部获取数据(这块代码就不贴了,用的是pymysql库,怎么方便怎么来)
manipulation = PaymentPayManipulation()
pay_records = manipulation.need_pay_data(order_no=order_no, pay_type=pay_type, env=env)
obj = Payment_pay.objects.filter(order_no=order_no,env=env,pay_type=pay_type,trade_order_map=pay_records["trade_order_map"])
if not obj:
Payment_pay.objects.create(order_no=order_no)
else:
Payment_pay.objects.filter(order_no=order_no).update(env=env,pay_type=pay_type,trade_order_map=pay_records["trade_order_map"])
serializers(序列化,继承 serializers.ModelSerializer)
from rest_framework import serializers
from .models import Payment_pay
class PaymentPaySerializer(serializers.ModelSerializer):
"""
代扣详情序列化
"""
class Meta:
model = Payment_pay
fields = "__all__"
def validate(self, attrs):
return attrs
filter(过滤,继承 django_filters.rest_framework.FilterSet)
import django_filters
from .models import Payment_pay
class PaymentPayFilter(django_filters.rest_framework.FilterSet):
"""
过滤代扣详情
"""
order_no = django_filters.CharFilter(field_name='order_no', lookup_expr='exact', label="订单号")
env = django_filters.CharFilter(field_name='env', lookup_expr='exact', label="环境")
pay_type = django_filters.CharFilter(field_name='pay_type', lookup_expr='exact', label="支付方式")
class Meta:
model = Payment_pay
fields = ['order_no', 'env', 'pay_type']
regulation(框架没有,自己定义用来放规则,只要数据不变,规则可改可加)
class PaymentPayRegulation(object):
"""
代扣详情数据规则
"""
@staticmethod
def trade_order_map_rule(data_list):
re_list = []
for data in data_list:
data["trade_status_notes"] = "0-初始化,1-等待,2-成功,3-失败,4-过期,5-部分成功"
data["is_trade_status"] = data["trade_status"]
re_list.append(data)
return re_list
前端
代码结构
前端页面显示 (引用组件)
<div v-if="trade_order_isshow">
<br/>
<el-tag >交易中心trade_order</el-tag>
<tradeOrder-table :datalist="trade_order_map_data"></tradeOrder-table>
</div>
前端表单显示(组件化 el-table-column)
<template>
<el-row :gutter="20">
<el-table
:row-style="rowStyle"
:data="datalist"
style="width: 100%; height: 100%;">
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="pay_order_no">
<span style="margin-left:100px;">{{ props.row.pay_order_no }}</span>
</el-form-item>
<el-form-item label="order_status">
<el-tooltip placement="top">
<div slot="content">{{ props.row.order_status_notes }}</div>
<span style="margin-left:100px;" v-if="props.row.is_order_status === 2">{{ props.row.order_status }}</span>
<span v-else style="color: red;margin-left:100px;">{{ props.row.order_status }}</span>
</el-tooltip>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column
label="pay_order_no"
prop="pay_order_no">
</el-table-column>
<el-table-column
label="order_status"
prop="order_status">
</el-table-column>
</el-table>
</el-row>
</template>
<script>
export default {
props: ['datalist'],
methods:{
rowStyle({ row, rowIndex }) {
for (let i=0;i<this.datalist.length;i++)
{
if (this.datalist[i].is_order_status !== 2)
{
if(rowIndex === i){
return 'background-color: pink'
}
}
}
},
}
}
</script>
效果
评测成功
可查看详情
评测失败
复杂的配置、繁琐的场景、恶心的结果校验都可以抽象成简单对象,为的就是提高测试效率,达到一键测试,早日下班。