测试开发进阶(三十七)

报告模块

报告下载-中文文件

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


     
     
     
     
  1. from django.utils.encoding import escape_uri_path

  2. report_path_final = escape_uri_path(report_filename) # 中文乱码的解决办法

使用 escape_uri_path可以解决

报告展示


     
     
     
     
  1. def retrieve(self, request, *args, **kwargs):

  2. instance = self.get_object()

  3. serializer = self.get_serializer(instance)

  4. datas = serializer.data

  5. try:

  6. datas['summary'] = json.loads(datas['summary'], encoding='utf8')

  7. except Exception as e:

  8. pass

  9. return Response(datas)

测试开发进阶(三十七)_第1张图片

配置模块

测试开发进阶(三十七)_第2张图片

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

  • 配置名称

  • 所属项目

  • 所属接口

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

测试开发进阶(三十七)_第3张图片

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

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

序列化器

InterfacesAnotherSerializer拿到

  • 项目名称

  • 项目ID

  • 接口ID

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

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


     
     
     
     
  1. interface_dict = validated_data.pop('interface')

  2. validated_data['interface_id'] = interface_dict['iid']

将它变成对应的ID

测试开发进阶(三十七)_第4张图片


     
     
     
     
  1. {

  2. "count": 2,

  3. "next": null,

  4. "previous": null,

  5. "results": [

  6. {

  7. "id": 1,

  8. "name": "登录接口配置_自动化测试平台项目",

  9. "interface": {

  10. "name": "登录接口_自动化测试平台项目",

  11. "project": "自动化测试平台项目"

  12. },

  13. "author": "柠檬小姐姐"

  14. },

  15. {

  16. "id": 2,

  17. "name": "查询项目列表配置_前程贷项目",

  18. "interface": {

  19. "name": "查看项目列表接口_前程贷P2P金融项目",

  20. "project": "前程贷P2P金融项目"

  21. },

  22. "author": "柠檬小姐姐"

  23. }

  24. ],

  25. "total_pages": 1,

  26. "current_page_num": 1

  27. }


     
     
     
     
  1. from rest_framework import serializers

  2. from interfaces.models import Interfaces

  3. from utils.validates import whether_existed_project_id, whether_existed_interface_id

  4. from .models import Configures

  5. class InterfacesAnotherSerializer(serializers.ModelSerializer):

  6. project = serializers.StringRelatedField(help_text='项目名称')

  7. # 项目ID

  8. pid = serializers.IntegerField(write_only=True, validators=[whether_existed_project_id], help_text='项目ID')

  9. # 接口ID

  10. iid = serializers.IntegerField(write_only=True, validators=[whether_existed_interface_id], help_text='接口ID')

  11. class Meta:

  12. model = Interfaces

  13. fields = ('iid', 'name', 'project', 'pid')

  14. extra_kwargs = {

  15. 'name':

  16. {

  17. 'read_only': True

  18. }

  19. }

  20. def validate(self, attrs):

  21. """

  22. 校验项目ID是否与接口ID一致

  23. :param attrs:

  24. :return:

  25. """

  26. if not Interfaces.objects.filter(id=attrs['iid'], project_id=attrs['pid'], is_delete=False).exists():

  27. raise serializers.ValidationError('项目和接口信息不对应!')

  28. return attrs

  29. class ConfiguresSerializer(serializers.ModelSerializer):

  30. """

  31. 配置序列化器

  32. """

  33. interface = InterfacesAnotherSerializer(help_text='项目ID和接口ID')

  34. class Meta:

  35. model = Configures

  36. fields = ('id', 'name', 'interface', 'author', 'request')

  37. extra_kwargs = {

  38. 'request': {

  39. 'write_only': True

  40. }

  41. }

  42. def create(self, validated_data):

  43. interface_dict = validated_data.pop('interface')

  44. validated_data['interface_id'] = interface_dict['iid']

  45. return Configures.objects.create(**validated_data)

  46. def update(self, instance, validated_data):

  47. if 'interface' in validated_data:

  48. interface_dict = validated_data.pop('interface')

  49. validated_data['interface_id'] = interface_dict['iid']

  50. return super().update(instance, validated_data)

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


     
     
     
     
  1. def whether_existed_project_id(value):

  2. """

  3. 检查项目id是否存在

  4. :param value:

  5. :return:

  6. """

  7. if not isinstance(value, int):

  8. raise serializers.ValidationError('所选项目有误!')

  9. elif not Projects.objects.filter(is_delete=False, id=value).exists():

  10. raise serializers.ValidationError('所选项目不存在!')

