使用Django快速完成測(cè)試數(shù)據(jù)構(gòu)造(二)

作為一枚中臺(tái)測(cè)試侨把,我們的功能太過(guò)依賴(lài)上游數(shù)據(jù)犀变,比如我只需要測(cè)試支付,但必須要一步步填寫(xiě)各種資料提交訂單才可以測(cè)支付功能秋柄,此類(lèi)數(shù)據(jù)我們可以通過(guò)python的request获枝、json模塊模擬創(chuàng)建訂單過(guò)程,實(shí)現(xiàn)一秒創(chuàng)建訂單骇笔。
梳理完成該功能步驟:
1.學(xué)習(xí)了解request省店、json模塊嚣崭,抓取請(qǐng)求,封裝為函數(shù)懦傍,參數(shù)處理雹舀、發(fā)送請(qǐng)求、接收處理返回結(jié)果
2.Django多數(shù)據(jù)聯(lián)用粗俱,復(fù)雜功能依賴(lài)多個(gè)數(shù)據(jù)庫(kù)
4.頁(yè)面模擬請(qǐng)求说榆、校驗(yàn)返回結(jié)果、返回關(guān)鍵信息到頁(yè)面

一寸认、學(xué)習(xí)了解request签财、json模塊

1.1 抓取請(qǐng)求

使用charles或者fiddler抓取創(chuàng)建訂單請(qǐng)求,保存請(qǐng)求偏塞、參數(shù)列表唱蒸、返回結(jié)果

1.2 處理參數(shù)列表為python字典格式

使用vim替換功能格式化列表為python字典的格式

1.3 封裝為函數(shù),模擬發(fā)送請(qǐng)求灸叼、接收響應(yīng)結(jié)果

使用request模擬客戶端提交訂單請(qǐng)求神汹,請(qǐng)求參數(shù)、接收返回結(jié)果并轉(zhuǎn)換為json格式返回
代碼示例:

# coding:utf-8
import requests
import json
'''
author:xxx
功能:
1.創(chuàng)建xx訂單
古今。屁魏。。
創(chuàng)建日期:xxxx-xx-xx
修改日期:xxxx-xx-xx by xxx
'''
# 提交xx訂單
def commitOrder(userId, xxId, providerId, productId, compactId, token):
    url = 'http://mobile-api.xxx.com/xxxapi/xx_xx?ck=16840f92-1f83-4a68-8a39-e6262f6f11e5'
    data = {
        ......(非關(guān)鍵參數(shù)直接給定義值即可)
        'xxx': str(xxId),
        ......
        
        'xxx': str(ProductId),
        'xxx': str(userid),
        ......
        'xxx': str(providerId),
        ......
        'xxx': str(compactId),
        ......
        'xxx': str(userid),
        ......
        '_t': token,
       ......
        'xxx': '[{"id":"0","xxx":"autoCreateOrder"}]'
    }

    res_1 = requests.post(url, data).json()
    res_2 = json.dumps(res_1, indent=2)
    res = json.loads(res_2)
    content = res.get('content')
    return content

二沧卢、Django多數(shù)據(jù)聯(lián)用

該功能參考了尚學(xué)堂以為老師的攻略蚁堤,整個(gè)分享寫(xiě)的非常非常詳細(xì):
https://code.ziqiangxuetang.com/django/django-tutorial.html

2.1在項(xiàng)目中創(chuàng)建database_router.py添加如下代碼

# -*- coding: utf-8 -*-
from django.conf import settings

DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING

