测试开发进阶(三十七)

测试开发进阶(三十七)

报告模块

报告下载-中文文件

下载时候如果报告名中有中文,则可能出现乱码

1
2
from django.utils.encoding import escape_uri_path
report_path_final = escape_uri_path(report_filename) # 中文乱码的解决办法

使用escape_uri_path可以解决

报告展示

1
2
3
4
5
6
7
8
9
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
datas = serializer.data
try:
datas['summary'] = json.loads(datas['summary'], encoding='utf8')
except Exception as e:
pass
return Response(datas)

image-20191112225407620

配置模块

配置管理

配置管理页面展示需要展示

  • 配置名称
  • 所属项目
  • 所属接口

configures

其中:配置信息里面的外键是所属接口

interface

接口里面的外键是所属项目

所以要在序列化器中处理掉这里面的关系

序列化器

InterfacesAnotherSerializer拿到

  • 项目名称
  • 项目ID
  • 接口ID

ConfiguresSerializer里面用InterfacesAnotherSerializer拿到的东西进行展示

注意:createvalidated_data拿到的是一个对象,需要

1
2
interface_dict = validated_data.pop('interface')
validated_data['interface_id'] = interface_dict['iid']

将它变成对应的ID

image-20191112232930521

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "登录接口配置_自动化测试平台项目",
"interface": {
"name": "登录接口_自动化测试平台项目",
"project": "自动化测试平台项目"
},
"author": "柠檬小姐姐"
},
{
"id": 2,
"name": "查询项目列表配置_前程贷项目",
"interface": {
"name": "查看项目列表接口_前程贷P2P金融项目",
"project": "前程贷P2P金融项目"
},
"author": "柠檬小姐姐"
}
],
"total_pages": 1,
"current_page_num": 1
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from rest_framework import serializers
from interfaces.models import Interfaces
from utils.validates import whether_existed_project_id, whether_existed_interface_id
from .models import Configures


class InterfacesAnotherSerializer(serializers.ModelSerializer):
project = serializers.StringRelatedField(help_text='项目名称')
# 项目ID
pid = serializers.IntegerField(write_only=True, validators=[whether_existed_project_id], help_text='项目ID')
# 接口ID
iid = serializers.IntegerField(write_only=True, validators=[whether_existed_interface_id], help_text='接口ID')

class Meta:
model = Interfaces
fields = ('iid', 'name', 'project', 'pid')
extra_kwargs = {
'name':
{
'read_only': True
}
}

def validate(self, attrs):
"""
校验项目ID是否与接口ID一致
:param attrs:
:return:
"""
if not Interfaces.objects.filter(id=attrs['iid'], project_id=attrs['pid'], is_delete=False).exists():
raise serializers.ValidationError('项目和接口信息不对应!')
return attrs


class ConfiguresSerializer(serializers.ModelSerializer):
"""
配置序列化器
"""
interface = InterfacesAnotherSerializer(help_text='项目ID和接口ID')

class Meta:
model = Configures
fields = ('id', 'name', 'interface', 'author', 'request')
extra_kwargs = {
'request': {
'write_only': True
}
}

def create(self, validated_data):
interface_dict = validated_data.pop('interface')
validated_data['interface_id'] = interface_dict['iid']
return Configures.objects.create(**validated_data)

def update(self, instance, validated_data):
if 'interface' in validated_data:
interface_dict = validated_data.pop('interface')
validated_data['interface_id'] = interface_dict['iid']
return super().update(instance, validated_data)

utils.validates.whether_existed_project_id中检查项目id是否存在

1
2
3
4
5
6
7
8
9
10
def whether_existed_project_id(value):
"""
检查项目id是否存在
:param value:
:return:
"""
if not isinstance(value, int):
raise serializers.ValidationError('所选项目有误!')
elif not Projects.objects.filter(is_delete=False, id=value).exists():
raise serializers.ValidationError('所选项目不存在!')

视图