视图

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


     
     
     
     
  1. data: function () {

  2. return {

  3. editVisible: false, // 新增配置弹框是否显示标识

  4. apiMsgData: {

  5. id: null,

  6. name: "",

  7. header: [{key: null, value: null}],

  8. globalVar: [{key: null, value: null, param_type: 'string'}],

  9. },

  10. bodyShow: 'second',

  11. otherShow: 'first',

  12. paramTypes: ['string', 'int', 'float', 'boolean'],

  13. cell: Object(),

  14. project_names: [],

  15. selected_project_id: null,

  16. selected_interface_id: null,

  17. selected_configure_id: null,

  18. configure_name: null, // 配置名称

  19. author: '', // 用例编写人员

  20. interfaces: [],

  21. configures: [],

  22. }

  23. }

需要后台返回一个字典:


     
     
     
     
  1. datas = {

  2. "author": config_obj.author,

  3. "configure_name": config_name,

  4. "selected_interface_id": selected_interface_id,

  5. "selected_project_id": selected_project_id,

  6. "header": config_headers_list,

  7. "globalVar": config_variables_list

  8. }


     
     
     
     
  1. import json

  2. from rest_framework.viewsets import ModelViewSet

  3. from rest_framework import permissions

  4. from rest_framework.response import Response

  5. from .models import Configures

  6. from .serializers import ConfiguresSerializer

  7. from interfaces.models import Interfaces

  8. from utils import handle_datas

  9. class ConfiguresViewSet(ModelViewSet):

  10. """

  11. list:

  12. 返回配置信息(多个)列表数据

  13. create:

  14. 创建配置信息

  15. retrieve:

  16. 返回配置信息(单个)详情数据

  17. update:

  18. 更新(全)配置信息

  19. partial_update:

  20. 更新(部分)配置信息

  21. destroy:

  22. 删除配置信息

  23. retrieve:

  24. 获取配置详情

  25. """

  26. queryset = Configures.objects.filter(is_delete=False)

  27. serializer_class = ConfiguresSerializer

  28. permission_classes = (permissions.IsAuthenticated,)

  29. ordering_fields = ('id', 'name')

  30. def perform_destroy(self, instance):

  31. instance.is_delete = True

  32. instance.save() # 逻辑删除

  33. def retrieve(self, request, *args, **kwargs):

  34. config_obj = self.get_object()

  35. # 不建议使用eval()

  36. config_request = json.loads(config_obj.request, encoding='utf-8')

  37. # 处理请求头数据

  38. config_headers = config_request['config']['request'].get('headers')

  39. config_headers_list = handle_datas.handle_data4(config_headers)

  40. # 处理全局变量数据

  41. config_variables = config_request['config'].get('variables')

  42. config_variables_list = handle_datas.handle_data2(config_variables)

  43. config_name = config_request['config']['name']

  44. selected_interface_id = config_obj.interface_id

  45. # 接口所属的项目ID

  46. selected_project_id = Interfaces.objects.get(id=selected_interface_id).project_id

  47. datas = {

  48. "author": config_obj.author,

  49. "configure_name": config_name,

  50. "selected_interface_id": selected_interface_id,

  51. "selected_project_id": selected_project_id,

  52. "header": config_headers_list,

  53. "globalVar": config_variables_list

  54. }

  55. return Response(datas)

测试开发进阶(三十七)_第5张图片

用例模块

序列化器

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

测试开发进阶(三十七)_第6张图片


     
     
     
     
  1. from rest_framework import serializers

  2. from interfaces.models import Interfaces

  3. from utils import validates

  4. from .models import Testcases

  5. class TestcasesSerializer(serializers.ModelSerializer):

  6. """

  7. 用例序列化器

  8. """

  9. interface = InterfacesAnotherSerializer(help_text="所属接口和项目信息")

  10. class Meta:

  11. model = Testcases

  12. fields = ('id', 'name', 'interface', 'include', 'author', 'request')

  13. extra_kwargs = {

  14. 'include': {

  15. 'write_only': True

  16. },

  17. 'request': {

  18. 'write_only': True

  19. }

  20. }

  21. def create(self, validated_data):

  22. interface_dict = validated_data.pop('interface')

  23. validated_data['interface_id'] = interface_dict['iid']

  24. return Testcases.objects.create(**validated_data)

  25. def update(self, instance, validated_data):

  26. if 'interface' in validated_data:

  27. interface_dict = validated_data.pop('interface')

  28. validated_data['interface_id'] = interface_dict['iid']

  29. return super().update(instance, validated_data)

用例编辑

测试开发进阶(三十七)_第7张图片

测试开发进阶(三十七)_第8张图片

