中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

自己給網(wǎng)站做優(yōu)化怎么做百度seo高級優(yōu)化

自己給網(wǎng)站做優(yōu)化怎么做,百度seo高級優(yōu)化,WordPress互聯(lián),深圳做二維碼網(wǎng)站建設(shè)🍅 視頻學(xué)習(xí):文末有免費的配套視頻可觀看 🍅 關(guān)注公眾號:互聯(lián)網(wǎng)雜貨鋪,回復(fù)1 ,免費獲取軟件測試全套資料,資料在手,漲薪更快 接口測試三要素: 參數(shù)構(gòu)造 發(fā)起請求&#x…

🍅 視頻學(xué)習(xí):文末有免費的配套視頻可觀看

🍅?關(guān)注公眾號:互聯(lián)網(wǎng)雜貨鋪,回復(fù)1?,免費獲取軟件測試全套資料,資料在手,漲薪更快

接口測試三要素

  • 參數(shù)構(gòu)造

  • 發(fā)起請求,獲取響應(yīng)

  • 校驗結(jié)果

一、原始狀態(tài)

當(dāng)我們的用例沒有進行分層設(shè)計的時候,只能算是一個“苗條式”的腳本。以一個后臺創(chuàng)建商品活動的場景為例,大概流程是這樣的(默認已經(jīng)是登錄狀態(tài)下):

創(chuàng)建商品-創(chuàng)建分類-創(chuàng)建優(yōu)惠券-創(chuàng)建活動

要進行接口測試的話,按照接口測試的三要素來進行,具體的效果如下:

 # 1、參數(shù)構(gòu)造createCommodityParams = {"input": {"title": "活動商品","subtitle": "","brand": "","categoryLevel1Code": "12","categoryLevel2Code": "1312","categoryLevel3Code": "131211","detail": [{"uri": "ecommerce/1118d9.jpg","type": 0}],"installInfo": {"installType": 1,"installFee": null},"pictureList": [{"uri": "ecommerce/222.jpg","main": true}],"postageInfo": {"postageType": 2,"postageFee": 1,"postageId": null},"sellerDefinedCode": "","publish": 1,"skuList": [{"skuCode": "","externalSkuCode": "","price": 1,"retailPrice": 6,"stock": 100,"weight": 0,"suggestPrice": 0,"skuAttrValueList": [{"attrCode": "COLOR","attrName": "顏色","attrValue": "綠色","attrValueId": "1001"}]}],"jumpSwitch":false,"recommendCommodityCodeList": [],"recommendFittingCodeList": [],"mallCode": "8h4xxx"}}createCategoryParams = {......}createCouponParams = {......}createPublicityParams = {......}publishCommodityParams = {......}publishPublicityParams = {......}createCommodityParams["input"]["title"] = "autoTest" + str(time.time())createCommodityParams["input"]["mallCode"] = self.mallCodecreateCommodityParams["input"]["skuList"][0]["price"] = random.randint(1,10)createCategoryParams["input"]["categoryName"] = "autoTestCategory" + str(time.time())createCouponParams。。。createPublicityParams。。。publishCommodityParams。。。publishPublicityParams。。。# 2、發(fā)起請求,獲取響應(yīng)# 創(chuàng)建商品并獲取商品codecreateCommodityRes = api.getUrl("testApi.create.commodity").post.params(createCommodityParams)commodityCode = createCommodityRes["commodityCode"]# 創(chuàng)建分類并獲取分類codecreateCategoryRes = api.getUrl("testApi.create.category").post.params(createCategoryParams)categoryCode = createCategoryRes["categoryCode"]# 創(chuàng)建優(yōu)惠券并獲取優(yōu)惠券codecreateCouponRes = api.getUrl("testApi.create.coupon").post.params(createCouponParams)couponCode = createCouponRes["couponCode"]# 創(chuàng)建活動并關(guān)聯(lián)商品,綁定優(yōu)惠券,設(shè)置分類createPublicityParams["input"]["commodityCode"] = commodityCodecreatePublicityParams["input"]["categoryCode"] = categoryCodecreatePublicityParams["input"]["couponCode"] = couponCodecreatePublicityRes = api.getUrl("testApi.create.publicity").post.params(createPublicityParams)# 結(jié)果校驗(斷言)assert.equal(createPublicityRes["code"], 0)assert.equal(createPublicityRes["publicityName"], createPublicityParams["publicityName"])。。。