查看lemon-test/src/components/page/ConfigureAdd.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
data: function () {
return {
editVisible: false, // 新增配置弹框是否显示标识
apiMsgData: {
id: null,
name: "",
header: [{key: null, value: null}],
globalVar: [{key: null, value: null, param_type: 'string'}],
},
bodyShow: 'second',
otherShow: 'first',
paramTypes: ['string', 'int', 'float', 'boolean'],
cell: Object(),
project_names: [],
selected_project_id: null,
selected_interface_id: null,
selected_configure_id: null,
configure_name: null, // 配置名称
author: '', // 用例编写人员
interfaces: [],
configures: [],
}
}

需要后台返回一个字典:

1
2
3
4
5
6
7
8
datas = {
"author": config_obj.author,
"configure_name": config_name,
"selected_interface_id": selected_interface_id,
"selected_project_id": selected_project_id,
"header": config_headers_list,
"globalVar": config_variables_list
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import json
from rest_framework.viewsets import ModelViewSet
from rest_framework import permissions
from rest_framework.response import Response
from .models import Configures
from .serializers import ConfiguresSerializer
from interfaces.models import Interfaces
from utils import handle_datas


class ConfiguresViewSet(ModelViewSet):
"""
list:
返回配置信息(多个)列表数据

create:
创建配置信息

retrieve:
返回配置信息(单个)详情数据

update:
更新(全)配置信息

partial_update:
更新(部分)配置信息

destroy:
删除配置信息

retrieve:
获取配置详情
"""
queryset = Configures.objects.filter(is_delete=False)
serializer_class = ConfiguresSerializer
permission_classes = (permissions.IsAuthenticated,)
ordering_fields = ('id', 'name')

def perform_destroy(self, instance):
instance.is_delete = True
instance.save() # 逻辑删除

def retrieve(self, request, *args, **kwargs):
config_obj = self.get_object()
# 不建议使用eval()
config_request = json.loads(config_obj.request, encoding='utf-8')

# 处理请求头数据
config_headers = config_request['config']['request'].get('headers')
config_headers_list = handle_datas.handle_data4(config_headers)

# 处理全局变量数据
config_variables = config_request['config'].get('variables')
config_variables_list = handle_datas.handle_data2(config_variables)

config_name = config_request['config']['name']
selected_interface_id = config_obj.interface_id
# 接口所属的项目ID
selected_project_id = Interfaces.objects.get(id=selected_interface_id).project_id

datas = {
"author": config_obj.author,
"configure_name": config_name,
"selected_interface_id": selected_interface_id,
"selected_project_id": selected_project_id,
"header": config_headers_list,
"globalVar": config_variables_list
}

return Response(datas)

image-20191112233956495

用例模块

序列化器

list接口对应的序列化器:TestcasesSerializer

TestcasesSerializer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from rest_framework import serializers
from interfaces.models import Interfaces
from utils import validates
from .models import Testcases


class TestcasesSerializer(serializers.ModelSerializer):
"""
用例序列化器
"""
interface = InterfacesAnotherSerializer(help_text="所属接口和项目信息")

class Meta:
model = Testcases
fields = ('id', 'name', 'interface', 'include', 'author', 'request')
extra_kwargs = {
'include': {
'write_only': True
},
'request': {
'write_only': True
}
}

def create(self, validated_data):
interface_dict = validated_data.pop('interface')
validated_data['interface_id'] = interface_dict['iid']
return Testcases.objects.create(**validated_data)

def update(self, instance, validated_data):
if 'interface' in validated_data:
interface_dict = validated_data.pop('interface')
validated_data['interface_id'] = interface_dict['iid']
return super().update(instance, validated_data)

用例编辑

编辑1

编辑2

编辑3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import json
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework import permissions
from .models import Testcases
from interfaces.models import Interfaces
from .serializers import TestcasesSerializer, TestcasesRunSerializer
from utils import handle_datas


class TestcasesViewSet(ModelViewSet):
"""
list:
返回用例(多个)列表数据

create:
创建用例

retrieve:
返回用例(单个)详情数据

update:
更新(全)用例

partial_update:
更新(部分)用例

destroy:
删除用例

run:
运行用例

details:
获取用例详情
"""
queryset = Testcases.objects.filter(is_delete=False)
serializer_class = TestcasesSerializer
permission_classes = (permissions.IsAuthenticated,)
ordering_fields = ('id', 'name')

def perform_destroy(self, instance):
instance.is_delete = True
instance.save() # 逻辑删除

def retrieve(self, request, *args, **kwargs):
"""获取用例详情信息"""
# Testcase对象
testcase_obj = self.get_object()

# 用例前置信息
testcase_include = json.loads(testcase_obj.include, encoding='utf-8')

# 用例请求信息
testcase_request = json.loads(testcase_obj.request, encoding='utf-8')
testcase_request_datas = testcase_request.get('test').get('request')

# 处理用例的validate列表
# 将[{'check': 'status_code', 'expected':200, 'comparator': 'equals'}]
# 转化为[{key: 'status_code', value: 200, comparator: 'equals', param_type: 'string'}]
testcase_validate = testcase_request.get('test').get('validate')
testcase_validate_list = handle_datas.handle_data1(testcase_validate)

# 处理用例的param数据
testcase_params = testcase_request_datas.get('params')
testcase_params_list = handle_datas.handle_data4(testcase_params)

# 处理用例的header列表
testcase_headers = testcase_request_datas.get('headers')
testcase_headers_list = handle_datas.handle_data4(testcase_headers)

# 处理用例variables变量列表
testcase_variables = testcase_request.get('test').get('variables')
testcase_variables_list = handle_datas.handle_data2(testcase_variables)

# 处理form表单数据
testcase_form_datas = testcase_request_datas.get('data')
testcase_form_datas_list = handle_datas.handle_data6(testcase_form_datas)

# 处理json数据
# testcase_json_datas = str(testcase_request_datas.get('json'))
testcase_json_datas = json.dumps(testcase_request_datas.get('json'), ensure_ascii=False)

# 处理extract数据
testcase_extract_datas = testcase_request.get('test').get('extract')
testcase_extract_datas_list = handle_datas.handle_data3(testcase_extract_datas)

# 处理parameters数据
testcase_parameters_datas = testcase_request.get('test').get('parameters')
testcase_parameters_datas_list = handle_datas.handle_data3(testcase_parameters_datas)

# 处理setupHooks数据
testcase_setup_hooks_datas = testcase_request.get('test').get('setup_hooks')
testcase_setup_hooks_datas_list = handle_datas.handle_data5(testcase_setup_hooks_datas)

# 处理teardownHooks数据
testcase_teardown_hooks_datas = testcase_request.get('test').get('teardown_hooks')
testcase_teardown_hooks_datas_list = handle_datas.handle_data5(testcase_teardown_hooks_datas)

selected_configure_id = testcase_include.get('config')
selected_interface_id = testcase_obj.interface_id
selected_project_id = Interfaces.objects.get(id=selected_interface_id).project_id
selected_testcase_id = testcase_include.get('testcases')

datas = {
"author": testcase_obj.author,
"testcase_name": testcase_obj.name,
"selected_configure_id": selected_configure_id,
"selected_interface_id": selected_interface_id,
"selected_project_id": selected_project_id,
"selected_testcase_id": selected_testcase_id,

"method": testcase_request_datas.get('method'),
"url": testcase_request_datas.get('url'),
"param": testcase_params_list,
"header": testcase_headers_list,
"variable": testcase_form_datas_list, # form表单请求数据
"jsonVariable": testcase_json_datas,

"extract": testcase_extract_datas_list,
"validate": testcase_validate_list,
"globalVar": testcase_variables_list, # 变量
"parameterized": testcase_parameters_datas_list,
"setupHooks": testcase_setup_hooks_datas_list,
"teardownHooks": testcase_teardown_hooks_datas_list,
}
return Response(datas)
 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
您的支持将鼓励我继续创作!