测试开发进阶(三十七)_第9张图片


     
     
     
     
  1. import json

  2. from rest_framework.response import Response

  3. from rest_framework.viewsets import ModelViewSet

  4. from rest_framework import permissions

  5. from .models import Testcases

  6. from interfaces.models import Interfaces

  7. from .serializers import TestcasesSerializer, TestcasesRunSerializer

  8. from utils import handle_datas

  9. class TestcasesViewSet(ModelViewSet):

  10. """

  11. list:

  12. 返回用例(多个)列表数据

  13. create:

  14. 创建用例

  15. retrieve:

  16. 返回用例(单个)详情数据

  17. update:

  18. 更新(全)用例

  19. partial_update:

  20. 更新(部分)用例

  21. destroy:

  22. 删除用例

  23. run:

  24. 运行用例

  25. details:

  26. 获取用例详情

  27. """

  28. queryset = Testcases.objects.filter(is_delete=False)

  29. serializer_class = TestcasesSerializer

  30. permission_classes = (permissions.IsAuthenticated,)

  31. ordering_fields = ('id', 'name')

  32. def perform_destroy(self, instance):

  33. instance.is_delete = True

  34. instance.save() # 逻辑删除

  35. def retrieve(self, request, *args, **kwargs):

  36. """获取用例详情信息"""

  37. # Testcase对象

  38. testcase_obj = self.get_object()

  39. # 用例前置信息

  40. testcase_include = json.loads(testcase_obj.include, encoding='utf-8')

  41. # 用例请求信息

  42. testcase_request = json.loads(testcase_obj.request, encoding='utf-8')

  43. testcase_request_datas = testcase_request.get('test').get('request')

  44. # 处理用例的validate列表

  45. # 将[{'check': 'status_code', 'expected':200, 'comparator': 'equals'}]

  46. # 转化为[{key: 'status_code', value: 200, comparator: 'equals', param_type: 'string'}]

  47. testcase_validate = testcase_request.get('test').get('validate')

  48. testcase_validate_list = handle_datas.handle_data1(testcase_validate)

  49. # 处理用例的param数据

  50. testcase_params = testcase_request_datas.get('params')

  51. testcase_params_list = handle_datas.handle_data4(testcase_params)

  52. # 处理用例的header列表

  53. testcase_headers = testcase_request_datas.get('headers')

  54. testcase_headers_list = handle_datas.handle_data4(testcase_headers)

  55. # 处理用例variables变量列表

  56. testcase_variables = testcase_request.get('test').get('variables')

  57. testcase_variables_list = handle_datas.handle_data2(testcase_variables)

  58. # 处理form表单数据

  59. testcase_form_datas = testcase_request_datas.get('data')

  60. testcase_form_datas_list = handle_datas.handle_data6(testcase_form_datas)

  61. # 处理json数据

  62. # testcase_json_datas = str(testcase_request_datas.get('json'))

  63. testcase_json_datas = json.dumps(testcase_request_datas.get('json'), ensure_ascii=False)

  64. # 处理extract数据

  65. testcase_extract_datas = testcase_request.get('test').get('extract')

  66. testcase_extract_datas_list = handle_datas.handle_data3(testcase_extract_datas)

  67. # 处理parameters数据

  68. testcase_parameters_datas = testcase_request.get('test').get('parameters')

  69. testcase_parameters_datas_list = handle_datas.handle_data3(testcase_parameters_datas)

  70. # 处理setupHooks数据

  71. testcase_setup_hooks_datas = testcase_request.get('test').get('setup_hooks')

  72. testcase_setup_hooks_datas_list = handle_datas.handle_data5(testcase_setup_hooks_datas)

  73. # 处理teardownHooks数据

  74. testcase_teardown_hooks_datas = testcase_request.get('test').get('teardown_hooks')

  75. testcase_teardown_hooks_datas_list = handle_datas.handle_data5(testcase_teardown_hooks_datas)

  76. selected_configure_id = testcase_include.get('config')

  77. selected_interface_id = testcase_obj.interface_id

  78. selected_project_id = Interfaces.objects.get(id=selected_interface_id).project_id

  79. selected_testcase_id = testcase_include.get('testcases')

  80. datas = {

  81. "author": testcase_obj.author,

  82. "testcase_name": testcase_obj.name,

  83. "selected_configure_id": selected_configure_id,

  84. "selected_interface_id": selected_interface_id,

  85. "selected_project_id": selected_project_id,

  86. "selected_testcase_id": selected_testcase_id,

  87. "method": testcase_request_datas.get('method'),

  88. "url": testcase_request_datas.get('url'),

  89. "param": testcase_params_list,

  90. "header": testcase_headers_list,

  91. "variable": testcase_form_datas_list, # form表单请求数据

  92. "jsonVariable": testcase_json_datas,

  93. "extract": testcase_extract_datas_list,

  94. "validate": testcase_validate_list,

  95. "globalVar": testcase_variables_list, # 变量

  96. "parameterized": testcase_parameters_datas_list,

  97. "setupHooks": testcase_setup_hooks_datas_list,

  98. "teardownHooks": testcase_teardown_hooks_datas_list,

  99. }

  100. return Response(datas)

你可能感兴趣的:(测试开发进阶(三十七))