按照上面的寫法,對于單個腳本的調(diào)式來說或許可以,但是一旦用例的數(shù)量和復(fù)雜程度積累起來后,其維護成本將是巨大的,或者可以說不具備可維護性。

弊端說明

  • 可讀性差,所有的處理都放在一起,代碼量大,不簡潔直觀

  • 靈活性差,參數(shù)寫死在腳本,適用用例范圍小

  • 復(fù)用性差,如果其他用例需要同樣或類似的步驟,需要重新寫一份

  • 維護性差,如果接口有任何改動,那么所有涉及到此接口的腳本都需要一一修改

例如:隨著用例場景的增加,就可能會出現(xiàn)下面這種情況

按照原始的模式,我們就需要些3個腳本文件分別來描述著3個場景,并且創(chuàng)建商品_API、創(chuàng)建分類_API、創(chuàng)建優(yōu)惠券_API在場景1,2,3中均出現(xiàn)了;上架商品_API在場景2,3中均出現(xiàn)。由此我們完全可以預(yù)見到,當(dāng)幾百上千的用例場景出現(xiàn)后,這種形式是沒有維護性可言的。

二、進化歷程

因此我們依照著痛點,以最開始的原始狀態(tài)為例,對用例進行分層改造,來看看進化后的狀態(tài)。

1、API 定義層

我們編程的時候會將一些重復(fù)的代碼進行封裝使用,那么這里依然可以借用這種思想,我們將 API 的定義單獨抽離,單獨定義。

我們期望的效果是這樣的:

提前將API的定義放在一層,供用例場景引用,這樣當(dāng)接口有任何修改時,我們只需要修改API definition層即可。

實例演示

對應(yīng)著上面的demo,我們就是需要做如下抽離:

class APIDefinition:
‘’’
創(chuàng)建商品API定義
createCommodityParams: 創(chuàng)建商品接口入?yún)?br /> return:創(chuàng)建商品接口響應(yīng)結(jié)果
‘’’
def createCommodityRequest(createCommodityParams):
return api.getUrl(“testApi.create.commodity”).post.params(createCommodityParams)

     '''創(chuàng)建分類API定義createCategoryParams: 創(chuàng)建分類接口入?yún)eturn:創(chuàng)建分類接口響應(yīng)結(jié)果''' def createCategoryRequest(createCategoryParams)return api.getUrl("testApi.create.category").post.params(createCategoryParams)# 創(chuàng)建優(yōu)惠券接口定義def createCouponRequest(createCouponParams)return api.getUrl("testApi.create.coupon").post.params(createCouponParams)# 創(chuàng)建活動接口定義def createPublicityRequest(createPublicityParams)return api.getUrl("testApi.create.publicity").post.params(createPublicityParams)# ...其余省略

2、Service 層

上面我們已經(jīng)將接口的定義抽離出來,解決了 API 重復(fù)定義的問題,但是再繼續(xù)分析會發(fā)現(xiàn)有一個問題依然沒有解決,就是場景的復(fù)用性.

再看剛才的圖:

3個場景中都有重復(fù)的步驟,類似創(chuàng)建商品、創(chuàng)建分類、創(chuàng)建優(yōu)惠券這些,并且這些步驟都是一個個API的組合,一個步驟對應(yīng)一個API,在各個步驟之間還會有數(shù)據(jù)的處理與傳遞,為了解決這些問題,將對場景再次做抽離,這里我稱之為?service?層。

這一層之所以叫做service(服務(wù))層,是因為它的作用是用來提供測試用例所需要的各種“服務(wù)”,好比參數(shù)構(gòu)建、接口請求、數(shù)據(jù)處理、測試步驟。

用下圖先來看分層的目標(biāo):

我們希望將常用的測試場景步驟封裝至service層中,供用例場景調(diào)用,增加復(fù)用性,也可以理解為測試用例的前置處理;

