Django はインターフェイス自動化プラットフォームを実装します (14) テスト ケース モジュール テストケース シリアライザーとビュー [継続的に更新]

関連記事:

Django 実装インターフェイス自動化プラットフォーム (13) インターフェイス モジュール インターフェイス シリアライザーとビュー [継続的に更新]_Do テスト ニャー ソース ブログ - CSDN ブログ

この章はプロジェクトの内訳です。この章の内容を参照する場合は、プロジェクト コード全体と併せて参照する必要があります。

Python django vue httprunner はインターフェイス自動化プラットフォーム (最終バージョン) を実装します

1. テストケース アプリケーションと関連インターフェイス

リクエストメソッド URI 対応するアクション 実現機能
得る /テストケース/ 。リスト() テストケースリストのクエリ
役職 /テストケース/ 。作成() データを作成する
得る /testcases/{id}/ .retrieve() テストケースの詳細データを取得する
置く /testcases/{id}/ アップデート() データ内のすべてのフィールドを更新する
パッチ /testcases/{id}/ .partial_update() データの一部のフィールドを更新する
消去 /testcases/{id}/ 。破壊() データの一部を削除する
役職 /testcases/{id}/run/ 特定のインターフェースですべてのケースを実行する

 1.1 ユースケースのリスト

得る /テストケース/ 。リスト() テストケースリストのクエリ

1.2 ユースケースの作成 

1.2.1 基本情報

 1. プロジェクトリストを取得する

2. プロジェクトの下のインターフェースリストを取得します

3. プレユースケースのリスト

4. すべての構成リストを取得しました

1.2.2 基本情報

 

 

2. モデルクラス

from django.db import models

from utils.base_models import BaseModel


class Interfaces(BaseModel):
    id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
    name = models.CharField('接口名称', max_length=200, unique=True, help_text='接口名称')
    project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
                                related_name='interfaces', help_text='所属项目')
    tester = models.CharField('测试人员', max_length=50, help_text='测试人员')
    desc = models.CharField('简要描述', max_length=200, null=True, blank=True, help_text='简要描述')

    class Meta:
        db_table = 'tb_interfaces'
        verbose_name = '接口信息'
        verbose_name_plural = verbose_name
        ordering = ('id',)

    def __str__(self):
        return self.name

このコードは、BaseModel を拡張する Testcases という Django モデル クラスを定義します。

まず、Django モデル モジュールとカスタム BaseModel モジュールが django.db インポート モデルからインポートされます。

次に、次のフィールドを含む Testcases モデル クラスが定義されます。

  • id: 主キー フィールド。AutoField タイプを使用して、自動インクリメントされる ID を生成します。
  • name: ケース名フィールドを使用します。CharField タイプを使用し、最大長は 50 で、一意の値として設定されます。
  • インターフェイス: ユースケースが属するインターフェイスを示す、interfaces.Interfaces モデルに関連付けられた外部キー フィールド。
  • include: pre-field。TextField タイプを使用します。これは空にすることができ、ユースケースが実行される前に実行する必要があるシーケンス情報を保存します。
  • author: author フィールド、CharField タイプを使用、最大長は 50、このユースケースの作成者情報を保存します。
  • request: リクエスト情報フィールドには、TextField 型を使用して、リクエストの詳細情報が保存されます。

次に、モデル クラスのメタ クラスが定義されます。これにはいくつかのメタデータが含まれます。

  • db_table: データベース テーブルの名前。tb_testcases に設定されます。
  • verbose_name: 人間が判読できるモデルの名前。「ユースケース情報」に設定されます。
  • verbose_name_plural: モデルの複数形の名前。verbose_name と同じです。
  • 順序付け: ID フィールドに従って昇順で並べ替えられた、クエリ結果のデフォルトの並べ替えルール。

最後に、ユースケースの名前を返す __str__ メソッドが定義されています。このメソッドは、バックグラウンド管理インターフェイスやその他の場所でモデル オブジェクトの読み取り可能な情報を表示するために使用されます。