class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.
    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router will fallback to the `default` database.
    Settings example:
    DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
    """

    def db_for_read(self, model, **hints):
        """"Point all read operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        if model._meta.app_label in DATABASE_MAPPING:
            return DATABASE_MAPPING[model._meta.app_label]
        return None

    def allow_relation(self, obj1, obj2, **hints):
        """Allow any relation between apps that use the same database."""
        db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
        db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
        if db_obj1 and db_obj2:
            if db_obj1 == db_obj2:
                return True
            else:
                return False
        return None

    # for Django 1.4 - Django 1.6
    def allow_syncdb(self, db, model):
        """Make sure that apps only appear in the related database."""

        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(model._meta.app_label) == db
        elif model._meta.app_label in DATABASE_MAPPING:
            return False
        return None

    # Django 1.7 - Django 1.11
    def allow_migrate(self, db, app_label, model_name=None, **hints):
        print(db, app_label, model_name, hints)
        if db in DATABASE_MAPPING.values():
            return DATABASE_MAPPING.get(app_label) == db
        elif app_label in DATABASE_MAPPING:
            return False
        return None

2.2 在setting.py中添加app、數(shù)據(jù)庫(kù)但狭、app-db對(duì)應(yīng)關(guān)系

INSTALLED_APPS添加應(yīng)用:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user',
    'account',
    'contract',
    'order',
    ......
]

DATABASES添加數(shù)據(jù)庫(kù):

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DBname1',
        'USER': 'username',
        'PASSWORD': 'pwd',
        'HOST': 'ip地址',
        'PORT': '3306',
    },
    'users': {
        'ENGINE':'django.db.backends.mysql',
        'NAME': 'DBname2',
        'HOST': 'ip地址',
        'USER': 'username',
        'PASSWORD': 'pwd',
        'PORT': '3306'
    },
    'contract': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DBname3',
        'HOST': 'ip地址',
        'USER': 'username',
        'PASSWORD': 'pwd',
        'PORT': '3306'
    },
    'order': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'DBname4',
        'HOST': 'ip地址',
        'USER': 'username',
        'PASSWORD': 'pwd',
        'PORT': '3306'
    },
    'account': {
        'ENGINE':'django.db.backends.mysql',
        'NAME': 'DBname4',
        'HOST': 'ip地址',
        'USER': 'username',
        'PASSWORD': 'pwd',
        'PORT': '3306'
    },
    ......
}

2.3 定義常量

DATABASE_ROUTERS = ['tools.database_router.DatabaseAppsRouter']

2.4定義DATABASE_APPS_MAPPING:

DATABASE_APPS_MAPPING = {
    #'app_name':'database_name',
    'user': 'users',
    'contract':'contract',
    'order':'order',
    'account':'account',
    'xxapp':'xxDB',
     ......
}

2.5 在應(yīng)用模型類(lèi)中添加如下代碼:

app_label = 'users'

2.6 操作數(shù)據(jù)庫(kù)代碼:

userId = User.objects.using('users').get(username=userName).fld_userid

三披诗、頁(yè)面設(shè)計(jì)

左側(cè)點(diǎn)擊創(chuàng)建訂單,右側(cè)顯示創(chuàng)建訂單頁(yè)面
創(chuàng)建訂單頁(yè)面需要用戶名立磁、服務(wù)提供者信息呈队、服務(wù)類(lèi)型下拉列表(bootstrap下拉列表控件)等信息