但是這里還是有一點小問題,就是service層的東西太多太雜,有些場景步驟可能只適用于我當(dāng)前的項目用例,在實際的工作中,各個系統(tǒng)間是相互依賴的,前臺APP的測試很大可能就依賴后臺創(chuàng)建作為前置條件

好比我在APP端只要商品和分類,可能只想創(chuàng)建商品和分類,并不想創(chuàng)建優(yōu)惠券,這個時候service層就沒有適用的場景步驟供調(diào)用,那么我就需要根據(jù)自己的需要重新封裝;可是對于很多單接口的前置數(shù)據(jù)處理又是一致的,比如:

     createCommodityParams["input"]["title"] = "autoTest" + str(time.time())createCommodityParams["input"]["mallCode"] = self.mallCodecreateCommodityParams["input"]["skuList"][0]["price"] = random.randint(1,10)createCategoryParams["input"]["categoryName"] = "autoTestCategory" + str(time.time())createCouponParams。。。createPublicityParams。。。publishCommodityParams。。。publishPublicityParams。。。

重新封裝的話還要再處理這一步,就有點麻煩且不符合我們的復(fù)用性設(shè)計了,因此我們對service層再細化為3層,分別為:

apiObject

單接口的預(yù)處理層,這一層主要作用是單接口入?yún)⒌臉?gòu)造,接口的請求與響應(yīng)值返回

  • 每個接口請求不依賴與業(yè)務(wù)步驟,都是單接口的請求;

  • 此外一些簡單固定的入?yún)?gòu)建也直接放在這里處理,比如隨機的商品名,title等,和具體業(yè)務(wù)流程無關(guān),針對所有調(diào)用此接口的場景均適用

caseService

多接口的預(yù)處理層,這一層主要是測試步驟(teststep)或場景的有序集合。

  • 用例所需要的步驟,通過每一個請求進行組合,每一個步驟都對應(yīng)著一個API請求,這些步驟會組成一個個場景,各個場景之間可以互相調(diào)用組成新的場景,以適應(yīng)不同的測試用例需求。

  • 場景封裝好以后可以供不同的測試用例調(diào)用,除了當(dāng)前項目的用例,其他業(yè)務(wù)線需要的話也可從此caseService中選擇調(diào)用,提高復(fù)用性的同時也避免了用例相互依賴的問題。

util

這一層主要放置針對當(dāng)前業(yè)務(wù)的接口需要處理的數(shù)據(jù)

  • 在實際編寫測試步驟時,可能部分接口的參數(shù)是通過其他接口獲取后經(jīng)過處理才可以使用,或是修改數(shù)據(jù)格式,或是修改字段名稱,亦或是某些 value 的加解密處理等。

細化分層后,各層的職責(zé)便更加清晰明確,具體如下圖:

實例演示

apiObject:

  class ApiObject:def createCommodity(createCommodityParams):inputParams = ApiParamsBuild().createCommodityParamsBuild(createCommodityParams)response = APIDefinition().createCommodityRequest(inputParams)return responsedef createCategory(createCategoryParams):...def createCoupon(createCouponParams):.........class ApiParamsBuild:def createCommodityParamsBuild(createCommodityParams):createCommodityParams["input"]["title"] = "autoTest" + str(time.time())createCommodityParams["input"]["mallCode"] = self.mallCodecreateCommodityParams["input"]["skuList"][0]["price"] = random.randint(1,10)return createCommodityParamsdef createCategoryParamsBuild(createCategoryParams):...def createCouponParamsBuild(createCouponParams):.........

到此,我們來看看原始的用例經(jīng)過目前封裝后的模樣:

1、參數(shù)構(gòu)造

    createCommodityParams = {"input": {"title": "活動商品","subtitle": "","brand": "","categoryLevel1Code": "12","categoryLevel2Code": "1312","categoryLevel3Code": "131211","detail": [{"uri": "ecommerce/1118d9.jpg","type": 0}],"installInfo": {"installType": 1,"installFee": null},"pictureList": [{"uri": "ecommerce/222.jpg","main": true}],"postageInfo": {"postageType": 2,"postageFee": 1,"postageId": null},"sellerDefinedCode": "","publish": 1,"skuList": [{"skuCode": "","externalSkuCode": "","price": 1,"retailPrice": 6,"stock": 100,"weight": 0,"suggestPrice": 0,"skuAttrValueList": [{"attrCode": "COLOR","attrName": "顏色","attrValue": "綠色","attrValueId": "1001"}]}],"jumpSwitch":false,"recommendCommodityCodeList": [],"recommendFittingCodeList": [],"mallCode": "8h4xxx"}}createCategoryParams = {......}createCouponParams = {......}createPublicityParams = {......}publishCommodityParams = {......}publishPublicityParams = {......}# 2、發(fā)起請求,獲取響應(yīng)# 創(chuàng)建商品并獲取商品codecreateCommodityRes = ApiObject().createCommodity(createCommodityParams)commodityCode = createCommodityRes["commodityCode"]# 創(chuàng)建分類并獲取分類codecreateCategoryRes = ApiObject().createCategory(createCategoryParams)categoryCode = createCategoryRes["categoryCode"]# 創(chuàng)建優(yōu)惠券并獲取優(yōu)惠券codecreateCouponRes = ApiObject().createCoupon(createCouponParams)couponCode = createCouponRes["couponCode"]# 創(chuàng)建活動并關(guān)聯(lián)商品,綁定優(yōu)惠券,設(shè)置分類createPublicityParams["input"]["commodityCode"] = commodityCodecreatePublicityParams["input"]["categoryCode"] = categoryCodecreatePublicityParams["input"]["couponCode"] = couponCodecreatePublicityRes = ApiObject().createPublicity(createPublicityParams)# 結(jié)果校驗(斷言)assert.equal(createPublicityRes["code"], 0)assert.equal(createPublicityRes["publicityName"], createPublicityParams["publicityName"])。。。
