Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
據(jù)科學(xué)家比軟件工程師擅長(zhǎng)統(tǒng)計(jì),又比統(tǒng)計(jì)學(xué)家擅長(zhǎng)軟件工程。聽起來牛逼轟轟,事實(shí)卻是,許多數(shù)據(jù)科學(xué)家有統(tǒng)計(jì)學(xué)背景,卻沒有什么軟件工程方面的經(jīng)驗(yàn),因此在編碼時(shí)容易犯一些簡(jiǎn)單的錯(cuò)誤。作為一名高級(jí)數(shù)據(jù)科學(xué)家,本文作者總結(jié)了他在工作中常見數(shù)據(jù)科學(xué)家犯的十大錯(cuò)誤。
我是一名高級(jí)數(shù)據(jù)科學(xué)家,在 Stackoverflow 的 python 編碼中排前 1%,而且還與眾多(初級(jí))數(shù)據(jù)科學(xué)家一起工作。下文列出了我常見到的 10 個(gè)錯(cuò)誤。
沒有共享代碼中引用的數(shù)據(jù)
數(shù)據(jù)科學(xué)需要代碼和數(shù)據(jù)。所以為了讓其他人能夠復(fù)現(xiàn)自己做出來的結(jié)果,你需要提供代碼中涉及的數(shù)據(jù)。這看起來很簡(jiǎn)單,但許多人會(huì)忘記共享代碼中需要的數(shù)據(jù)。
import pandas as pd df1=pd.read_csv('file-i-dont-have.csv') # fails do_stuff(df)
解決方案:用 d6tpipe 共享代碼中的數(shù)據(jù)文件,或者將數(shù)據(jù)文件上傳到 S3/網(wǎng)頁/Google 云等,還可以將數(shù)據(jù)文件保存到數(shù)據(jù)庫中,以便收件人檢索文件(但不要將數(shù)據(jù)添加到 git 中,這一點(diǎn)后面的內(nèi)容會(huì)講到)。
硬編碼其他人無法訪問的路徑
和錯(cuò)誤 1 類似,如果硬編碼其他人無法訪問的路徑,他們就沒法運(yùn)行你的代碼,而且在很多地方都必須要手動(dòng)修改路徑。Booo!
import pandas as pd df=pd.read_csv('/path/i-dont/have/data.csv') # fails do_stuff(df) # or impor os os.chdir('c:\\Users\\yourname\\desktop\\python') # fails
解決方案:使用相對(duì)路徑、全局路徑配置變量或 d6tpipe,這樣其他人就可以輕易訪問你的數(shù)據(jù)了。
將數(shù)據(jù)和代碼混在一起
既然數(shù)據(jù)科學(xué)代碼需要數(shù)據(jù),為什么不將代碼和數(shù)據(jù)存儲(chǔ)在同一個(gè)目錄中呢?但你運(yùn)行代碼時(shí),這個(gè)目錄中還會(huì)存儲(chǔ)圖像、報(bào)告以及其他垃圾文件。亂成一團(tuán)!
├── data.csv ├── ingest.py ├── other-data.csv ├── output.png ├── report.html └── run.py
解決方案:對(duì)目錄進(jìn)行分類,比如數(shù)據(jù)、報(bào)告、代碼等。參閱 Cookiecutter Data Science 或 d6tflow 項(xiàng)目模板,并用問題 1 中提到的工具存儲(chǔ)以及共享數(shù)據(jù)。
用 Git 提交數(shù)據(jù)
大多數(shù)人現(xiàn)在都會(huì)版本控制他們的代碼(如果你沒有這么做那就是另一個(gè)問題了!)。在共享數(shù)據(jù)時(shí),可能很容易將數(shù)據(jù)文件添加到版本控制中。對(duì)一些小文件來說這沒什么問題。但 git 無法優(yōu)化數(shù)據(jù),尤其是對(duì)大型文件而言。
git add data.csv
解決方案:使用問題 1 中提到的工具來存儲(chǔ)和共享數(shù)據(jù)。如果你真的需要對(duì)數(shù)據(jù)進(jìn)行版本控制,請(qǐng)參閱 d6tpipe、DVC 和 Git Large File Storage。
寫函數(shù)而不是 DAG
數(shù)據(jù)已經(jīng)討論得夠多了,接下來我們談?wù)剬?shí)際的代碼。你在學(xué)編程時(shí),首先學(xué)的就是函數(shù),數(shù)據(jù)科學(xué)代碼主要由一系列線性運(yùn)行的函數(shù)組成。這會(huì)引發(fā)一些問題,詳情請(qǐng)參閱「4 Reasons Why Your Machine Learning Code is Probably Bad。」
def process_data(data, parameter): data=do_stuff(data) data.to_pickle('data.pkl') data=pd.read_csv('data.csv') process_data(data) df_train=pd.read_pickle(df_train) model=sklearn.svm.SVC() model.fit(df_train.iloc[:,:-1], df_train['y'])
解決方案:與其用線性鏈接函數(shù),不如寫一組有依賴關(guān)系的任務(wù)。可以用 d6tflow 或者 airflow。
寫 for 循環(huán)
和函數(shù)一樣,for 循環(huán)也是你在學(xué)代碼時(shí)最先學(xué)的。這種語句易于理解,但運(yùn)行很慢且過于冗長(zhǎng),這種情況通常表示你不知道用什么替代向量化。
x=range(10) avg=sum(x)/len(x); std=math.sqrt(sum((i-avg)**2 for i in x)/len(x)); zscore=[(i-avg)/std for x] # should be: scipy.stats.zscore(x) # or groupavg=[] for i in df['g'].unique(): dfg=df[df[g']==i] groupavg.append(dfg['g'].mean()) # should be: df.groupby('g').mean()
解決方案:NumPy、SciPy 和 pandas 都有向量化函數(shù),它們可以處理大部分你覺得需要用 for 循環(huán)解決的問題。
沒有寫單元測(cè)試
隨著數(shù)據(jù)、參數(shù)或者用戶輸入的改變,你的代碼可能會(huì)中斷,而你有時(shí)候可能沒注意到這一點(diǎn)。這就會(huì)導(dǎo)致錯(cuò)誤的輸出,如果有人根據(jù)你的輸出做決策的話,那么錯(cuò)誤的數(shù)據(jù)就會(huì)導(dǎo)致錯(cuò)誤的決策!
解決方案:用 assert 語句檢查數(shù)據(jù)質(zhì)量。Pandas 也有相同的測(cè)試,d6tstack 可以檢查數(shù)據(jù)的獲取,d6tjoin 可以檢查數(shù)據(jù)的連接。檢查數(shù)據(jù)的示例代碼如下:
assert df['id'].unique().shape[0]==len(ids) # have data for all ids? assert df.isna().sum()<0.9 # catch missing values assert df.groupby(['g','date']).size().max()==1 # no duplicate values/date? assert d6tjoin.utils.PreJoin([df1,df2],['id','date']).is_all_matched() # all ids matched?
沒有注釋代碼
我明白你急著做分析。于是你把代碼拼湊起來得到結(jié)果,把結(jié)果交給你的客戶或者老板。一周之后他們找到你,問你「你能改掉 xyz 嗎?」或「你能更新一下結(jié)果嗎?」。然后你和自己的代碼大眼瞪小眼,既不記得你為什么要這么做,也不記得你做過什么。現(xiàn)在想象一下其他人運(yùn)行這段代碼時(shí)的心情。
def some_complicated_function(data): data=data[data['column']!='wrong'] data=data.groupby('date').apply(lambda x: complicated_stuff(x)) data=data[data['value']<0.9] return data
解決方案:即便你已經(jīng)完成了分析,也要花時(shí)間注釋一下你做過什么。你會(huì)感謝自己的,當(dāng)然其他人會(huì)更加感謝你!這樣你看起來會(huì)更專業(yè)!
把數(shù)據(jù)存成 csv 或 pickle
說回?cái)?shù)據(jù),畢竟我們討論的是數(shù)據(jù)科學(xué)。就像函數(shù)和 for 循環(huán)一樣,CSV 和 pickle 文件也很常用,但它們其實(shí)并沒有那么好。CSV 不包含模式(schema),所以每個(gè)人都必須重新解析數(shù)字和日期。Pickle 可以解決這一點(diǎn),但只能用在 Python 中,而且不能壓縮。這兩種格式都不適合存儲(chǔ)大型數(shù)據(jù)集。
def process_data(data, parameter): data=do_stuff(data) data.to_pickle('data.pkl') data=pd.read_csv('data.csv') process_data(data) df_train=pd.read_pickle(df_train)
解決方案:用 parquet 或者其他帶有數(shù)據(jù)模式的二進(jìn)制數(shù)據(jù)格式,最好還能壓縮數(shù)據(jù)。d6tflow 可以自動(dòng)將數(shù)據(jù)輸出存儲(chǔ)為 parquet,這樣你就不用解決這個(gè)問題了。
使用 Jupyter notebook
這個(gè)結(jié)論還有一些爭(zhēng)議——Jupyter notebook 就像 CSV 一樣常用。很多人都會(huì)用到它們。但這并不能讓它們變得更好。Jupyter notebook 助長(zhǎng)了上面提到的許多不好的軟件工程習(xí)慣,特別是:
Jupyter notebook 很容易上手,但規(guī)模太小。
解決方案:用 pycharm 和/或 spyder。
原文鏈接:https://medium.com/m/global-identity?redirectUrl=https%3A%2F%2Ftowardsdatascience.com%2Ftop-10-coding-mistakes-made-by-data-scientists-bb5bc82faaee
要:本次分享主要介紹 Hive數(shù)據(jù)如何遷移到MaxCompute。MMA(MaxCompute Migration Assist)是一款MaxCompute數(shù)據(jù)遷移工具,本文將為大家介紹MMA工具的功能、技術(shù)架構(gòu)和實(shí)現(xiàn)原理,再通過實(shí)際操作MMA,演示將Hive數(shù)據(jù)遷移到MaxCompute。
演講嘉賓簡(jiǎn)介:阿里云智能產(chǎn)品專家-云花
精彩視頻回顧:Hive數(shù)據(jù)如何同步到MaxCompute
以下內(nèi)容根據(jù)演講視頻以及PPT整理而成。本次分享主要圍繞以下兩個(gè)方面:一、MMA功能介紹、技術(shù)架構(gòu)和原理二、MMA數(shù)據(jù)遷移操作演示
一、MMA功能介紹、技術(shù)架構(gòu)和原理1.MMA功能介紹MMA主要覆蓋的場(chǎng)景包括批處理,存儲(chǔ),數(shù)據(jù)集成,作業(yè)編排及調(diào)度。MMA提供遷移評(píng)估分析功能,自動(dòng)化生成遷移評(píng)估報(bào)告。遷移評(píng)估報(bào)告會(huì)報(bào)告出從Hive表的數(shù)據(jù)結(jié)構(gòu)到MaxCompute的數(shù)據(jù)結(jié)構(gòu)之間是否有數(shù)據(jù)類型映射兼容性問題,如語法問題。MMA支持自動(dòng)化數(shù)據(jù)遷移功能,支持批量建表以及數(shù)據(jù)自動(dòng)化批量遷移。另外,MMA還支持作業(yè)語法分析,可以檢查Hive SQL能否直接運(yùn)行在MaxCompute里。MMA還支持工作流遷移,對(duì)主流數(shù)據(jù)集成工具Sqoop進(jìn)行作業(yè)的遷移轉(zhuǎn)換,并自動(dòng)創(chuàng)新DataWorks數(shù)據(jù)繼承作業(yè)。
2.MMA遷移服務(wù)架構(gòu)MMA遷移服務(wù)架構(gòu)如下圖。左側(cè)是客戶Hadoop集群,右側(cè)的是Aliyun 大數(shù)據(jù)服務(wù),主要是DataWorks和MaxCompute。MMA工具會(huì)跑在客戶的Hadoop集群上,客戶的服務(wù)器需要能夠訪問Hive Server。在機(jī)器上部署MMA客戶端工具時(shí)會(huì)自動(dòng)化獲取Hive Meta里的數(shù)據(jù),既將Hive的Meta數(shù)據(jù)從MySQL中讀出來,還可以將Meta信息自動(dòng)轉(zhuǎn)換成MaxCompute DDL,然后用DDL在MaxCompute中批量創(chuàng)建表,批量拉起數(shù)據(jù)同步的作業(yè),向Hive Server并發(fā)提交Hive SQL作業(yè)。基于Hive SQL作業(yè)調(diào)用一個(gè)UDF,UDF里面會(huì)集成Tunnel的SDK,基于Tunnel將數(shù)據(jù)批量寫到MaxCompute的表中。作業(yè)和工作流的遷移也是基于MMA客戶端工具自動(dòng)發(fā)現(xiàn)的Hive Meta數(shù)據(jù),做工作流的作業(yè)檢查,包括把工作流的組件中的工作流的配置批量轉(zhuǎn)換成DataWorks工作流的配置,直接生成DataWorks工作流。以上步驟完成了數(shù)據(jù)到作業(yè)到工作流的遷移。最后一步是遷移完成后需要基于MaxCompute和DataWorks架構(gòu)對(duì)接業(yè)務(wù)系統(tǒng)。
3.MMA Agent技術(shù)構(gòu)架和原理通過客戶端和服務(wù)端,MMA可支持?jǐn)?shù)據(jù)和工作流的批量遷移。安裝在客戶服務(wù)器上的MMA客戶端工具包含下圖中的四個(gè)能力。首先可自動(dòng)獲取Hive Metadata,并自動(dòng)創(chuàng)建生成DDL和UDTF,而且可批量創(chuàng)建表和批量Hive數(shù)據(jù)遷移。相應(yīng)的,MMA有四個(gè)主要組件。Meta Carrier工具自動(dòng)將Hive Meta信息提取出來,在本地生成Hive Meta結(jié)構(gòu)。Meta Processor是基于Meta Carrier工具產(chǎn)出的結(jié)果,基于Hive Meta數(shù)據(jù)批量轉(zhuǎn)成MaxCompute的DDL,既批量轉(zhuǎn)成建表語句和數(shù)據(jù)類型的轉(zhuǎn)換。此外,MMA客戶端工具還內(nèi)置了ODPS Console,基于ODPS Console將Meta Processor產(chǎn)出的ODPS DDL在MaxCompute上批量創(chuàng)建表。最后基于Data Carrier批量創(chuàng)建Hive SQL作業(yè)。每個(gè)Hive SQL作業(yè)相當(dāng)于多個(gè)表或者多個(gè)分區(qū)并行的數(shù)據(jù)的同步。
二、MMA數(shù)據(jù)遷移操作演示1.環(huán)境準(zhǔn)備如下圖所示,MMA環(huán)境運(yùn)行要求是jdk1.6版本以上,Python3+。另外,運(yùn)行MMA的機(jī)器,通過Hive Client提交Hive SQL的作業(yè)。機(jī)器還需要可以訪問Hive Server,并連接MaxCompute服務(wù)。下圖右側(cè)的場(chǎng)景案例是客戶在基于MMA做同步數(shù)據(jù)時(shí)發(fā)現(xiàn)的問題。例子中客戶有自己的IDC,在阿里云有自己的ECS,客戶從IDC拉一條專線訪問阿里云。在安裝MMA之前,客戶可以從ECS上直接訪問MaxCompute,但I(xiàn)DC里的機(jī)器不能訪問MaxCompute。此時(shí)需要在這條專線上增加VBR路由配置,既在邊界路由上增加一個(gè)配置。配置之后可以打通從IDC到ECS,甚至到MaxCompute服務(wù)的網(wǎng)絡(luò)訪問。
2.下載和編譯工具包下載編譯工具包有兩種方法。一是下載下圖中編譯好的工具包。此外,由于用戶的Hive版本各不相同,用戶可以根據(jù)MMA官網(wǎng)上提供的GitHub地址下載源碼,拉到本地進(jìn)行編譯。
3.MMA Agent操作說明使用meta-carrier采集Hive Metadata:機(jī)器提前安裝好Hadoop環(huán)境,本地有Hive Server。提前下載客戶端的odps-data-carrier.zip包,并在本地解壓。解壓完成后會(huì)顯示下圖所示目錄。bin目錄下有幾個(gè)文件,首先是MMA的幾個(gè)核心角色:meta-carrier、meta-processor、odps_ddl_runner用于批量創(chuàng)建表,hive_udtf_sql_runner用于同步數(shù)據(jù)。libs目錄下是工具依賴的jar包和庫。 res目錄的console目錄下的bin目錄包含odpscmd,是MMA客戶端的工具,odps_config,ini配置文件。本地Hive上面有三個(gè)庫,其中dma_demo庫下有五個(gè)表,可將五個(gè)表自動(dòng)批量同步到MaxCompute上。首先需要在MaxCompute上創(chuàng)建一個(gè)project,既在DataWorks控制臺(tái)創(chuàng)建一個(gè)空Project。打開新的命令窗口,在本地運(yùn)行的ODPS Command客戶端工具,連接新創(chuàng)建的空的project。在已經(jīng)安裝了MMA Hive的機(jī)器上運(yùn)行,解壓,進(jìn)入odps-data-carrier工具的目錄。執(zhí)行 bin/meta-carrier -h查看其參數(shù)說明,-d表示用戶可以指定數(shù)據(jù)庫,通過指定數(shù)據(jù)庫提取meta數(shù)據(jù),若不指定,會(huì)將Hive下所有的庫的meta都拉取出來。-o指定輸出目錄,-t參數(shù)指定表,-u參數(shù)指定uri地址,即Hive Meta的地址。開始測(cè)試時(shí)首先指定地址,因?yàn)槭莟hirft地址,所以用thirft協(xié)議連接。此外由于Hive Meta在本地,所以只需要將dma_demo庫的meta拉取出來,加-o參數(shù),指定目錄。通過tree meta可以查看meta目錄結(jié)構(gòu)。meta目錄下生成和數(shù)據(jù)庫同名的dma_demo目錄。dma_demo目錄下的json文件是描述數(shù)據(jù)庫meta信息的文件。partition_meta里面的兩個(gè)表是分區(qū)表,table_meta的表是非分區(qū)表,會(huì)把所有表集的meta信息寫在下面。
使用network-measurement-tool:網(wǎng)絡(luò)測(cè)量工具network-measurement-tool用于網(wǎng)絡(luò)測(cè)速,測(cè)量Hive集群到MaxCompute各region的網(wǎng)絡(luò)連通質(zhì)量。通過網(wǎng)絡(luò)測(cè)速可以知道網(wǎng)絡(luò)傳輸速度和大概的數(shù)據(jù)量,根據(jù)網(wǎng)絡(luò)傳輸速度預(yù)估數(shù)據(jù)傳輸時(shí)間。network-measurement-tool工具連接MaxCompute上所有region的節(jié)點(diǎn)ENDPOINT地址,由最快到最慢做測(cè)速排序。下圖中執(zhí)行結(jié)果最快的是HANGZHOU,連接時(shí)間為51ms,最慢的是一個(gè)海外region KUALA_LUMPUR,連接時(shí)間為3393ms。
使用sql-checker檢查Hive SQL是否可以直接在MaxCompute上執(zhí)行:sql-checker可用于檢查Hive SQL語法兼容性,判斷SQL能否直接在MaxCompute上運(yùn)行。其參數(shù)input要指定meta目錄,指定缺省project和sql參數(shù)。若執(zhí)行結(jié)果返回其兼容性O(shè)K,即此sql語句可以直接在MaxCompute上運(yùn)行。
使用meta-processor生成ODPS DDL和Hive UDTF SQL:通過第一步已經(jīng)拉出了Hive Meta庫的metadata信息。下一步需要將Hive Meta轉(zhuǎn)換成MaxCompute DDL。使用bin/meta-processor -h查看參數(shù)。-i即input,-o是output目錄。bin/meta-processor的-i就是第一個(gè)命令的輸出結(jié)果,代表meta的目錄,存放的是carrier拉出的Hive Meta數(shù)據(jù)。指定-i meta -o output。將bin/meta-processor運(yùn)行結(jié)果放入output中。生成output目錄。tree output可查看結(jié)構(gòu)。output目錄下也會(huì)生成一個(gè)以MaxCompute的project命名的dma_demo目錄。dma_demo目錄下面有一個(gè)hive_udtf_sql目錄,目錄下面的.sql用于批量數(shù)據(jù)遷移。還包含odps_ddl目錄,用于后續(xù)批量創(chuàng)建表,目錄下的.sql是創(chuàng)建表的語句。
使用odps_ddl_runner.py批量創(chuàng)建表和分區(qū):既然DDL已經(jīng)生成,下一步需要批量創(chuàng)建表。批量創(chuàng)建表依賴MaxCompute的命令行工具(客戶端工具)。工具包一級(jí)目錄下的odps_config包含幾個(gè)基本參數(shù),其中project_name、access_id、access_key、end_point為必填項(xiàng)。配置完成可以開始批量創(chuàng)建表。批量創(chuàng)建表工具要執(zhí)行Python命令,python36 bin/odps_ddl_runner.py -h。參數(shù)中input參數(shù)由meta processer自動(dòng)生成,odpscmd參數(shù)不是必須指定的,它會(huì)默認(rèn)找到所在目錄,不需要單獨(dú)配置參數(shù)。創(chuàng)建表過程要拉起odps_command工具,基于客戶端工具來向MaxCompute提交建表語句。通過show table查看是否創(chuàng)建了五個(gè)表,再查看分區(qū)是否也建好。若Hive和MaxCompute上的分區(qū)創(chuàng)建完成,兩邊的表結(jié)構(gòu)也應(yīng)相同。
使用hive_udtf_sql_runner.py遷移數(shù)據(jù):通過命令行python36 bin/hive_udtf_sql_runner.py開始讀output目錄下的.sql語句。查看python36 bin/hive_udtf_sql_runner.py命令的參數(shù),Input_all會(huì)批量遷移output下所有數(shù)據(jù)。若只想做單表的遷移或者單分區(qū)的遷移,需要使用input_single_file參數(shù)。parallelism參數(shù)表示并行度。數(shù)據(jù)遷移完成后在MaxCompute中查看表中是否有數(shù)據(jù)。對(duì)比MaxCompute中的數(shù)據(jù)和Hive中對(duì)應(yīng)表的數(shù)據(jù)。若其size相同,Hive和MaxCompute中對(duì)應(yīng)表的數(shù)據(jù)相同,說明已經(jīng)完整遷移數(shù)據(jù)。
進(jìn)階功能1:僅生成指定的database或table的metadata:在生成meta時(shí)可以不生成整個(gè)數(shù)據(jù)庫的meta,可以指定一個(gè)表,生成一個(gè)表的meta。Meta carrier 工具提供了抓取指定數(shù)據(jù)庫可表的能力。
進(jìn)階功能2:進(jìn)靈活的hive到MaxCompute映射:如果用戶需要自定義MaxCompute上的表,可以更改命名,加前綴或后綴,修改自定義字段名。如可以修改MaxCompute DDL里的json文件實(shí)現(xiàn)表名或字段名的自定義。
進(jìn)階功能3:?jiǎn)伪砘騿畏謪^(qū)遷移:上面的例子中已經(jīng)批量遷移五張表,通過drop table inventory,演示單分區(qū)遷移。首先若只需同步一個(gè)分區(qū)的數(shù)據(jù),需要重新創(chuàng)建一張表。執(zhí)行python36 bin/odps_ddl_runner.py創(chuàng)建表,指定其output目錄,開始批量創(chuàng)建表。此時(shí)inventory表以及其五個(gè)分區(qū)已經(jīng)創(chuàng)建完成。但創(chuàng)建的分區(qū)中沒有數(shù)據(jù),可指定其中一個(gè)分區(qū),如第二個(gè)分區(qū)。通過使用input_single_file參數(shù),指定具體分區(qū)的sql目錄。可指定目錄為output/dma_demo/hive_udtf_sql/single_partition/inventory_1.sql。執(zhí)行完成后查看結(jié)果,對(duì)比在Hive上第二分區(qū)的數(shù)據(jù)和遷移進(jìn)MaxCompute的單分區(qū)的數(shù)據(jù),若兩個(gè)單分區(qū)數(shù)據(jù)一致,則表示遷移完成。
4.使用DataWorks自動(dòng)遷移數(shù)據(jù)和工作流MMA1.0版本還未將工作流遷移做成服務(wù)化功能,目前還是一個(gè)線下工具。客戶需要根據(jù)下圖模板生成相應(yīng)目錄。在做工作流遷移時(shí),如果使用開源組件,可以按照模板將配置放到相應(yīng)目錄下。如果不使用開源組件,如自研的工作流調(diào)度編排服務(wù),可基于標(biāo)準(zhǔn)化模板,按照模板的目錄結(jié)構(gòu)生成用戶自己的工作流數(shù)據(jù),打成zip包上傳到DataWorks。目前MMA1.0還需要客戶手動(dòng)打包文件上傳zip包,后臺(tái)會(huì)進(jìn)行自動(dòng)解析并加載到DataWorks工作流。上傳完成后,DataWorks服務(wù)會(huì)根據(jù)ODPS DDL 批量生成MaxCompute的table。MaxCompute表創(chuàng)建后,DataWorks服務(wù)會(huì)自動(dòng)拉起DataX的數(shù)據(jù)同步任務(wù),完成批量數(shù)據(jù)遷移。
下圖是可配置的項(xiàng)目描述文件project.xml,其中project信息可以自定義。另外一個(gè)是工作流描述文件,workflow.xml中是工作流自定義的參數(shù),用戶可以通過編輯配置文件進(jìn)行修改。
5.其他類型作業(yè)的遷移方案UDF、MR遷移:用戶直接將jar包上傳到MaxCompute上,開啟2.0支持,開啟對(duì)Hive兼容的flag。將Hive兼容的flag設(shè)置為true,再在MaxCompute下直接遷移Hive下的UDF和MR。需求注意不支持UDF,MR中直接訪問文件系統(tǒng),網(wǎng)絡(luò)訪問和外部數(shù)據(jù)源連接。外表遷移:原則上能結(jié)構(gòu)化的數(shù)據(jù)盡量遷移到MaxCompute內(nèi)部表。如果必須通過外表訪問外部文件,建議先將數(shù)據(jù)從HDPS遷移到OSS或OTS,再在MaxCompute中創(chuàng)建外部表,實(shí)現(xiàn)對(duì)文件的訪問。Spark作業(yè)遷移:MMA對(duì)開源Spark的語法完全兼容。用戶只需要下載Spark On MaxCompute客戶端,在編寫Spark SQL時(shí)僅增加MaxCompute的連接參數(shù),其它部分和Spark SQL的語法相同。
6.查看遷移評(píng)估報(bào)告創(chuàng)建MaxCompute DDL完成后,除了生成DDL會(huì)SQL以外,還會(huì)生成遷移評(píng)估報(bào)告report.html文件。遷移評(píng)估報(bào)告是一個(gè)兼容性報(bào)告,顯示Hive表的數(shù)據(jù)結(jié)構(gòu)和MaxCompute表的數(shù)據(jù)結(jié)構(gòu)之間的映射關(guān)系是否有風(fēng)險(xiǎn),并標(biāo)識(shí)風(fēng)險(xiǎn)等級(jí)。另外會(huì)給出明細(xì)說明以及預(yù)警提示,如數(shù)據(jù)類型不兼容或語法不兼容等。用戶在遷移之前可以查看此報(bào)告評(píng)估遷移風(fēng)險(xiǎn)。
查看更多:https://yqh.aliyun.com/detail/6648?utm_content=g_1000106727
上云就看云棲號(hào):更多云資訊,上云案例,最佳實(shí)踐,產(chǎn)品入門,訪問:https://yqh.aliyun.com/
口測(cè)試【接口:系統(tǒng)與系統(tǒng)之間,組件與組件之間,數(shù)據(jù)傳遞交互的通道】
1.1接口概念:指的是系統(tǒng)或組件之間的交互點(diǎn),通過這些交互點(diǎn)可以實(shí)現(xiàn)數(shù)據(jù)的交互;可分為硬件接口和軟件接口;
服務(wù)器開了個(gè)口,客戶端發(fā)送請(qǐng)求
1.2接口的類型:
①按協(xié)議劃分:http、tcp、ip②按語言劃分:C++、java、php
③按范圍劃分,系統(tǒng)之間的接口和程序內(nèi)部的接口
系統(tǒng)之間的接口:多個(gè)內(nèi)部系統(tǒng)之間的交互【用戶系統(tǒng)、訂單系統(tǒng)、商品系統(tǒng)】,內(nèi)部系統(tǒng)與外部系統(tǒng)【支付系統(tǒng)】之間的交互
程序內(nèi)部的接口:方法與方法之間,函數(shù)與函數(shù)之間【傳入不同的數(shù)據(jù),輸出不同的值,叫接口函數(shù)】,模塊與模塊之間的交互
1.3接口測(cè)試的概念
接口測(cè)試:對(duì)系統(tǒng)或組件之間的接口進(jìn)行測(cè)試,校驗(yàn)傳遞的數(shù)據(jù)正確性和邏輯依賴關(guān)系(淘寶先登錄才能看訂單,即使復(fù)制了訂單的網(wǎng)頁,但是未登錄,復(fù)制的訂單網(wǎng)頁打開還是跳轉(zhuǎn)登錄界面。)的正確性。【校驗(yàn)數(shù)據(jù)的交換、傳遞和控制管理的過程,以及相互邏輯依賴關(guān)系。】
1.4接口測(cè)試原理【接口測(cè)試主要測(cè)試目標(biāo):服務(wù)器,功能測(cè)試:測(cè)試客戶端】
1>怎么測(cè)?模擬客戶端,向服務(wù)器發(fā)送請(qǐng)求
2>用什么測(cè)?工具:fiddler、postman、jmeter;代碼:python+UnitTest框架+Requests框架
3>測(cè)試什么?測(cè)試服務(wù)器針對(duì)客戶端請(qǐng)求,回應(yīng)的響應(yīng)數(shù)據(jù)是否與預(yù)期結(jié)果一致
1.5特點(diǎn)
①測(cè)試可以提前介入,提早發(fā)現(xiàn)bug,符合質(zhì)量控制前移的理念
②可以發(fā)現(xiàn)一些頁面操作發(fā)現(xiàn)不了的問題
③接口測(cè)試低成本高效益(底層的一個(gè)bug能夠引發(fā)上層8個(gè)左右bug,接口測(cè)試可以實(shí)現(xiàn)自動(dòng)化)
④不同于傳統(tǒng)的單元測(cè)試,接口測(cè)試是從用戶的角度對(duì)系統(tǒng)進(jìn)行全面的檢查
1.6實(shí)現(xiàn)方式
工具:fiddler、postman、jmeter;代碼:python+UnitTest框架+Requests框架
1.7自動(dòng)化接口測(cè)試
接口自動(dòng)化測(cè)試:借助工具、代碼,模擬客戶端發(fā)送請(qǐng)求給服務(wù)器,借助斷言自動(dòng)判斷 預(yù)期結(jié)果和實(shí)際結(jié)果是否一致。【是讓程序或工具代替人工自動(dòng)地完成對(duì)接口進(jìn)行測(cè)試的一種過程】
(超文本傳輸協(xié)議,基于請(qǐng)求與響應(yīng)模式的,應(yīng)用層協(xié)議,也是互聯(lián)網(wǎng)上應(yīng)用最為廣泛的一種協(xié)議)【端口是用來找到應(yīng)用】
2.1 協(xié)議:就是規(guī)則。要求通信的雙方必須嚴(yán)格遵守。
2.2 特點(diǎn)
①支持客戶端/服務(wù)器模式 ②簡(jiǎn)單快速 ③靈活 ④無連接 ⑤無狀態(tài)
2.3 URL(Uniform Resource Locator)統(tǒng)一資源定位符,是互聯(lián)網(wǎng)上標(biāo)準(zhǔn)資源的地址。HTTP使用URL來建立連接和傳輸數(shù)據(jù)。
作用:在網(wǎng)絡(luò)環(huán)境中,唯一的定義一個(gè)數(shù)據(jù)資源
2.4 URL語法格式(組成)【http:80;https:443】
http[協(xié)議] :// xxxxx[域名] : xxxx[端口:0~65535] / xxxxxx[資源路徑] ? xx[k=value]&xx&x[查詢參數(shù)]
協(xié)議:規(guī)定數(shù)據(jù)傳輸?shù)姆绞?/p>
域名:在網(wǎng)絡(luò)環(huán)境中找到主機(jī) 用://與協(xié)議分隔
端口(port)【常省略】:在網(wǎng)絡(luò)主機(jī)上,標(biāo)識(shí)一個(gè)進(jìn)程(運(yùn)行起來的應(yīng)用程序) 本地主機(jī)用PID標(biāo)識(shí) 用 :與域名分隔
資源路徑:標(biāo)識(shí)網(wǎng)絡(luò)資源(文件、圖片、音視頻、變量.....) 用/與端口分隔
查詢參數(shù):參數(shù)傳遞給資源路徑 用?與資源路徑分隔,內(nèi)部用&分隔
【當(dāng)資源路徑?jīng)]有時(shí),可以認(rèn)為是“/”】
2.5 HTTP請(qǐng)求【請(qǐng)求包;請(qǐng)求報(bào)文】
1>作用:
客戶端(app、瀏覽器),發(fā)送請(qǐng)求給服務(wù)器時(shí),使用的協(xié)議--http請(qǐng)求協(xié)議
規(guī)定發(fā)送給服務(wù)器的數(shù)據(jù)傳輸?shù)恼Z法格式
2>整體格式
第一行:請(qǐng)求行:請(qǐng)求方法(空格)url(空格)協(xié)議版本
第二行:請(qǐng)求頭:語法格式 【格式:key:value】
user-agent:描述發(fā)送端的本地瀏覽器類型
Content-Type:xxxx(描述請(qǐng)求體的數(shù)據(jù)類型)通常碰到form(表單類型)和json類型
空行:代表http請(qǐng)求頭結(jié)束,請(qǐng)求體開始
請(qǐng)求體:請(qǐng)求發(fā)送時(shí)攜帶的數(shù)據(jù)。 數(shù)據(jù)類型(Content-Type)的值【post、put(相當(dāng)于修改)有請(qǐng)求體,get、delete沒有請(qǐng)求體】
3>fiddler抓包驗(yàn)證
先清空fiddler--訪問網(wǎng)站--點(diǎn)開(一般第一條)請(qǐng)求--點(diǎn)擊【raw】
4>請(qǐng)求行
http請(qǐng)求方法(大小寫無所謂)【對(duì)應(yīng)數(shù)據(jù)庫增刪改查】
GET:查詢
POST:添加(常用在登錄)
PUT:修改
DELETE:刪除
5>請(qǐng)求頭
語法格式:k:v
user-agent:產(chǎn)生請(qǐng)求瀏覽器類型
Content-Type:請(qǐng)求體數(shù)據(jù)類型
application/json:JSON數(shù)據(jù)格式(k:v)
application/x-www-form-urlencoded:form表單數(shù)據(jù)
6>請(qǐng)求體
數(shù)據(jù)值的組織形式,受Content-Type的值影響
k=v格式
get、delete方法沒有請(qǐng)求體
post、put方法有請(qǐng)求體
2.6 HTTP響應(yīng)
1>作用:服務(wù)器端,針對(duì)客戶端發(fā)送的http請(qǐng)求,回發(fā)響應(yīng)數(shù)據(jù)。 --http應(yīng)答
規(guī)定回發(fā)給客戶端的數(shù)據(jù)組織格式
2>整體格式【響應(yīng)包;響應(yīng)報(bào)文】
響應(yīng)行(狀態(tài)行):協(xié)議版本(空格)狀態(tài)碼(空格)狀態(tài)描述【狀態(tài)碼和狀態(tài)描述捆綁,狀態(tài)碼對(duì)應(yīng)狀態(tài)描述】
響應(yīng)頭:語法格式:k:v
Content-Type:描述響應(yīng)體中數(shù)據(jù)類型
空行:代表響應(yīng)頭結(jié)束
響應(yīng)體:絕大多數(shù)情況不為空(請(qǐng)求成功:回發(fā)數(shù)據(jù),失敗:回發(fā)錯(cuò)誤數(shù)據(jù))
數(shù)據(jù)類型受Content-Type值影響
3>狀態(tài)碼【有三位數(shù)字組成,第一個(gè)數(shù)字定義響應(yīng)的類別】
1xx:指示信息--表示請(qǐng)求已接收,等待繼續(xù)處理
**2xx:成功--表示請(qǐng)求已被成功接收、理解、接受:eg:200、201
3xx:重定向--待訪問的資源,需求重新指定路徑訪問。【要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作】
**4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn) eg:404【請(qǐng)求文件不存在】/403【請(qǐng)求文件存在但拒絕被訪問,也就是說沒有權(quán)限訪問】
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求
4>狀態(tài)碼描述
一般與狀態(tài)碼唯一對(duì)應(yīng)
5>響應(yīng)頭
語法格式:k:v
Content-Type:值為響應(yīng)體的數(shù)據(jù)類型
Content-Length:響應(yīng)體的大小【可不寫,瀏覽器自動(dòng)求取,一旦寫,必須準(zhǔn)確】
6>響應(yīng)體(測(cè)試中的實(shí)際結(jié)果,預(yù)期結(jié)果從接口文檔中來)
就是響應(yīng)的消息體,數(shù)據(jù)可以是普通文本、XML、JSON、HTML源碼
1>傳統(tǒng)風(fēng)格
對(duì)用戶進(jìn)行操作的相關(guān)接口,包括增刪改查
操作 | 請(qǐng)求方式 | URL | 成功狀態(tài) |
查詢某個(gè)用戶 | GET/POST | http://127.0.0.1:8080/myweb/user/getUser?id=1 http://127.0.0.1:8080/myweb/user/getById?id=1 http://127.0.0.1:8080/myweb/getUserById?id=1 | 200 |
查詢所有用戶 | GET/POST | http://127.0.0.1:8080/myweb/user/getUserList http://127.0.0.1:8080/myweb/user/getUsers | 200 |
添加用戶 | POST | http://127.0.0.1:8080/myweb/user/addUser | 200 |
修改用戶 | POST | http://127.0.0.1:8080/myweb/user/updateUser | 200 |
刪除用戶 | GET/POST | http://127.0.0.1:8080/myweb/user/deleteUser?id=1 | 200 |
特點(diǎn):
請(qǐng)求方法,只使用get和post即可
URL不唯一,不重復(fù)。同一個(gè)操作可以對(duì)應(yīng)不同的URL
狀態(tài)碼的使用較單一。200最常見
2>RESTful風(fēng)格接口【一種軟件架構(gòu)風(fēng)格、設(shè)計(jì)風(fēng)格,而不是標(biāo)準(zhǔn),只是提供了一組設(shè)計(jì)原則和約束條件】
REST:即(Representational State Transfer)的縮寫,詞組翻譯是“表現(xiàn)層狀態(tài)轉(zhuǎn)化”【同一URL,對(duì)應(yīng)的方法不同,對(duì)應(yīng)的操作也不同】,如果一個(gè)架構(gòu)符合REST原則,就稱它為RESTful架構(gòu)。
操作 | 請(qǐng)求方式 | URL | 成功狀態(tài) |
查詢某個(gè)用戶 | GET | http://127.0.0.1:8080/myweb/users/1 | 200 |
查詢所有用戶 | GET | http://127.0.0.1:8080/myweb/users | 200 |
添加用戶 | POST | http://127.0.0.1:8080/myweb/users | 201 |
修改用戶 | PUT | http://127.0.0.1:8080/myweb/users/1 | 201 |
刪除用戶 | DELETE | http://127.0.0.1:8080/myweb/users/1 | 204 |
架構(gòu)特點(diǎn):
1.每一個(gè)URL代表一種資源;
2.客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;
3.客戶端通過四個(gè)HTTP動(dòng)詞,對(duì)服務(wù)器端資源進(jìn)行操作,實(shí)現(xiàn)“表現(xiàn)層狀態(tài)轉(zhuǎn)換”(數(shù)據(jù)的不同表現(xiàn)形式,圖像、文字表現(xiàn)同一個(gè)數(shù)據(jù)對(duì)象)
4.接口之間傳遞的數(shù)據(jù)最常用格式為JSON。
5.1接口文檔
1>接口文檔:又稱為API文檔,一般是由開發(fā)人員所編寫的,用來描述系統(tǒng)所提供接口信息的文檔。大家都根據(jù)這個(gè)接口文檔進(jìn)行開發(fā),并需要一直維護(hù)和遵守。
2>作用
1.能夠讓前端開發(fā)與后臺(tái)開發(fā)人員更好的配合,提高工作效率。(有一個(gè)統(tǒng)一參考的文件)
2.項(xiàng)目選代或者項(xiàng)目人員更迭時(shí),方便后期人員查看和維護(hù)
3.方便測(cè)試人員進(jìn)行接口測(cè)試
【錯(cuò)誤碼:不是錯(cuò)誤,與http狀態(tài)碼區(qū)分開,其實(shí)是狀態(tài)碼,描述狀態(tài)】
形式:word文檔形式、Excel表格式形式、pdf文檔
基本信息:
Path:對(duì)應(yīng)url里的資源路徑(url前面的協(xié)議等在接口文檔的系統(tǒng)信息里呈現(xiàn))
Method:PUT/POST/DELETE/GET
接口描述:。。。。。
請(qǐng)求參數(shù):
Headers(請(qǐng)求頭):數(shù)據(jù)類型(k【Content-Type】:v【application/json】)
Body(請(qǐng)求體):實(shí)現(xiàn)該接口使用的數(shù)據(jù)以及對(duì)應(yīng)類型。
返回?cái)?shù)據(jù)(預(yù)期結(jié)果):成功和失敗的狀態(tài)碼
狀態(tài)碼:200 成功:狀態(tài)碼200
錯(cuò)誤碼(自定義狀態(tài)碼):碼值和描述信息 失敗:錯(cuò)誤碼(自定義狀態(tài)碼)
5.2接口文檔解析
接口文檔的解析本質(zhì):從接口文檔中,找出http請(qǐng)求所需要的數(shù)據(jù)信息,包括:
請(qǐng)求方法、URL【行里兩個(gè)】、請(qǐng)求頭(k:v)【Content-Type類型】、請(qǐng)求體【數(shù)據(jù):數(shù)據(jù)類型的名字和類型】(行頭體)、響應(yīng)狀態(tài)碼、描述。
Eg:
請(qǐng)求體:{“數(shù)據(jù)類型的名字,建議復(fù)制文檔里的不要用手敲”:“數(shù)據(jù)值,文檔中不知道,可找開發(fā)要”}
Fiddler:
K:v是json類型數(shù)據(jù)
Raw項(xiàng):方法、url、請(qǐng)求頭、請(qǐng)求體
6.1為什么要寫
1.防止測(cè)試點(diǎn)漏測(cè)、條理清晰
2.方便分配工作,評(píng)估工作量和時(shí)間
3.面試使用
6.2接口測(cè)試的測(cè)試點(diǎn)(測(cè)試維度)
6.3功能測(cè)試
手工測(cè)試中的單個(gè)業(yè)務(wù)模塊,一般對(duì)應(yīng)一個(gè)接口。
Eg: 登錄業(yè)務(wù)-->登錄接口
加入購物車業(yè)務(wù)-->加入購物車接口
支付業(yè)務(wù)-->支付接口
.........
借助工具、代碼,繞開前端界面,組織接口所需要的數(shù)據(jù),展開接口測(cè)試。
按照用戶實(shí)際使用場(chǎng)景,梳理接口業(yè)務(wù)場(chǎng)景。
組織業(yè)務(wù)場(chǎng)景時(shí),一般只需要做正向測(cè)試即可。(與手工一致)
一般建議用最少的用例覆蓋最多的業(yè)務(wù)場(chǎng)景。
Eg:登錄---搜索商品---加購物車---下單---支付---評(píng)價(jià)
6.4性能測(cè)試
1>響應(yīng)時(shí)長(zhǎng):發(fā)送請(qǐng)求,服務(wù)器多久回發(fā)響應(yīng)
2>吞吐量:當(dāng)前的接口處理用戶的請(qǐng)求事物數(shù)量
3>并發(fā)數(shù):多個(gè)用戶同時(shí)向接口發(fā)請(qǐng)求,比如淘寶秒殺
4>服務(wù)器資源利用率:CPU、內(nèi)存、顯卡、網(wǎng)絡(luò)I/O、磁盤I/O
6.5瀏覽器開發(fā)者工具
瀏覽器的開發(fā)者工具:F12或右鍵檢查打開--->Network--->一定要選擇ALL--->關(guān)于登錄,可以在網(wǎng)站界面輸入好數(shù)據(jù),點(diǎn)擊登錄按鈕--->查看
點(diǎn)擊Name下數(shù)據(jù)--->do_login(與登錄按鈕對(duì)應(yīng)):
Headers【相當(dāng)于HTTP響應(yīng),組織形式不一樣,但是數(shù)據(jù)該有的都有】:
General:表示總則;包括請(qǐng)求URL、請(qǐng)求方法、狀態(tài)碼(Status Code)、IP地址和端口號(hào)(Remote Address)
Response Headers:表示響應(yīng)頭;數(shù)據(jù)以k:v形式組織
Request Headers:表示請(qǐng)求頭;對(duì)應(yīng)HTTP請(qǐng)求頭里的信息;數(shù)據(jù)類型依然k:v形式
Query String Parameters:表示查詢字符串參數(shù),對(duì)應(yīng)url后部分的查詢參數(shù)
Form Data:表單數(shù)據(jù);比如登錄界面,這部分是登錄界面輸入的數(shù)據(jù)
Payload:有一個(gè)view source,是請(qǐng)求體的數(shù)據(jù),可以直接復(fù)制json數(shù)據(jù)
Response【查看服務(wù)器響應(yīng)返回的結(jié)果】
6.6安全測(cè)試
1>攻擊安全:由專業(yè)安全測(cè)試工程師完成;
2>業(yè)務(wù)安全
①敏感數(shù)據(jù)是否加密:比如密碼
②SQL注入:
輸入用戶名為:‘ or 1=1#,提示用戶名格式錯(cuò)誤,表示沒有SQL注入的漏洞
③其他
6.7與手工測(cè)試區(qū)別
1>手工測(cè)試測(cè)寫入到輸入框中的數(shù)據(jù)是否正確。接口測(cè)試測(cè)參數(shù)對(duì)應(yīng)的參數(shù)值是否正確,相當(dāng)于k:v。
2>接口測(cè)試不單單針對(duì)參數(shù)值進(jìn)行測(cè)試,還可以針對(duì)參數(shù)本身進(jìn)行測(cè)試。比如測(cè)username本身,用uname:正確的用戶名去測(cè)試,看看能否通過。
對(duì)于參數(shù)測(cè):
①正向參數(shù):
必選參數(shù):所有的必填項(xiàng)都包含。
組合參數(shù):所有的必填+任意一個(gè)或多個(gè)可選參數(shù)
全部參數(shù):所有的必填+所有的可選參數(shù)
②反向參數(shù):
多參:多出一個(gè)或多個(gè)必選參數(shù)(可以任意指定)
少參:缺少一個(gè)或者多個(gè)必選參數(shù)
無參:沒有必選參數(shù)
錯(cuò)誤參數(shù):參數(shù)名輸入錯(cuò)誤
6.8接口測(cè)試文檔要素
編號(hào)、用例名稱(標(biāo)題)、模塊、優(yōu)先級(jí)、預(yù)置條件、請(qǐng)求方法、URL、請(qǐng)求頭、請(qǐng)求體(請(qǐng)求數(shù)據(jù))、預(yù)期結(jié)果
URL列:寫完整URL或者寫{協(xié)議+域名}/文檔里的path內(nèi)容【path寫明確,協(xié)議和域名可寫成文字,以防后期協(xié)議和域名修改,就不用大篇幅修改】
登錄里的用戶名未注冊(cè)就是不存在
3>數(shù)值部分和手工測(cè)試一樣,參數(shù)是接口特有的。
用戶名和密碼為空不能想當(dāng)然認(rèn)為都是用戶名或密碼錯(cuò)誤,要去實(shí)踐。
登錄的信息都是去數(shù)據(jù)庫中比對(duì),如果特殊字符等在數(shù)據(jù)庫中不允許出現(xiàn),就不用做此類反向測(cè)試。要在數(shù)據(jù)庫中組織出不符合的數(shù)據(jù),測(cè)開發(fā)在接收數(shù)據(jù)的時(shí)候,不能依托數(shù)據(jù)庫,而是依托開發(fā)的代碼有沒有校驗(yàn)出來,不符合規(guī)范的手機(jī)號(hào)是否能登錄成功。
總結(jié):在接口測(cè)試用例中,對(duì)于k:v,考慮k的正反向,v保證正確;考慮v的正反向,k保證正確。
8.1分析測(cè)試點(diǎn)
Eg:針對(duì)“員工管理”業(yè)務(wù)場(chǎng)景:登錄---添加員工---查詢員工(看看是否添加成功)---修改員工---再次查詢(看看修改成功)---刪除員工---查詢員工(看看是否刪除)【相當(dāng)于把多個(gè)模塊接口串起來,用最少的用例盡可能的覆蓋所有接口】
8.2添加用戶【測(cè)校驗(yàn)的情況:正確、錯(cuò)誤、重復(fù)】
請(qǐng)求方法:post
URL:
請(qǐng)求頭:
請(qǐng)求體:
返回?cái)?shù)據(jù):
8.3查詢員工【測(cè)校驗(yàn)的情況:正確、空值、錯(cuò)誤值】
8.4修改員工
8.5刪除員工
9.1開發(fā)者工具
Headers:請(qǐng)求方法、request URL、request headers中的content-type【代表數(shù)據(jù)類型,后面的utf可以不管】、Form data【請(qǐng)求體,k:v對(duì)】
Preview:返回?cái)?shù)據(jù)中看不懂的字符,在preview里能找到
Response:看返回?cái)?shù)據(jù)【漢字的轉(zhuǎn)碼在preview里】
9.2Postman使用
Postman:
Headers:填寫content-type的k:v值
Body:下拉框選項(xiàng)選擇content-type中的v項(xiàng),然后填入請(qǐng)求體中的k:v對(duì),是json就選擇raw【原始】
Send完看響應(yīng)數(shù)據(jù),在body下,選擇pretty,把html改成json,就可以看到返回的結(jié)果了
結(jié)果:
點(diǎn)擊sava或ctrl+s,小紅點(diǎn)就沒有了
總體步驟:
**3.1斷言響應(yīng)狀態(tài)碼
選擇:Status code:code is 200
詳情:pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
解釋:
pm:代表postman的一個(gè)實(shí)例【類下面的一個(gè)對(duì)象】
test():是pm實(shí)例的一個(gè)方法。有兩個(gè)參數(shù)
參數(shù)1:在斷言成功后,給出的文字提示,可以修改。"Status code is 200"
參數(shù)2:匿名函數(shù),function () {pm.response.to.have.status(200);}
function代表函數(shù),后面應(yīng)該放函數(shù)名,但是沒有,所以是匿名函數(shù);
response代表響應(yīng)體,to.have應(yīng)該有
整句話表示:postman的響應(yīng)結(jié)果中應(yīng)該包含狀態(tài)碼200
200是預(yù)期結(jié)果
斷言的結(jié)果在Tests項(xiàng)下Test Results,看到PASS和Status code is 200【對(duì)應(yīng)斷言成功后的描述】
3.2斷言響應(yīng)體是否包含某個(gè)字符串
選擇:Response body:Contains string
詳情:pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("string_you_want_to_search");
});
解釋:預(yù)期結(jié)果用返回體內(nèi)的value值,推薦用message的value
3.3斷言響應(yīng)體是否等于某個(gè)字符串(對(duì)象)【json花括號(hào)括起來是對(duì)象,中括號(hào)括起來是數(shù)組】
選擇:Response body:Is equal to a string
詳情:pm.test("Body is correct", function () {
pm.response.to.have.body("response_body_string");
});
解釋:通常data對(duì)應(yīng)令牌數(shù)據(jù)會(huì)不停地改變,這個(gè)字符串是對(duì)返回的全部字符串進(jìn)行判斷,一旦有數(shù)據(jù)不停變化時(shí),斷言不通過。
**3.4斷言JSON數(shù)據(jù)
選擇:Response body:JSON value check
詳情:pm.test("Your test name", function () {
var jsonData=pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});
解釋:
var jsonData=pm.response.json(); var jsonData用js語法定義一個(gè)變量;jsonData是變量名;pm.response.json()代表響應(yīng)的json結(jié)果,就是響應(yīng)的數(shù)據(jù)
pm.expect(jsonData.value).to.eql(100); 預(yù)期json結(jié)果值等于100相同,value對(duì)應(yīng)響應(yīng)體中的key
3.5斷言相應(yīng)頭【返回的Headers里】
選擇:Response headers:Content-Type header check
詳情:pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");
});
解釋:響應(yīng)頭中包含Content-Type;可以判定k:v是否正確,斷言響應(yīng)頭所對(duì)應(yīng)的value,直接(k,v)
示例:pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type","application/json");
});【在響應(yīng)的headers中,添加響應(yīng)頭中的key對(duì)應(yīng)的value判定,用,分隔】
15.1概念
全局變量:全局變量是全局唯一的,不可重復(fù)定義的變量
環(huán)境變量:一個(gè)變量只能屬于某個(gè)環(huán)境,在某一個(gè)環(huán)境中變量不可重復(fù)定義;在環(huán)境與環(huán)境之間可以定義重復(fù)的變量;一個(gè)環(huán)境可以包含多個(gè)環(huán)境變量;常見環(huán)境分類:開發(fā)環(huán)境、測(cè)試環(huán)境、生產(chǎn)環(huán)境【一個(gè)項(xiàng)目生產(chǎn)部署上線】
15.2設(shè)置變量
全局變量:
環(huán)境變量:
15.3獲取變量【請(qǐng)求參數(shù)是從params、headers、url中拿出來的,只要從界面中獲取的[相當(dāng)于從兩個(gè)請(qǐng)求的postman界面中獲取的];請(qǐng)求參數(shù)只能用在請(qǐng)求參數(shù)中,不可以用在代碼區(qū)域{tests、請(qǐng)求前置腳本},可用在params、headers、bodys中】
全局變量:
環(huán)境變量:
【獲取都用要一個(gè)變量去接收,多級(jí)的要一級(jí)一級(jí)取】
16.1地位:在send按鈕點(diǎn)擊后,請(qǐng)求前置腳本代碼,第一時(shí)間被執(zhí)行。在postman內(nèi)部實(shí)際http請(qǐng)求之前。
16.2時(shí)間戳
概念:對(duì)應(yīng)絕對(duì)時(shí)間----從1970年1月1日00:00:00到現(xiàn)在所經(jīng)歷的秒數(shù)
16.3案例
調(diào)用百度首頁接口,傳時(shí)間戳給服務(wù)器
實(shí)現(xiàn)步驟:
①拿到時(shí)間戳寫入全局變量
//拿到時(shí)間戳數(shù)據(jù)值
var timestamp = new Date().getTime()
//將時(shí)間戳設(shè)置到全局變量中
pm.globals.set("glb_timestamp",timestamp)
②點(diǎn)擊send按鈕,發(fā)送請(qǐng)求。請(qǐng)求發(fā)送前執(zhí)行上述代碼,寫入全局變量
③查看寫入的變量:點(diǎn)擊眼睛圖標(biāo)
④在請(qǐng)求參數(shù)(界面)中,使用全局變量。{{var_name}}【params是查詢參數(shù)】
⑤在postman控制臺(tái),查看發(fā)送的http請(qǐng)求
【send發(fā)送請(qǐng)求之前會(huì)執(zhí)行請(qǐng)求前置腳本,寫進(jìn)全局變量當(dāng)中,再發(fā)送請(qǐng)求】
17.1介紹:應(yīng)用于多個(gè)http請(qǐng)求之間,有數(shù)據(jù)關(guān)聯(lián)、或依賴關(guān)系時(shí)。
17.2實(shí)現(xiàn)步驟
A接口依賴B接口的數(shù)據(jù)
①向B接口發(fā)送http請(qǐng)求,獲取數(shù)據(jù)
②將數(shù)據(jù)保存至全局變量(環(huán)境變量)中
③A接口獲取全局變量(環(huán)境變量)中數(shù)據(jù)值,進(jìn)行使用
17.3案例
請(qǐng)求獲取天氣接口,提取響應(yīng)結(jié)果中的城市,將城市名,給百度搜索接口使用
①發(fā)送天氣接口請(qǐng)求,在天氣接口的Tests中獲取城市名,再把城市名寫入
//獲取全部響應(yīng)結(jié)果
var jsondate=pm.response.json()
//從響應(yīng)結(jié)果中,獲取城市名
var city=jsondate.一級(jí)一級(jí)往下引用k名
//將城市名寫入到全局變量
pm.globals.set(“city”,city)
【點(diǎn)擊send按鈕,發(fā)送請(qǐng)求,查看設(shè)置的全局變量。點(diǎn)擊小眼睛,看全局變量名和全局變量值】
//修改百度搜索請(qǐng)求,使用全局變量,按城市名進(jìn)行搜索
18.1批量執(zhí)行用例集
Data:引入外部文件
18.2生成測(cè)試報(bào)告(newman)【在dos界面】
1.先把用例集執(zhí)行,run
2.導(dǎo)出用例集
3.生成測(cè)試報(bào)告
①{ newman run 測(cè)試腳本文件【導(dǎo)出的json文件】}[可單獨(dú)執(zhí)行] -e 環(huán)境變量文件【沒有環(huán)境變量就省略】 -d 測(cè)試數(shù)據(jù)文件 -r html【必寫】 --reporter-html-export report.html【報(bào)告名稱,report名可以修改】
【比如:登錄接口,測(cè)一個(gè)用戶,請(qǐng)求體的數(shù)據(jù)是寫死的,要是測(cè)1000個(gè)用戶,需要用到參數(shù)化】
【當(dāng)http請(qǐng)求,使用的數(shù)據(jù)有較高相似度時(shí),相同的請(qǐng)求時(shí),考慮使用參數(shù)化(將數(shù)據(jù)組織到數(shù)據(jù)文件中)】
19.1數(shù)據(jù)文件簡(jiǎn)介
CSV:
優(yōu)點(diǎn):數(shù)據(jù)組織形式簡(jiǎn)單,適用于大量數(shù)據(jù)的場(chǎng)合
缺點(diǎn):不支持bool類型數(shù)據(jù)(數(shù)據(jù)被postman讀入后,自動(dòng)添加“”包裹bool值);不支持多參、少參、無參、錯(cuò)誤參數(shù)的接口測(cè)試;不支持復(fù)雜數(shù)據(jù)類型(如嵌套字典、列表)
【數(shù)值直接拿去用,非數(shù)值都加上“”】
JSON:
優(yōu)點(diǎn):支持bool類型;支持多參、少參、無參、錯(cuò)誤參數(shù)的接口測(cè)試;支持復(fù)雜數(shù)據(jù)類型(如嵌套字典、列表)
缺點(diǎn):對(duì)于相同的數(shù)據(jù)量,JSON數(shù)據(jù)文件大小要遠(yuǎn)大于CSV文件
19.2導(dǎo)入外部數(shù)據(jù)文件
CSV:【一定要utf8編碼】
①創(chuàng)建XXX.CSV數(shù)據(jù)文件
②將數(shù)據(jù)寫入到CSV文件中:第一行寫入的是數(shù)據(jù)對(duì)應(yīng)的字段名;從第二行向后依次是對(duì)應(yīng)的數(shù)值,數(shù)據(jù)間用英文,分隔
③在Postman中,選中使用數(shù)據(jù)文件的用例集,導(dǎo)入數(shù)據(jù)文件【run->data:select file->選擇導(dǎo)入文件->通過preview預(yù)覽按鈕,校驗(yàn)數(shù)據(jù)文件是否正確】
JSON:【可在json.cn網(wǎng)站里編寫,編寫好復(fù)制粘貼到記事本打開的json文件中】
①創(chuàng)建XXX.JSON數(shù)據(jù)文件
②在數(shù)據(jù)文件中,按json語法寫入json數(shù)據(jù)。Postman要求,json格式的數(shù)據(jù)文件,數(shù)據(jù)內(nèi)容的最外層,必須是[ ]。內(nèi)部所有的數(shù)據(jù)用{ }存儲(chǔ)
③在Postman中,選中使用數(shù)據(jù)文件的用例集,導(dǎo)入數(shù)據(jù)文件【run->data:select file->選擇導(dǎo)入文件->通過preview預(yù)覽按鈕,校驗(yàn)數(shù)據(jù)文件是否正確】
【建議書寫json數(shù)據(jù)時(shí),無論是不是字符串,都可以用” ”包裹value值】
19.3讀取數(shù)據(jù)文件數(shù)據(jù)
1.方法
①請(qǐng)求參數(shù)(請(qǐng)求行、請(qǐng)求頭、請(qǐng)求體)中,使用數(shù)據(jù)文件中的數(shù)據(jù)
使用{{}}包裹c(diǎn)sv文件字段名或json文件中的key
②代碼(斷言、請(qǐng)求前置腳本)中,使用數(shù)據(jù)文件中的數(shù)據(jù)
需要借助postman提供的關(guān)鍵字data點(diǎn)【.】csv文件字段名或json文件中的key
【send不能讀外部數(shù)據(jù)文件,用到外部數(shù)據(jù)文件了,讀取要進(jìn)入到run里,通過run參數(shù)化用例集的按鈕批量執(zhí)行。如果有異常,借助控制臺(tái)。】
小結(jié):借助數(shù)據(jù)文件,實(shí)現(xiàn)“數(shù)據(jù)驅(qū)動(dòng)”。有多少條數(shù)據(jù),對(duì)應(yīng)就有多少個(gè)http請(qǐng)求。
19.4生成測(cè)試報(bào)告
步驟:
①批量執(zhí)行測(cè)試用例(借助數(shù)據(jù)文件)
②導(dǎo)出測(cè)試用例集(建議與數(shù)據(jù)文件放在一起)
③執(zhí)行生成測(cè)試報(bào)告的命令
Newman run 用例集名稱.json -d 數(shù)據(jù)文件名.csv/.json -r html --reporter-html-export 報(bào)告名稱.html
拿到一個(gè)項(xiàng)目,要對(duì)項(xiàng)目整體有個(gè)認(rèn)識(shí):熟悉項(xiàng)目的功能;了解項(xiàng)目組織架構(gòu)和相應(yīng)技術(shù)。
20.1功能模塊:XXXXXX【模塊功能列出】
20.2技術(shù)棧
前端:頁面顯示........
后端:spring全家桶;mysql【實(shí)現(xiàn)數(shù)據(jù)持久化存儲(chǔ),斷電也不會(huì)丟】+redis【緩存存儲(chǔ)數(shù)據(jù),讀取快】+rabbitmq【消息隊(duì)列,完成數(shù)據(jù)通信】
20.3技術(shù)架構(gòu)圖(比較詳細(xì)展開描述技術(shù)棧)
20.4初始化項(xiàng)目環(huán)境(利用postman)
①先創(chuàng)建環(huán)境,給環(huán)境取名【測(cè)試、開發(fā)、生成】
②initial value:在外部數(shù)據(jù)文件中使用,current value:在postman中使用
【注意】:設(shè)置了環(huán)境,在執(zhí)行用例的時(shí)候要選擇對(duì)應(yīng)環(huán)境
20.5數(shù)據(jù)依賴
1.登錄成功,返回的“令牌”,被增刪改查功能接口依賴
2.添加完的數(shù)據(jù)id,會(huì)被查、改、刪依賴
【借助關(guān)聯(lián)和環(huán)境變量實(shí)現(xiàn)】
20.6提取令牌
1.登錄完成,返回data,不是完整令牌,缺少前綴
2.實(shí)現(xiàn):
①發(fā)送http登錄請(qǐng)求,在響應(yīng)體中得到data值
var json_data = pm.response.json()
var env = json_data.data.token
②將data值拼接“Bearer”和“空格”,組成一個(gè)合法令牌
pm.environment.set("env","Bearer"+" "+env)
③將令牌寫入環(huán)境變量中。(在Tests中通過代碼寫入)
20.7生成測(cè)試報(bào)告
1.在environment中有環(huán)境,要先導(dǎo)出環(huán)境
2.將環(huán)境文件與測(cè)試用例集放置到同一目錄下
3.執(zhí)行命令
663
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。