上記の定義により、Django フレームワークを使用して、上で定義したフィールドを含む Testcases という名前のデータ テーブルを作成し、データ操作とクエリを実行できます。

知らせ:

ヘッダー、URI、リクエスト本文、アサーションなどのすべてのリクエスト関連情報は、すべて モデル クラスのリクエスト フィールドにあります。

request の値は json 文字列です。好き:

{
	"test": {
		"name": "1陈帅百度",
		"request": {
			"url": "/mcp/pc/pcsearch",
			"method": "POST",
			"json": {
				"invoke_info": {
					"pos_1": [{}],
					"pos_2": [{}],
					"pos_3": [{}]
				}
			}
		},
		"validate": [{
			"check": "status_code",
			"expected": 200,
			"comparator": "equals"
		}]
	}
}

リクエストとアサーションに関する情報が含まれます。

最下層で使用されるhttprunner 1.0で作成されたインターフェース自動化ドライバーはjson形式です。

関連情報:

httprunner 2.x の基本的な使い方 (2)

3. シリアライザークラス


class TestcaseModelSerializer(serializers.ModelSerializer):
    interface = InterfaceProjectModelSerializer(label='所属项目和接口信息', help_text='所属项目和接口信息')

    class Meta:
        model = Testcases
        exclude = ('create_datetime', 'update_datetime')
        extra_kwargs = {
            'request': {
                'write_only': True
            },
            'include': {
                'write_only': True
            },
        }

    # def validate_request(self, attr):
    #     # TODO
    #     return attr
    #
    # def validate(self, attrs):
    #     # TODO
    #     return attrs

    def to_internal_value(self, data):
        result = super().to_internal_value(data)
        iid = data.get('interface').get('iid')
        result['interface'] = Interfaces.objects.get(id=iid)
        return result

    # def create(self, validated_data):
    #     pass


# class TestcaseRunSerializer(serializers.ModelSerializer):
#     env_id = serializers.IntegerField(label="所属环境id", help_text="所属环境id",
#                                       validators=[ManualValidateIsExist('env')])
#
#     class Meta:
#         model = Testcases
#         fields = ('id', 'env_id')

class TestcaseRunSerializer(RunSerializer):

    class Meta(RunSerializer.Meta):
        model = Testcases

4. 見る 

import json
import os
from datetime import datetime

from django.conf import settings
from django.http import JsonResponse
from rest_framework import viewsets
from rest_framework import permissions
from rest_framework.response import Response
from rest_framework.decorators import action

from .models import Testcases
from envs.models import Envs
from . import serializers
from utils import handle_datas, common
from utils.mixins import RunMixin