可以看到,現(xiàn)在接口請求的url、method、通用入?yún)⑻幚淼纫呀?jīng)不會在用例中體現(xiàn)了,接下來繼續(xù)封裝caseService層。caseService:我們將多接口的場景步驟進行封裝
```    class CaseService:def createPublicityByCategory(params):# 創(chuàng)建商品并獲取商品codecreateCommodityRes = ApiObject().createCommodity(createCommodityParams)commodityCode = createCommodityRes["commodityCode"]# 創(chuàng)建分類并獲取分類codecreateCategoryRes = ApiObject().createCategory(createCategoryParams)categoryCode = createCategoryRes["categoryCode"]# 創(chuàng)建優(yōu)惠券并獲取優(yōu)惠券codecreateCouponRes = ApiObject().createCoupon(createCouponParams)couponCode = createCouponRes["couponCode"]# 創(chuàng)建活動并關(guān)聯(lián)商品,綁定優(yōu)惠券,設(shè)置分類createPublicityParams["input"]["commodityCode"] = commodityCodecreatePublicityParams["input"]["categoryCode"] = categoryCodecreatePublicityParams["input"]["couponCode"] = couponCodecreatePublicityRes = ApiObject().createPublicity(createPublicityParams)return createPublicityRes......

這時體現(xiàn)在用例中的表現(xiàn)就如下層testcase層所示.

3、testcase 層

我們想要的是一個清晰明了,“一勞永逸”的自動化測試用例,就像我們的手工測試用例一樣,我們的前置條件可以復(fù)用,我們?nèi)雲(yún)⒖梢匀我庑薷?#xff0c;但測試步驟都是固定不變的(前提可能是產(chǎn)品沒有偷偷改需求~)。

這一層其實是對應(yīng)的testsuite(測試用例集),是測試用例的無序集合。其中各個用例之間應(yīng)該是相互獨立,互不干擾,不存在依賴關(guān)系,每個用例都可以單獨運行。

最終我們期望自動化用例的維護過程中達到的效果如下:
testcase 層:

   # 1、參數(shù)構(gòu)造createCommodityParams = {"input": {"title": "活動商品","subtitle": "","brand": "","categoryLevel1Code": "12","categoryLevel2Code": "1312","categoryLevel3Code": "131211","detail": [{"uri": "ecommerce/1118d9.jpg","type": 0}],"installInfo": {"installType": 1,"installFee": null},"pictureList": [{"uri": "ecommerce/222.jpg","main": true}],"postageInfo": {"postageType": 2,"postageFee": 1,"postageId": null},"sellerDefinedCode": "","publish": 1,"skuList": [{"skuCode": "","externalSkuCode": "","price": 1,"retailPrice": 6,"stock": 100,"weight": 0,"suggestPrice": 0,"skuAttrValueList": [{"attrCode": "COLOR","attrName": "顏色","attrValue": "綠色","attrValueId": "1001"}]}],"jumpSwitch":false,"recommendCommodityCodeList": [],"recommendFittingCodeList": [],"mallCode": "8h4xxx"}}createCategoryParams = {......}createCouponParams = {......}createPublicityParams = {......}publishCommodityParams = {......}publishPublicityParams = {......}# 2、發(fā)起請求,獲取響應(yīng)createPublicityRes = CaseService().createPublicityByCategory(createCommodityParams,createCategoryParams,createCouponParams...)# 結(jié)果校驗(斷言)assert.equal(createPublicityRes["code"], 0)assert.equal(createPublicityRes["publicityName"], createPublicityParams["publicityName"])。。。

可以看到,這時涉及到用例場景步驟的代碼已經(jīng)非常少了,并且完全獨立,與框架、其他用例等均無耦合。

到這里我們再看用例,會發(fā)現(xiàn)一點,測試數(shù)據(jù)依然冗長,那么下面就開始對測試數(shù)據(jù)進行參數(shù)化和數(shù)據(jù)驅(qū)動的處理。

4、testdata

此層用來管理測試數(shù)據(jù),作為參數(shù)化場景的數(shù)據(jù)驅(qū)動。

參數(shù)化: 所謂參數(shù)化,簡單來說就是將入?yún)⒗米兞康男问絺魅?#xff0c;不要將參數(shù)寫死,增加靈活性,好比搜索商品的接口,不同的關(guān)鍵字和搜索范圍作為入?yún)?#xff0c;就會得到不同的搜索結(jié)果。上面的例子中其實已經(jīng)是參數(shù)化了。

數(shù)據(jù)驅(qū)動:對于參數(shù),我們可以將其放入一個文件中,可以存放多個入?yún)?#xff0c;形成一個參數(shù)列表的形式,然后從中讀取參數(shù)傳入接口即可。常見做數(shù)據(jù)驅(qū)動的有 JSON、CSV、YAML 等。

實例演示

我們以CSV為例,不特別依照某個框架,通常測試框架都具備參數(shù)化的功能。

將所需要的入?yún)⒎湃雝est.csv文件中:

  createCommodityParams,createCategoryParams,...{"input": {"title": "活動商品","subtitle": "","brand": "","categoryLevel1Code": "12","categoryLevel2Code": "1312","categoryLevel3Code": "131211","detail": [{"uri": "ecommerce/1118d9.jpg","type": 0}],"installInfo": {"installType": 1,"installFee": null},"pictureList": [{"uri": "ecommerce/222.jpg","main": true}],"postageInfo": {"postageType": 2,"postageFee": 1,"postageId": null},"sellerDefinedCode": "","publish": 1,"skuList": [{"skuCode": "","externalSkuCode": "","price": 1,"retailPrice": 6,"stock": 100,"weight": 0,"suggestPrice": 0,"skuAttrValueList": [{"attrCode": "COLOR","attrName": "顏色","attrValue": "綠色","attrValueId": "1001"}]}],"jumpSwitch":false,"recommendCommodityCodeList": [],"recommendFittingCodeList": [],"mallCode": "8h4xxx"}},...

然后再回到用例層,利用框架參數(shù)化的功能對數(shù)據(jù)進行讀取

    # 1、參數(shù)構(gòu)造@parametrize(params = readCsv("test.csv"))# 2、發(fā)起請求,獲取響應(yīng)createPublicityRes = CaseService().createPublicityByCategory(params)# 結(jié)果校驗(斷言)assert.equal(createPublicityRes["code"], 0)assert.equal(createPublicityRes["publicityName"], createPublicityParams["publicityName"])。。。

注:這里的測試數(shù)據(jù),不僅僅局限于接口的請求參數(shù),既然做數(shù)據(jù)驅(qū)動,那么斷言也可以維護在此,以減少用例層的代碼冗余。

5、rawData

這一層是存放接口原始入?yún)⒌牡胤健?/p>

某些接口的入?yún)⒖赡芎芏?#xff0c;其中很多參數(shù)值又可能是固定不變的,構(gòu)建入?yún)⒌臅r候我們只想對"變"的值進行動態(tài)的維護,而不維護的值就使用原始參數(shù)中的默認值,以此減少工作量(emmm…可能也就是CV大法的量吧~)

再者就是數(shù)據(jù)驅(qū)動的數(shù)據(jù)文件中只維護需要修改的參數(shù),使數(shù)據(jù)文件更簡潔,可閱讀性更強。

實例演示:

這種利用原始參數(shù)(rawData)的方法我們稱之為模板化,實際工作中有多種方式可實現(xiàn),例如jsonpath、Mustache或者自己根據(jù)需求實現(xiàn)方法,本文重點在介紹分層設(shè)計,所以就不具體演示模板化技術(shù)的細節(jié)了,僅說明設(shè)計此層的作用。

以實例中的入?yún)reateCommodityParams為例,未用模板化技術(shù)前,我們要在CSV里面維護完整的入?yún)?#xff1a;

 createCommodityParams,createCategoryParams,...{"input": {"title": "活動商品","subtitle": "","brand": "","categoryLevel1Code": "12","categoryLevel2Code": "1312","categoryLevel3Code": "131211","detail": [{"uri": "ecommerce/1118d9.jpg","type": 0}],"installInfo": {"installType": 1,"installFee": null},"pictureList": [{"uri": "ecommerce/222.jpg","main": true}],"postageInfo": {"postageType": 2,"postageFee": 1,"postageId": null},"sellerDefinedCode": "","publish": 1,"skuList": [{"skuCode": "","externalSkuCode": "","price": 1,"retailPrice": 6,"stock": 100,"weight": 0,"suggestPrice": 0,"skuAttrValueList": [{"attrCode": "COLOR","attrName": "顏色","attrValue": "綠色","attrValueId": "1001"}]}],"jumpSwitch":false,"recommendCommodityCodeList": [],"recommendFittingCodeList": [],"mallCode": "8h4xxx"}},...

但是實際上,我們可能僅僅需要修改維護其中某個或某幾個字段(例如只想維護商品價格),其余的使用默認值即可,使用模板化技術(shù)后可能在CSV中就是這樣的表現(xiàn):

createCommodityParams,createCategoryParams,...{"input": {"skuList": [{"price": 1,"retailPrice": 6}},...

或者這樣

- keyPath: $.input.skuList[0].pricevalue: 1- keyPath: $.input.skuList[0].retailPricevalue: 6

亦或使用Mustache,將需要修改的value進行參數(shù)化{{value}}。

我們可以看到,這樣處理后的數(shù)據(jù)驅(qū)動的文件就變得簡潔清晰的許多,當(dāng)一個文件中維護了多個用例且入?yún)⒆侄魏芏鄷r,這樣維護起來就可以清晰的看出每個數(shù)據(jù)對應(yīng)的用例的作用了;

price就是為了測試價格的,stock就是為了測試庫存的,publish就是為了測試上下架的等等。

注: 當(dāng)然,此層的使用視實際情況而定,有可能這個接口的參數(shù)本身就沒多少,那么直接全量使用就行,或者你就是覺得數(shù)據(jù)量哪怕再大我都能分得清楚,看的明白,不用也rawData是可以的~

6、Base

此層主要放置我們需要處理的公共前置條件和一些自動化公共方法,也可以理解為公共的config和util。

在我們實際的自動化開發(fā)過程中,有很多前置條件或公共方法,比如登錄處理,log 處理,斷言方法或一些數(shù)據(jù)處理;

使用過程中所有的service和testcase層都會繼承此類,這樣這些公共方法和前置條件便可直接通用;在各個業(yè)務(wù)線之間也可保持一致性。

三、完結(jié)

最后,我們來看下整體分層后的目錄結(jié)構(gòu)總覽:

 └─apiautotest└─project└─rawData(原始參數(shù))├─testRawData.json└─service(用例服務(wù))└─apiObject(單接口預(yù)處理,單接口入?yún)⒌臉?gòu)造,接口的請求與響應(yīng)值返回)├─testApiObject.py└─caseService(多接口預(yù)處理,測試步驟(teststep)或場景的有序集合)├─testCaseService.py└─util(工具類)├─util.py└─testcase(測試用例)└─testDataDriven(測試數(shù)據(jù)驅(qū)動)├─testData.csv├─testcase.py(測試用例集)└─testBase.py(測試基類,初始化和公共方法) └─platformapi(Api定義)├─testApiDefinition.py

同時,在這我為大家準(zhǔn)備了一份軟件測試視頻教程(含面試、接口、自動化、性能測試等),就在下方,需要的可以直接去觀看,也可以直接【點擊文末小卡片免費領(lǐng)取資料文檔】

自動化測試從菜鳥到高手【2024最新完整版】,從基礎(chǔ)到項目實戰(zhàn)(Python自動化測試保姆級教程)

http://m.risenshineclean.com/news/58210.html

相關(guān)文章:

  • 網(wǎng)站建設(shè)比較好西安seo霸屏
  • 影樓網(wǎng)站源碼php免費個人網(wǎng)站注冊
  • 山東定制網(wǎng)站建設(shè)公司鄭州網(wǎng)絡(luò)營銷學(xué)校
  • 淺談全球五金網(wǎng)電子商務(wù)網(wǎng)站建設(shè)營銷寶
  • 個人網(wǎng)站設(shè)計畢業(yè)設(shè)計論文百度關(guān)鍵詞推廣費用
  • 石景山周邊網(wǎng)站建設(shè)免費個人博客網(wǎng)站
  • wordpress 安裝證書seo引擎
  • 投資網(wǎng)站實名認證可以做嗎深圳網(wǎng)站seo
  • 專門做棋牌廣告廣告的網(wǎng)站查網(wǎng)站排名
  • 做班級網(wǎng)站的實訓(xùn)報告網(wǎng)站怎么才能被百度收錄
  • 商務(wù)部市場體系建設(shè)司網(wǎng)站北京百度網(wǎng)站排名優(yōu)化
  • 以小說名字做網(wǎng)站的小說網(wǎng)關(guān)鍵詞搜索熱度
  • pc網(wǎng)站和app哪個容易做百度一下搜索
  • 國家企業(yè)信息系統(tǒng)官方seo優(yōu)化多久能上排名
  • 用eclipse編程做網(wǎng)站自動app優(yōu)化最新版
  • 網(wǎng)站開發(fā)計劃書范文怎么創(chuàng)建一個網(wǎng)址
  • 保定定興網(wǎng)站建設(shè)安卓手機優(yōu)化神器
  • 如何查找做網(wǎng)站的服務(wù)商白山網(wǎng)絡(luò)推廣
  • 做網(wǎng)站跟app的區(qū)別營銷策劃公司排行榜
  • 自己做的網(wǎng)站怎么設(shè)置文件下載國外免費網(wǎng)站服務(wù)器
  • 怎樣做企業(yè)手機網(wǎng)站seo二級目錄
  • 網(wǎng)站點擊量怎么看關(guān)鍵詞排名批量查詢
  • 云客服系統(tǒng)合肥百度搜索優(yōu)化
  • 6黃頁網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣公司主要做什么
  • 站點建錯了網(wǎng)頁能打開嗎seo還有用嗎
  • 網(wǎng)站html地圖怎么做百度廣告競價
  • 全椒做網(wǎng)站seo專業(yè)培訓(xùn)
  • 網(wǎng)站建設(shè)內(nèi)容和功能的介紹做百度推廣銷售怎么找客戶
  • 中山比好的做網(wǎng)站的公司企業(yè)官網(wǎng)
  • 自己買主機可以做網(wǎng)站嗎濟南seo小黑seo