{% load i18n %}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>bootstrap 搜索下拉框</title>
  <!-- jquery -->
  <script src="http://cdn.staticfile.org/jquery/2.1.1/jquery.min.js" type="text/javascript"></script>
  <!-- bootstrap -->
  <link  rel="stylesheet">
  <script src="http://cdn.staticfile.org/twitter-bootstrap/3.3.1/js/bootstrap.min.js" type="text/javascript"></script>
  <!-- bootstrap-select -->
  <link rel="stylesheet" >
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.12.4/js/bootstrap-select.min.js"></script>
  <style>
      table {
          width: 60%;
          border: 0px;
          {#mso-cellspacing:1px ;#}
          cellpadding:"4";
          background-color: azure;
          align-content: center;
      }
      .title{
          width: 25%;
      }
      {#td{#}
      {#    width: 100%;#}
      {#}#}
      input{
          width: 100%;
          background-color: azure;
      }
      select,option{
          width: 300px;
      }
  </style>
</head>
<body>
<h1>創(chuàng)建訂單頁(yè)面</h1>
<form method="POST" action="createorder_action">
    <table border="1" >
        <tr>
            <td class="title">用戶名</td>
            <td><input type="text" name="userName" placeholder="請(qǐng)輸入xx用戶名"></td>
        </tr>
        <tr>
            <td class="title">新建xx名稱(chēng)</td>
            <td><input type="text" name="patientName" placeholder="新建xx名"></td>
        </tr>
        <tr>
            <td class="title">服務(wù)提供者用戶名</td>
            <td><input type="text" name="docotorName" placeholder="請(qǐng)輸入服務(wù)提供者用戶名"></td>
        </tr>
        <tr>
            <td class="title">服務(wù)類(lèi)型</td>
            <td>
                <select name='servicetype' class="selectpicker show-tick form-control" data-live-search="true" width="50%">
                    <option value="1">服務(wù)1(fuwu1)</option>
                    <option value="2">服務(wù)2(fuwu2)</option>
                    <option value="3">服務(wù)4(fuwu3)</option>
                    <option value="4">服務(wù)5(fuwu4)</option>
                    <option value="5">服務(wù)5(fuwu5)</option>
                    <option value="6">服務(wù)6(fuwu6)</option>
                </select>
            </td>
        </tr>

        <tr>
            <td>1分錢(qián)訂單(僅支持xx服務(wù)功能)</td>
            <td>是<input type="radio" name="is_one_money" value="1" style="width:30px" />&nbsp;&nbsp;&nbsp;&nbsp;
                否<input type="radio" name="is_one_money" value="0" checked="checked" style="width:30px"/>
            </td>
        </tr>

        <tr>
            <td colspan="2" align="center"><button type="submit">創(chuàng)建訂單</button></td>
            <td></td>
        </tr>
    </table>
</form>
<div><h2>{{ message }}</h2></div>

</body>
</html>

四、處理函數(shù)

涉及公司內(nèi)部信息較多唱歧,截取部分代碼

view.py編寫(xiě)處理函數(shù)

def createorder(request):
    response = render(request, "createorder.html")
    return response


def createorder_action(request):
    '''
   獲取用戶輸入
    '''
    userName = request.POST.get("userName")
    xxName = request.POST.get("xxName")
    providerName = request.POST.get("providerName")
    servicetype = request.POST.get('servicetype')
    is_one_money = request.POST.get("is_one_money")

    try:   
       '''
       根據(jù)用戶輸入獲取請(qǐng)求需要的信息宪摧,
       這里一般需要自己在應(yīng)用中封裝一些公用的方法/定義Const常量文件等引入當(dāng)前文件方便使用。
       比如封裝函數(shù)根據(jù)輸入的用戶名獲取用戶id颅崩,
       定義Const常量文件根據(jù)用戶選擇的服務(wù)匹配對(duì)應(yīng)常量值以避免重復(fù)寫(xiě)或手寫(xiě)出錯(cuò)
       
       '''
        utoken = gettoken(userName)
        userId = User.objects.using('users').get(username=userName).fld_userid
        docId = getDocId(docName)
        xxId1 = getxxId1(xxId1)
        xxId2 = createNewPatient(userId, xxName, utoken)
        providerId = getProviderId(xxId1)

        orderinfo = ''
        response = ''
        if servicetype == '1':
            compactinfo = getCompactInfo(ProviderId, contract.ServicedefTypeConst.type1)
            compactId = compactinfo.id
            productId = compactinfo.productid
            orderinfo = commitNetCase(userId, xxId2, providerId, productId, compactId, utoken)
            # message=userId, patientId, doctorteamHotId, basicProductId, compactId, utoken
            message = 'xx類(lèi)型訂單提交成功几于,訂單id為:' + str(orderinfo.get('orderId'))
            response = render(request, 'createorder.html', {"message": message})
        elif servicetype == '2':
            ......
        elif servicetype == '3':
            ......
        elif servicetype == '4':
            ......
        elif servicetype == '6':
            ......
           
        if is_one_money == '1':
            if servicetype == '1' or servicetype == '2' or servicetype == '5' or servicetype == '6':
                update_to_one_point(orderinfo.get("orderId"))
            elif servicetype == '3':
                update_to_one_point(orderinfo.get("xxx1"))
            elif servicetype == '4':
                update_to_one_point(orderinfo.get("xxx2"))
        elif is_one_money == '0':
            pass
        else:
            raise Exception("錯(cuò)誤的是否造1分錢(qián)訂單狀態(tài)")
        return response
    except InsecureRequestWarning:
        if is_one_money == 1:
            if servicetype == 1 or servicetype == 2 or servicetype == 5 or servicetype == 6:
                update_to_one_point(orderinfo.get("orderId"))
            elif servicetype == 3:
                update_to_one_point(orderinfo.get("xxx"))
            elif servicetype == 4:
                update_to_one_point(orderinfo.get("xxx"))
        elif is_one_money == 0:
            pass
        else:
            raise Exception("錯(cuò)誤的是否造1分錢(qián)訂單狀態(tài)")
        return response
    except Exception as e:
        message = '輸入信息有誤,或醫(yī)生不存在該服務(wù)沿后!'
        response = render(request, 'createorder.html', {"message": message})
        return response

五沿彭、配置路由

項(xiàng)目路由配置:

urlpatterns = [
   # path('admin/', admin.site.urls), 
   path("index/",views.index),
   ......
   path("order/", include("order.urls")),
   ......

]

應(yīng)用路由配置:

urlpatterns = [
   path("createorder",unifiedorder.views.createorder),
   path(r"createorder_action", unifiedorder.views.createorder_action),
]

六、大功告成尖滚,可以一鍵提交訂單啦

圖片.png

七喉刘、完善異常處理

進(jìn)行調(diào)試瞧柔、處理異常情況等,讓用戶輸入異常時(shí)頁(yè)面給出對(duì)應(yīng)提示

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末睦裳,一起剝皮案震驚了整個(gè)濱河市造锅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廉邑,老刑警劉巖哥蔚,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鬓催,居然都是意外死亡肺素,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)宇驾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)兰迫,“玉大人稽莉,你說(shuō)我怎么就攤上這事⌒持妫” “怎么了他挎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵筝尾,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我办桨,道長(zhǎng)筹淫,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任呢撞,我火速辦了婚禮损姜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殊霞。我一直安慰自己摧阅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布绷蹲。 她就那樣靜靜地躺著棒卷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祝钢。 梳的紋絲不亂的頭發(fā)上比规,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音拦英,去河邊找鬼蜒什。 笑死,一個(gè)胖子當(dāng)著我的面吹牛龄章,可吹牛的內(nèi)容都是我干的吃谣。 我是一名探鬼主播乞封,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼岗憋!你這毒婦竟也來(lái)了肃晚?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤仔戈,失蹤者是張志新(化名)和其女友劉穎关串,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體监徘,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡晋修,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凰盔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墓卦。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖户敬,靈堂內(nèi)的尸體忽然破棺而出落剪,到底是詐尸還是另有隱情,我是刑警寧澤尿庐,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布忠怖,位于F島的核電站,受9級(jí)特大地震影響抄瑟,放射性物質(zhì)發(fā)生泄漏凡泣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一皮假、第九天 我趴在偏房一處隱蔽的房頂上張望鞋拟。 院中可真熱鬧,春花似錦钞翔、人聲如沸严卖。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)哮笆。三九已至,卻和暖如春汰扭,著一層夾襖步出監(jiān)牢的瞬間稠肘,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工萝毛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留项阴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像环揽,于是被迫代替她去往敵國(guó)和親略荡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容