class TestcasesViewSet(RunMixin, viewsets.ModelViewSet):

    queryset = Testcases.objects.all()
    serializer_class = serializers.TestcaseModelSerializer
    permission_classes = [permissions.IsAuthenticated]

    # 删除
    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        response.status_code = 200
        response = {"code":2000,"msg":"删除成功"}
        response =JsonResponse(response)
        return response

    # 获取单个详情
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object() # type: Testcases
        try:
            testcase_include = json.loads(instance.include, encoding='utf-8')
        except Exception:
            testcase_include = dict()

        try:
            testcase_request = json.loads(instance.request, encoding='utf-8')
        except Exception:
            return Response({'msg': '用例格式有误', 'status': 400}, status=400)

        testcase_request_data = testcase_request.get('test').get('request')
        # 获取json参数
        json_data = testcase_request_data.get('json')
        json_data_str = json.dumps(json_data, ensure_ascii=False)

        # 获取extract参数
        extract_data = testcase_request.get('test').get('extract')
        extract_data = handle_datas.handle_data3(extract_data)

        # 获取validate参数
        validate_data = testcase_request.get('test').get('validate')
        validate_data = handle_datas.handle_data1(validate_data)

        # 获取variables参数
        variables_data = testcase_request.get('test').get('variables')
        variables_data = handle_datas.handle_data2(variables_data)

        # 获取parameters参数
        parameters_data = testcase_request.get('test').get('parameters')
        parameters_data = handle_datas.handle_data3(parameters_data)

        # 获取setup_hooks参数
        setup_hooks_data = testcase_request.get('test').get('setup_hooks')
        setup_hooks_data = handle_datas.handle_data5(setup_hooks_data)

        # 获取teardown_hooks参数
        teardown_hooks_data = testcase_request.get('test').get('teardown_hooks')
        teardown_hooks_data = handle_datas.handle_data5(teardown_hooks_data)

        data = {
            "author": instance.author,
            "testcase_name": instance.name,
            "selected_configure_id": testcase_include.get('config'),
            "selected_interface_id": instance.interface_id,
            "selected_project_id": instance.interface.project_id,
            "selected_testcase_id": testcase_include.get('testcases', []),
            "method": testcase_request_data.get('method'),
            "url": testcase_request_data.get('url'),
            "param": handle_datas.handle_data4(testcase_request_data.get('params')),
            "header": handle_datas.handle_data4(testcase_request_data.get('headers')),
            "variable": handle_datas.handle_data2(testcase_request_data.get('data')),
            "jsonVariable": json_data_str,
            "extract": extract_data,
            "validate": validate_data,
            # 用例的当前配置(variables)
            "globalVar": variables_data,
            "parameterized": parameters_data,
            "setupHooks": setup_hooks_data,
            "teardownHooks":teardown_hooks_data
        }

        return Response(data, status=200)

    # @action(methods=['post'], detail=True)
    # def run(self, request, *args, **kwargs):
    #     # 1、取出用例模型对象并获取env_id
    #     # instance = self.get_object()    # type: Testcases
    #     # serializer = self.get_serializer(data=request.data)
    #     # serializer.is_valid(raise_exception=True)
    #     # env_id = serializer.validated_data.get('env_id')
    #     # env = Envs.objects.get(id=env_id)
    #
    #     # 2、创建以时间戳命名的目录
    #     # dirname = datetime.strftime(datetime.now(), "%Y%m%d%H%M%S")
    #     # testcase_dir_path = os.path.join(settings.PROJECT_DIR, datetime.strftime(datetime.now(), "%Y%m%d%H%M%S"))
    #     # os.makedirs(testcase_dir_path)
    #
    #     # 3、创建以项目名命名的目录
    #     # 4、生成debugtalks.py、yaml用例文件
    #     # common.generate_testcase_file(instance, env, testcase_dir_path)
    #
    #     # 5、运行用例并生成测试报告
    #     # return common.run_testcase(instance, testcase_dir_path)
    #     qs = [self.get_object()]
    #     return self.execute(qs)

    def get_serializer_class(self):
        if self.action == "run":
            return serializers.TestcaseRunSerializer
        else:
            return super().get_serializer_class()

    def get_testcase_qs(self):
        return [self.get_object()]
        # return self.queryset.filter(id=self.get_object().id)

 

このコードは Django ビュー セットであり、テスト ケースの追加、削除、変更、クエリを処理するために使用されます。RunMixin クラスを拡張し、ModelViewSet ビュー セットを使用してコードを簡素化します。

このビューセットは次のメソッドを定義します。

  1. destroy: 親クラスの destroy メソッドをオーバーライドし、指定されたテスト ケースを削除し、削除成功の応答を返します。
  2. 取得: 親クラスの取得メソッドをオーバーライドして、単一のテスト ケースの詳細を取得し、処理後に関連データを返します。
  3. get_serializer_class: 要求されたさまざまなアクションに応じて、シリアル化用のさまざまなシリアライザーを選択します。
  4. get_testcase_qs: テスト ケースのクエリセットを取得します。

さらに、コメント アウトされたコード部分があります。これには、テスト ケースの実行、タイムスタンプに従ってディレクトリの作成、テスト ケース ファイルの生成、およびテスト ケースを実行してテスト レポートを生成するロジックが含まれています。

このコードでは、handle_datas、common などのいくつかのカスタム ツール クラスと関数が使用されていることに注意してください。関連するコードは提供されていないため、実際の状況に応じて補足する必要がある場合があります。

おすすめ

転載: blog.csdn.net/qq_39208536/article/details/131789464
おすすめ