常規工具
腳手架工具
Yeoman:它旨在為開發者提供一系列健壯的工具、程序庫和
工作流,幫助開發者快速構建漂亮的
Web應用。
構建工具(自動)
Grunt.js:生態強大,發展速度快,有大量可選插件;
Gulp.js:流式項目構建工具;
Browserify.js:Node.js模塊,主要用于改寫現有的CommonJS模塊,使得瀏覽器端也可以使用這些模塊;
Uglify.js:JavaScript解析器、壓縮工具和代碼美化庫。
軟件包管理工具
Homebrew (Mac OS):Apple Mac OS下的軟件安裝工具;
Apt:Debian、Ubuntu等系列
Linux系統的軟件包管理工具,可用來安裝、刪除、升級軟件等;
NPM:Node.js的官方軟件包管理器;
Bower:twitter的一個開源項目,用于web包管理。
前端
MVC框架
Backbone.js:提Web開發的框架,為復雜的Javascript應用程序提供模型(models)、集合(collections)、視圖(views)結構;
Ember.js:可以創建功能豐富的Web應用程序,并提供一個標準的應用程序架構的JavaScript框架;
Angular.js:一組用來開發Web頁面的框架、模板以及數據綁定和豐富UI的組件,無需進行手工DOM操作,還允許為App擴展HTML類庫。
模板
Handlebars.js:JavaScript頁面模板庫,可以為開發者提供必需的語義模板;
Mustache.js:是Mustache模板系統的JavaScript實現,語法邏輯比較簡單,適用于C++、Clojure、Erlang、Go、Java、JavaScript等語言;
Jade:Node模板引擎,主要用于Node.js里的服務端模板;
Haml-js:允許在JavaScript項目中使用Haml語法,與原生的Haml擁有差不多的功能;
Eco:可以用來將CoffeeScript邏輯嵌入到標記中。
Casper.js:CasperJS是一個為PhantomJS和SlimerJS準備的導航腳本及測試工具;
Zombie.js:Zombie.js是一個輕量級的框架,可以在一個模擬的環境下測試客戶端的 JavaScript 代碼,且不需要瀏覽器的幫助。
后端
服務器
Express:Node的web應用框架;
Node:Node.js是構建于Chrome JavaScript運行時基礎上的一個平臺,可快速構建網絡應用。
數據庫
MongoDB:開源的文檔存儲數據庫,也是領先的非關系型數據庫;
Postgresql:開源的對象-關系數據庫服務器;
SQL:結構化查詢語言,可用來存取數據以及查詢、更新和管理關系數據庫系統。
架構
RESTful:目前流行的互聯網軟件架構,結構清晰、易于理解、方便擴展。
測試
Cucumber.js:采用受歡迎的行為驅動開發工具并將其應用到JavaScript堆棧中。
Jasmine:行為驅動的開發測試框架,不依賴瀏覽器、DOM或任何其他JavaScript架構,較適合網站、Node.js項目或應用在任何可以運行JavaScript的地方。
Mocha:運行在Node.js和瀏覽器之上,主要用于異步測試。
Q-Unit:單元測試框架,常用于jQuery、jQuery UI和jQuery移動項目,也可以用于測試常規的JavaScript代碼。
斷言庫(Assertion Libraries)
Chai:一個用于Node的BDD/TDD斷言庫(Assertion Libraries),可與任何JavaScript測試框架進行搭配。
函數式編程工具
Underscore.js:JavaScript庫,提供了大量有用的函數編程工具,無需擴展任何內置對象;
Lo-Dash:提供自定義、性能和一致性的JavaScript庫。
相信用過一段時間Robotium的同學一般都遇到過如下情況:界面跳轉到被測程序外以后,Robotium就毫無對策了,這也是Instrumentation框架最致命的一個缺點;然而領導是不會管你這些很“充分”的理由的…..
Ok,既然我們有這樣的需求,還是想辦法解決吧。調研了幾天最終還是實現了一個曲線救國的方法:
實現原理:編寫一個程序A,用于接收CASE中發送的指定廣播,當程序A接收到指定的廣播后就會響應你注入的動作事件。
熟悉Service 、BoradCastReceiver、input keyevent, 有不清楚的同學可以先
百度下以上知識模塊。
具體實現:
1、首先為了方便我們使用,我們可以設置為程序A為開機啟動一個Service,該Service中注冊一個BoardCastReceiver用于接收一個特定action的廣播,設置一個IntentFilter:IntentFilter mIntentFilter=new IntentFilter(); mIntentFilter.addAction(“
android.zered.action”);然后在BoardCastReceiver的OnReceive方法中使用Runtime.getRuntime.exec(cmdB)執行我們Case中發送過來的指令(input keyevent xx 當然也可以是其他的一些
shell命令)。注意:關于設置程序開機啟動,3.1以后Android系統對廣播接收做了安全處理——未啟動過的程序是不能接收廣播的,當然我們還是有方法解決:即把該程序設置為系統級應用即可,然后把該程序push到system/app下重啟
手機;
2、步驟1的完成已經為我們完成了一個命令執行端(可以理解為CS的
server端),現在我們需要做的就是發送這個廣播,發送廣播的方法為context.sendbroadcast,所以我們在Case中就可以使用solo.getCurrentActivity.sendbroadcast發送廣播;
剩下的就是我們要把這個命令行cmdB封裝到廣播中,Intent intent=new Intent();intent.setAction(“android.zered.action”);intent.putExtra(TAG,cmdB);solo.getCurrentActivity.sendbroadcast(intent);
Ok,這樣以來一個帶有命令行的廣播就算是發送出去了。
3、以上步驟完成以后,步驟1啟動的程序A中的Service接收到步驟2發送的廣播以后,就會執行我們發送的命令行指令cmdB了:Runtime.getRuntime.exec(intent.getStringExtra(TAG))
以上就是Robotium跨應用的一種處理方法,歡迎大家拍磚。
ORACLE數據庫遷移有多種,今天先從物理遷移實驗做起。
物理遷移比較簡單,但是要求兩個庫的版本必須一樣,且必須事先記錄要遷移的庫的SID、歸檔模式、數據文件、日志文件、控制文件、參數文件和密碼文件。
遷移過程大致分為以下四步:
1、用遷移的參數文件啟庫到nomount狀態。
數據庫默認情況下是用$ORACLE_HOME/dbs/spfile<SID>.ora文件來啟動的,如果要用pfile啟動的話
就制定pfile文件就可以啟動,nomount狀態也就是加載參數文件的過程,如果可以成功啟動,那么就說明參數文件沒有問題
2、啟到mount狀態,mount狀態是加載控制文件的過程。
3、如果可以啟到mount狀態了,那么就可以進行開庫操作了。
4、開庫成功之后,就說明遷移成功,可以看看數據丟失沒,然后啟動監聽和配置文件等。
下面進行試驗:
說明:如果兩個庫的目錄建的一模一樣的話,遷移相對簡單,這里演示目錄不一樣的情況。
查看原庫的SID 、數據文件、控制文件、密碼文件、參數文件、重做日志文件。
這里就不貼過程了
下面開始正式的步驟:
1、用pfile起到nomount狀態
SQL> startup nomount pfile='/u01/app/oracle/product/10.2.0/db_1/dbs/initorcl.ora' ORACLE instance started. Total System Global Area 432013312 bytes Fixed Size 2021344 bytes Variable Size 121636896 bytes Database Buffers 306184192 bytes Redo Buffers 2170880 bytes |
成功之后趕緊用pfile生成spfile文件,方便后面對參數的修改
2、起到mount狀態
SQL> alter database mount;
Database altered.
加載控制文件
如果出現錯誤,就說明控制文件所在的路徑和參數文件中的路徑不一致,就要修改初始化參數文件中控制文件的參數,然后重新加載
3、起到open狀態
SQL> alter database open;
Database altered.
這里出現錯誤的話,就是數據文件或其他文件找不到
通過
alter database rename file 'home/oracle/1.dbf' /home/oracle/oradata/1.dbf';
來解決。
4 遷移成功,開啟監聽
ID
----------
1
說明成功了
說到
測試用例的設計,我想每個有過測試經歷的測試工程師都會認為很簡單,不就是:按需求或概要設計,得到軟件功能劃分圖,然后據此按每個功能,采用等價類劃分、臨界值、因果圖等方法來設計用例就行了。
但事實上撇開測試數據的設計不談,僅就測試項來說,我們發現,對同一個項目,有經驗的測試人員,在寫用例或測試時總會有更多的測試考慮點,從而發現更多的問題;而有些測試人員測試用例的撰寫卻只有那么三板斧,表面看好象已經把頁面所有信息的測試都考慮到了,實際上卻還是遺漏了大量測試覆蓋點,導致其測試出來的程序總是比較脆弱。
究其原因,我覺得還是測試用例的撰寫水平不到位,更確切地說是測試用例的覆蓋度太低。說實話我認為
系統測試用例真正做到100%覆蓋是很難的。難道說按設計中的功能劃分,每個功能都寫到了這個用例就覆蓋完整了?錯,這還遠遠不夠。因為我們知道還有大量的內部處理、轉換、業務邏輯、相互影響的關系等都是需求或設計中所不會點明的。而這些一方面需要靠測試人員對項目本身的了解,另一方面要靠測試人員的經驗,來一一找到這些隱藏點并予以測試,才能真正地保證我們的測試覆蓋度。
所以本文拋開具體的測試數據設計方法,主要從測試覆蓋度的角度來介紹
用例設計時,如何才能考慮地更周全,如何才能將隱藏的測試項一一找出,從而使我們的測試更全面更完整。
想法雖然美好,可是畢竟每個測試的項目都是各不相同,針對不同項目我們的經驗也會告訴給我們不同的想法,這些想法通常很感性,很難用嚴密的邏輯理論來把它升華。因此本文的內容仍是很簡陋且不成熟,只是希望能以本文為磚,引起大家的思考,一起來補充完善,以使我們的測試用例設計水平不斷提高。
正文
一、測試用例的切面設計
1、功能點切面
2、特定切面
3、隱含切面
(1)、后臺功能
(2)、完整業務流程的測試
(3)、某種特定情況下的系統運行
(4)、其它相關系統
二、詳細用例的設計
1、功能切面表面用例設計
(1)、具體功能測試
(2)、組合操作的測試
(3)、GUI界面的測試
(4)、數據初始化情況測試
(5)、業務需求實現是否正確
2、功能切面隱含測試項用例設計:
(1)、數據完整性的測試
(2)、后臺的特殊處理
(3)、功能業務之間的關聯與轉換
(4)、從設計實現發掘測試點
(5)、并發操作時的測試
3、特定切面用例設計
4、隱含切面用例設計
(1)、無界面的后臺功能
(2)、與業務流相關的測試
(3)、其它測試類型
三、測試數據的設計
一、測試用例的切面設計
所謂測試切面設計,其實就是測試用例大項的劃分。測試用例劃分的經典方法是瀑布模型,也就是從上到下,逐漸細分,大模塊包括小模塊,小模塊包括更小的模塊。但僅僅如此是不夠的,我們還要從更多的角度切入系統,從不同的角度把系統切分成一塊一塊的,來進行測試,從而確保測試大項的完整性。
1、功能點切面
這是最常見的切面,通常我們認為頁面上的一個按鈕就是一個功能點。然后我們可以根據功能的復雜程度,按每個功能;或一個功能點分多頁;或多個功能點合成一頁來進行用例的撰寫。
2、特定切面
除此以外,還有一種特定切面的劃分方法,也是用例撰寫時經常會用到的。所謂的特定切面,就是忽略掉表面上的功能點,而關注測試對象的某一個面。比如我們的內部管理系統提供了銷售錄入導入、注冊錄入導入等功能,從菜單劃分上對應了七八個功能點。但這些功能處理后臺有個共同的處理項就是授權記錄的生成,這時我們就可以把“授權記錄生成”單獨拿出來做一個測試項,而在其它測試項中涉及這一部分的用例就不必再一一撰寫。此外象一些界面共通的操作用例單獨寫成一頁,也是一種特定切面。所以如果說將用例按功能點劃分是一種縱向劃分法,那么特定切面就是從橫向的角度分析所得到的切面。在普通功能點劃分上再根據實際情況設計特定切面,可以使我們的用例閱讀性、理解性、操作性更強。
3、隱含切面
這類用例是最容易被忽略的。它往往不是明顯的某個功能項,可能是功能項后臺的隱含處理,也可能是多個功能項之間的關聯處理,甚至可能是在某種特定情形下的處理。這都需要測試人員通過對軟件的學習了解,來進行挖掘。
(1)、后臺功能
常見的如一些定時自動啟動的服務;以及某種特定情況下自動執行的操作等。它們在界面上往往是不體現的,但許多在需求設計中還是會提到,也有一些比較細小的功能可能會被忽略,就需要測試人員根據對項目的了解程度來進行挖掘。所以說一個熟悉項目的和一個不熟悉的測試人員,寫出來的用例就完全是兩個層次的。
(2)、完整業務流程的測試
我們都知道測試用例的設計是從點、線、面三個層次去考慮的。完整的一個功能項是線,其中的某個按鈕是點,多個相關功能結合成完整業務流就是面。從實際來看這類用例往往被我們忽略。
事實上目前公司的軟件本來都是業務型應用軟件,將各種功能從業務流中切割出來單獨寫用例,肯定也會有涉及到整體流程的情況。若不加以區分,將細節與全局攪在一起,不僅思路混亂,也容易考慮不周。因此在系統測試階段,建議用例設計要有分有合,針對具體功能的就只圍著這個功能轉:而在業務流程測試項中,再完全從整體的業務流角度出發去考慮用例,這樣不僅不容易產生疏漏,用例閱讀與執行也更清楚。
(3)、某種特定情況下的系統運行
這類用例的設計往往與系統實際業務情況密不可分。比如財務軟件,通常需要在月尾一天、月頭一天、年尾一天、年頭一天,對所有相關功能中的日期處理進行測試;又比如WIN 2000環境開發測試的系統,要測試在98、XP、2003等操作系統下是否能運行自如;再有如存在大量動態圖片視頻等的網頁,在普通網速下的展現速度等等。總之就是要盡可能從實際應用的角度出發考慮,來進行測試補充。
(4)、其它相關系統
即指在當前項目中直接使用的其它成果,包括公司自有的系統模塊、組件、函數;以及購買或免費得到的一些功能組件。對這些內容需要預先與開發組長等討論清楚,是否需要測試。若時間緊張或其它原因決定不測的,應在測試計劃中說明。若需要測試的,則具體可根據實際情況來設計,可以是通過系統某個功能的測試來涉及,此時就不需要單獨劃分測試項;若相對比較獨立的,也可以通過單獨的測試項來對其專門進行測試。
(5)、除功能測試外的其它測試類型
包括可靠性、安全性、恢復性、配置安裝測試等等,這些測試類型都是一個單獨的測試項。
所謂好的開始是成功的一半,保證測試項劃分的完整、合理、正確,會直接影響到本次測試的成效。通常建議該階段工作要花1-2天的時間來考慮,并要在測試過程中隨著對軟件的深入了解,不斷進行調整補充。可千萬不要認為把分析設計中的功能模型圖搬搬過來就可以了。
二、詳細用例的設計
劃分好了測試項,接著就是針對各個測試項,考慮具體的測試用例了。根據測試項的特點,測試用例的設計角度也有所不同。下面我們就來看看通常的功能點測試用例,該從哪些角度出發來進行設計:
1、功能切面表面用例設計
(1)、具體功能測試
根據需求分析設計,按頁面提供的各個功能項,采用黑盒測試的各種方法,設計用例。比如頁面提供了增、刪、改、查功能,那么這四個功能是否正確實現就是我要驗證的。這是最簡單、最基本,同時也是必須的測試用例,通常我們的編碼人員自測也就是做到這個程度。^_^
(2)、組合操作的測試
這是從上一角度擴展出來的,相對而言也是編碼人員不會去測試的,所以需要測試人員多作考慮。
所謂組合操作測試,也就是選擇某幾個操作項,按一定的順序進行操作,驗證系統不會出現意外錯誤。當然要將所有功能項排列組合一遍來測試不僅不必要,也是不可能的。所以具體要將哪些功能項進行結合,要按怎樣的步驟來操作,還是需要測試人員根據實際情況來作設計(所以說在IT業人才就是一切呀,呵呵:)。
一般來說我們會考慮功能項之間的數據是否會存在關聯,若有就需要考慮這種組合了。常見的如查詢功能,需要將各條件逐一累加進行測試;增完的數據能否改,改完能否刪,刪完能否再增,這之間能否查詢到正確結果;按鈕的連續多次點擊會否出現異常;有嚴格前后順序要求的幾個操作,嘗試顛倒順序去操作,系統能否控制等等。
不僅在某功能內部,擴展到有關聯的多個功能項之間,同樣有組合操作測試的存在。如申報完了能才反饋;如申報成功或失敗后再嘗試申報等。當然對于這類用例既可以寫到某個功能切面中,也可以單獨寫到完整業務流程的切面中,這就取決于可能涉及用例的數量了,若關系比較復雜,當然是單獨寫比較好;若也就是三五個用例數,那就直接在某個功能的用例中補充好了。
(3)、GUI界面的測試
這類測試是測試人員的強項,具體測試項目如限長、非法輸入等等,就不必贅述了。要提醒的是在測試時,一定要從實際使用者的操作習慣出發。要知道界面原型所能確定的也只是頁面的擺放顯示,而實際操作時的控制實現仍是編碼人員自行實現的,即使有編碼指南,其所及范圍也是十分有限。而許多編碼人員在用戶操作方便性上的考慮往往差強人意。所以測試人員就必須要把好這一關。
(4)、數據初始化情況測試
不該為空的數據是否有校驗;該有默認值的數據默認值是否正確;引用其它功能生成的數據,是否會實時刷新;頁面關閉或系統重啟后,數據的初始化設置等都是這類用例。
(5)、業務需求實現是否正確
這類問題往往是由于我們的需求說明欠詳細,而編碼人員的需求了解程度又較低造成。作為測試人員自然要對需求進行深刻研究,來對軟件實現進行把關。這里常見的一些關注點有:
數據的長度、類型控制是否合理(比如控制納稅人識別號只能為數字,但實際業務中是會有字母出現的);
業務邏輯控制是否合理(比如某數據項不提供修改,但實際業務中該數據項經常會需要改動);
提供的實現方式是否合理(比如只在某一頁面提供某數據的獲取功能,但根據業務劃分有些人員不能操作此頁面,卻必須要能看到該數據);
所做的數據控制是否合理(比如必須在A功能中新增數據,然后才能在B功能中操作,但實際業務中有可能會出現相反操作);
所做的數據控制是否完整(如授權的方式有普通按月、有買斷、有按數量控制,那么當同一企業嘗試同時存在以上幾種授權方式時,系統是否能有必要的控制);
還有其它一些操作細節上的滿足(如業務上需要批量操作的數據有否提供批量操作功能、導入失敗的結果文件是否能修改后直接再導入等)。
對于不滿足的需求,經開發組長、需求經理等確認不作修改的,就要作為軟件的缺限或限制在測試報告中進行說明民。
2、功能切面隱含測試項用例設計:
(1)、數據完整性的測試
當某數據被其它功能引用;或當前功能要引用其它來源的數據,就會涉及到數據完整性的測試。最常見的如被引用的數據刪除了,或關鍵字被修改了,引用的數據會否出錯;兩個途徑進入的數據會否沖突或重復;此外還有因為相關的幾個功能由不同人員編碼,從而導致彼此的控制不一致,如A功能進入的數據在可允許的極端情況下,到B功能中引用會否異常(最常見如用戶名錄入時允許長度10,但引用到某個單子填寫時允許長度是8,此時就會異常了)。
(2)、后臺的特殊處理
是指某功能除了表面所見以外的程序處理。比如訂單錄入,表面所見的就是訂單的保存,但后臺還會有重復數據的判斷、非法數據的處理、業務邏輯上沖突情況的處理以及其它種種根據需求設計所特有的處理。又比如備份功能,在備份前可能有數據的清空、備份目錄的清空、備份目標是否存在的校驗、備份文件重復時的處理等等。類似這些在分析設計中就未必會寫全了,還是要測試人員多花心思去思考挖掘。
(3)、功能業務之間的關聯與轉換
相關聯的幾個功能之間數據的傳遞,會否產生影響。比如新增錄入的某種特殊字符,要查詢時會引起查詢SQL語句異常;又如某下載文件名中存在中文等字符,下載時由于編碼問題導致亂碼的出現;再有報表填寫時到小數點后四位,生成報文時會不會被忽略成兩位了等等。象這種問題,通常只能是在每個功能設計用例時,盡量保證用例中的數據能涉及到允許范圍的各種情況,即充分運用等價類劃分+邊界值的方法設計出各種“稀奇古怪”的數據,并需驗證這些數據從頭流到尾,都還是能保持其正確性,而不僅僅是在當前功能中正確。
(4)、從設計實現發掘測試點
這個就是我們測試中最難捉的BUG了,它往往是由編碼人員自己在編碼時創造出來的,連設計人員都不會知道。
比如內部管理系統中,正常的產品,其類別通常是2位數字;如果是模塊,其類別就以產品代碼來取代。這時如何來判斷該產品是模塊呢?最保險的當然是校驗其產品類別字段的值能否在產品表中找到;也有比較簡單的方法就是直接判斷類別代碼大于2位還是小于等于2位。此時若能確切知道采用的是哪種實現方法,就可以直接找到其漏洞所在。比如采用后一種方法,當產品類別長度變化時,明顯系統會出錯。那么即使確認該實現方式不改,測試人員也應將其作為限制寫入測試報告,。讓大家知道這個產品類別長度是不能隨意變化的。
而讓人郁悶的是,類似這樣的實現,有太多的編碼人員都是隨性處理的,它們細而隱蔽,在系統數據正常情況下根本不會被發現;而在漫漫的軟件使用道路中,由于需求變更等原因對原有一些設計做維護變化,這種問題就會突然暴發出來讓人措不及防。所以要杜絕這類漏洞,除了測試人員要做土撥鼠,不停地對軟件各功能的實現細節進行挖掘外,也要多給編碼人員灌輸完美實現的理念,多用復雜但抗壓性高的代碼,來替代簡單但依賴性強的代碼。
(5)、并發操作時的測試
即兩個或多個用戶同時操作同一功能時,會否引起數據的混亂。通常在C/S結構下,如果有同時操作的可能,是需要作此測試的;而在B/S結構下由于其特殊性,此問題通常難以解決。除非就是某用戶一旦使用過某功能后,在一定時間內鎖定不允許再用,但這也會帶來實際應用中的不便,所以除非是特別核心的數據,一般我們也不會去做此控制,當然對于可能出現的并發沖突也就作為系統的限制進行遺留了。
3、特定切面用例設計
所謂特定切面,其實就是從另一個角度切割出來的用例面,所以具體的用例撰寫方式其實與功能切面是一致的。
4、隱含切面用例設計
隱含切面分以下幾種情況:
(1)、無界面的后臺功能
對這類測試項,需要通過參數設置、代碼調用等方式來實現測試,但具體的測試設計其實與普通功能測試并無二致。這里要注意,因為測試時往往前臺、后臺是分開來分別進行的,而實際運行時兩者很可能是交集的,所以測試時要多注意后臺功能的執行與前臺的一些功能執行會否產生沖突?比如后臺有個文件搬運的服務,那有沒有可能在前臺文件生成過程中,后臺執行文件搬運了?若有可能就要注意會否出現問題了。
(2)、與業務流相關的測試
這類測試用例的設計,就要從完整業務角度來設計數據了。從理論上來講,應該要將各個功能可能出現的各種數據排列組合到一起,按業務流程逐一進行測試。但實際上我們不可能去做全覆蓋。所以設計這類用例時,最好有一張草稿,將所有相關功能按業務流程逐一列示,然后再將每個功能可能出現的特定數據一一標上,最后將圖中最可能出現的、最可能出錯的、最核心的數據取出來,分別組合成一個個完整的業務數據用例,來進行測試。這樣就可以按清晰的思路,找出最實用、最有效的測試數據。
(3)、其它測試類型
這一類的測試通常都有其特定的方法。如要測可靠性就準備大量數據不停地執行;要測安全性就考慮數據的加密、數據的傳輸、數據的破壞;恢復性一般從網絡、電源方面著手;配置安裝則根據系統可支持的配置,搭建相應環境進行功能驗證,此處的驗證也要掌握技巧,即要多測試那些涉及到:數據庫讀寫、磁盤文件讀寫、文件上傳下載、文件加解密、數據統計、圖表展現、打印等方面的功能。
三、測試數據的設計
每一個測試思路最終都要轉化成具體的數據才能來執行。關于測試數據設計的方法也不外乎那幾種,就不再贅述了。此處單就一些經常易犯的錯誤,提出一些注意點,作為用例數據設計時的參考:
1、盡量避免可能出現歧義測試結果的數據:即你設計的數據必須能唯一正確地反映出你所希望測試的結果。比如一組測試數據,有可能得到結果A或結果B,此時單用此數據來測試預期結果為A的用例,那明顯就產生了歧義。
2、對于不便具體列示的數據,則必須詳細描述其各項特性:有時我們在設計用例時為節約時間,不一定要到具體的一個數值,這也是允許的,但前提是你必須要詳細描述清楚你要測試的數據特性。比如數據庫字段限長20,要測試超長數據時,可以描述為:嘗試輸入長度為21位的半角英文字符;嘗試輸入長度為19位的半角英文字符,然后切換到中文全角再輸入一位全角字符等。千萬不能寫成:嘗試輸入超長字符,因為這只能是測試方案,作為方案是可以這樣寫,但到用例階段,必須要是具體的、明確的、可操作的。
3、測試數據的設計必須有明確目的性:即測試數據是從測試方案衍生而來的。如上例測試方案是測超長字符輸入控制,所以測試數據就要根據具體字段長度來錄入超長數據,如果一味錄入長15位、長16位的數據那就沒意義了。好的測試數據是可以同時針對多個測試方案的,此時可以在用例邊注明一下該數據的測試目的,因為隨著時間推移,對著具體的數據你也許會忘了它到底是測什么的,而這對你最后總結測試,查驗測試覆蓋率是非常不利的,所以隨時記下你的思路想法吧,好記性不如爛筆頭。
4、測試數據可省略描述:測試數據描述以能讓人看懂為準則。所以寫用例時當碰到連續幾個用例,僅某幾個關鍵數據值改動,其余均是一樣的情況下,不必每個用例都要重復描述所有數據,可以在第一個用例描述完整之后,其余用例中僅列示不同的數據,并標明其余數據同上第X個用例,即可。這樣測試時仍能復原測試數據,且該用例的測試目的一眼就明,增加了用例的清晰性。
至些,我根據測試用例設計的順序,從測試數據的切面設計(即測試項劃分),到詳細測試用例設計,再到測試數據設計三個層面,逐一介紹了如何來提高測試用例的覆蓋度。因為具體項目中的具體情況太多,以上敘述的內容也只能是管窺蠡測。至于其中的疏漏錯誤之處應也難免,只希望各位閱后能打開思路,從自己多年的測試經驗中多總結、提煉出一些想法思路,進一步補充完善這個文檔,使大家的測試用例設計能力都能進一步提升。
縱觀上圖可知,Oracle數據庫服務器大致分為兩個主要部分 既1.Oracle instance (數據庫實例 上半部分)2.database (數據庫 下半部分)。
用戶不能直接連接到數據庫,而是用戶先發出一個用戶進程, 用戶進程和Oracle服務器發出的服務器進程交互,然后服務器進程再和實例交互,最后實例和底層數據庫交互,從而實現用戶和數據庫的交互。具體過程看下圖:
下面詳述體系結構中各個組成部分的具體功能和特點
1.首先先有的整體的認識:
oracle 服務器=實例+數據庫
實例=SGA(實例內存)+后臺進程
內存=SGA+PGA
SGA=database buffer cache (數據庫高速緩存區緩存)+share pool +redo log buffer
2.實例內存SGA結構:前三個是必選的,其余是可選的。
1)database buffer cache(數據庫高速緩存區緩存) :是用來存放執行
SQL的
工作區域 (1)存儲從數據文件中獲得的數據塊的鏡像(2)當獲取和更新數據的時候能夠大幅度提高性能,因為數據庫塊的鏡像會保存一段時間,等下次再執行有關這個塊的操作時,可直接在緩存區操作(3)能夠動態調整大小,也可以對其進行自動管理。
2)Redo log buffer (在線日志緩沖區): ()記錄所有數據庫的塊的改變,主要用于恢復,大小由log_buffer 決定, 在對數據庫塊進行操作之前,會把所做的所有操作記錄這里。
3)share pool (共享池):包括library cache (庫高速緩沖區)和database dictionary cache(數據字典緩存) ,前者主要存儲最近使用的SQL和pl/sql 語句的信息(存一次 多次使用,防止硬解析,) 后者主要存儲最近使用的定義,如表、索引、列、用戶權限、和其他數據庫對象。
4)Large pool : 是系統全局區的一個可選的部分,是共享服務器的會話內存,以減輕在共享池中的負擔,可動態的改變大小,也可以自動管理。
5)
Java pool: java 命令的分析,可動態的改變大小,也可以自動管理
6)Stream pool : 流相關的數據在流池中,提高緩存效果。
3.接下來介紹實例后臺進程:
1) pmon (進程檢測進程) :當會話異常終止時 清除失敗的進程 包括 回滾事務、釋放鎖、動態注冊監聽器,
2) Smon (系統檢測進程):實例恢復(前滾所有重做日志中的改變、回滾沒有提交的事務),釋放臨時表空間。
3) DBWn(數據寫進程): 將數據庫高速緩存區緩存中的臟塊,刷新到磁盤數據文件中, 寫的條件:1,發生檢查點2,臟緩存到達極限值(1/4)、沒有可用的緩存區時。
4) LGWR(日志寫進程)將redo log buffer 中的redo 刷新到磁盤日志文件中, 寫的條件:1,commit 的時候,2.達到1/3滿時,3.大小達到1M時,4.每擱三秒 5.在DBWR進程寫數據之前。
5) CKPT (檢查點進程) : 給dbwn 信號,使它開始寫臟塊。更新數據文件頭和控制文件,(就是把scn號更新為最新的)3秒一次。 常說的一致性 要保證三個scn 號一致,包括數據文件頭的scn號,control files 記錄數據文件頭的scn號,control files 記錄的總的scn號。檢查點進程 觸發的越快,DBWR 寫的就越快,這樣內存中的緩存區臟塊就越少,進而恢復實例所用的時間就會越少,但是頻繁的I/O導致性能下降,所以性能和速度是矛盾的;
6) ARCn (歸檔進程):將聯機重做日志文件歸檔到(也可以理解為復制)歸檔日志文件 ,如果開啟了歸檔模式 重做日志文件 一般分為兩個組,這兩組是循環復寫的,一個組用來記錄對數據庫的修改,另一組進行歸檔。但是如果記錄修改的那組已經寫滿,這樣本來該再去寫另一組,但是另一組還沒有完成歸檔,這就會出問題,數據庫夯住了。。
Linux下看內存和CPU使用率一般都用top命令,但是實際在用的時候,用top查看出來的內存占用率都非常高,如:
Mem: 4086496k total, 4034428k used, 52068k free, 112620k buffers
Swap: 4192956k total, 799952k used, 3393004k free, 1831700k cached
top –M看更直觀,以M為單位
接近98.7%,而實際上的應用程序占用的內存往往并沒這么多,
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
25801 sybase 15 0 2648m 806m 805m S 1.0 20.2 27:56.96 dataserver
12084 oracle 16 0 1294m 741m 719m S 0.0 18.6 0:13.50 oracle
27576 xugy 25 0 986m 210m 1040 S 1.0 5.3 28:51.24 cti
25587 yaoyang 17 0 1206m 162m 3792 S 0.0 4.1 9:21.14
java 看%MEM這列的數字,按內存排序后,把前幾名加起來,撐死了才不過55%,那剩下的內存都干嘛用了?
一般的解釋是Linux系統下有一種思想,內存不用白不用,占用了就不釋放,聽上去有點道理,但如果我一定要知道應用程序還能有多少內存可用呢?
仔細看top關于內存的顯示輸出,有兩個數據buffers和cached,在Linux系統下的buffer指的是磁盤寫緩存,而cache則指的是磁盤讀緩存。
(A buffer is something that has yet to be "written" to disk.
A cache is something that has been "read" from the disk and stored for later use.)
而這兩塊是為了提高系統效率而分配的內存,在內存富余的時候,
操作系統將空閑內存利用起來,而有內存需求時,系統會釋放這部分的內存供應用程序使用。
這樣,真正應用程序可用的內存就是free+buffer+cache,上面的例子就是:
52068k + 112620k + 1831700k = 1996388k
而已用內存則是used-buffer-cache,上面的例子為:
4034428k - 112620k - 1831700k = 2090108k
Linux下查看內存還有一個更方便的命令,free:
$ free
total used free shared buffers cached
Mem: 4086496 4034044 52452 0 112756 1831564
-/+ buffers/cache: 2089724 1996772
Swap: 4192956 799952 3393004
Mem:這列就是用top命令看到的內存使用情況,而-/+buffers/cache這列就是我們剛剛做的計算結果,used-buffer-cache/free+buffer+cache
也可以加-m或者-g參數查看按MB或者GB換算的結果。
$ free -m
total used free shared buffers cached
Mem: 3990 3906 83 0 90 1786
-/+ buffers/cache: 2029 1961
Swap: 4094 781 3312
這樣,真正應用程序的內存使用量就可以得出來了,上面的例子中內存占用率為51.1%。
例如:
# free -m
total used free shared buffers cached
Mem: 4229 2834 1395 0 62 2548
-/+ buffers/cache: 223 4006 //物理內存使用223M,剩余4006M
Swap: 8001 0 8001
//定義Gun類 public abstract class Gun { protected String name; // 帶參數的構造方法,特殊的方法,名字必須與類名相同 public Gun() { public Gun(String name) { this.name = name; // 構造抽象方法,并在子類中繼承和定義。 abstract void sound(); public String getName() { return name; public void setName(String name) { this.name = name; //Carbine繼承自Gun public class Carbine extends Gun { //帶參數的構造方法,特殊的方法,名字必須與類名相同 public Carbine(String name) { this.name = name; //Gun類下不同的子類擁有同名的sound()方法,但是內容不同,在調用sound()方法時會根據具體的Gun而自動調用相應的方法。 void sound() http://www.huiyi8.com/jiaoben/ // TODO Auto-generated method stub System.out.println("DaDaDa!"); javascript特效 //Rifle繼承自Gun public class Rifle extends Gun { //帶參數的構造方法,是特殊的方法,名字必須與類名相同 public Rifle(String name) { this.name = name; //Gun類下不同的子類擁有同名的sound()方法,但是內容不同,在調用sound()方法時會根據具體的Gun而自動調用相應的方法。 //這用到了Java的多態性。 void sound() { // TODO Auto-generated method stub System.out.println("Peng! Peng! Peng!"); //定義Person類 public class Person { private String name; public String getName() { return name; public void setName(String name) { this.name = name; // 體現多態性。 public void shoot(Person p, Gun g) { System.out.println(this.name + " shoot\t" + p.getName() + " using a " + g.getName()); g.sound(); public class Test { public static void main(String[] args) { // TODO Auto-generated method stub Person p1 = new Person(); Person p2 = new Person(); p1.setName("XiaoWang"); p2.setName("XiaoLi"); Rifle r = new Rifle("rifle"); Carbine c = new Carbine("carbine"); // 將方法的調用和實現分離,已達到封裝的效果。 p1.shoot(p2, r); p1.shoot(p2, c); |
在
軟件開發初期處理安全需求是防止安全問題最經濟的方式。大多數安全需求都屬于非功能性需求(Non-Functional Requirements ,NFRs)。很多從業者發現,在
敏捷項目中處理安全和其他NFR非常具有挑戰性。原因有二:
匹配NFR和特性驅動的用戶故事需要付出很大努力;
安全控制常因缺少可見度而被忽視。敏捷過程容易讓團隊不自覺地側重于那些可以直觀改善客戶體驗 的新功能開發或缺陷修復。
在本文中,我們會探討以上兩個問題。
在用戶故事中處理NFR
敏捷專家們提出過一些方法,用以定義用戶故事驅動的開發過程中的NFR。Mike Cohn在他的
文章中討論了評論者們提出的一些有趣的建議。Scott Ambler就該主題寫了一系列文章,旨在證明并非所有的NFR都可以獨立存在于用戶故事中。而Dean Leffingwell可以說在這方面做了最深入的研究,他在自己的著作《敏捷軟件需求》中花了整整一章探討該主題。這些專家中大部分人都認為,NFR大致可以分成兩類:
非功能性用戶故事:以用戶故事的形式展現的可
測試功能塊。這些用戶故事中的參與者(Actor)可能是內部IT人員。例如:“作為安全分析師,我希望系統能抑制不成功的身份認證嘗試,這樣應用程序在面對暴力破解時不至于太過脆弱”。
約束:這是個跨領域的問題,常常涉及多個用戶故事。我們可以將它看作是對所有相關開發
工作收取“課稅”。例如:開發Web應用時,要求所有開發者對Http表單中的字段進行數據校驗即為一種約束。
處理第一類NFR很簡單:創建一系列的NFR用戶故事,將它們加入某種工作序列,例如Product Backlog。
NFR約束的挑戰:
然而處理第二類NFR則困難很多。敏捷專家們對此提出過一些解決辦法,包括:
在特定的用戶故事中添加恰當的約束作為驗收標準
在某個中央知識庫——例如,貼在墻上或者發表在wiki上的一份文件——中維護包含所有約束的列表。
但無論哪個方法都無法解決的問題是,如何針對特定的用戶故事選擇適用的約束。而且,使用SD Elements進行安全需求匹配的經驗表明,要將這些技術限定在一定范圍之內很困難。下面這個列表是標準Web應用需要面對的安全約束中的一部分,我們以此為例:
對來自客戶端的只讀數據進行完整性驗證,以防止參數篡改
避開存在于HTML、HTML屬性、CSS以及JavaScript中的不可信數據,從而防止跨站點腳本攻擊)(XSS)
避免客戶端JavaScript中基于DOM的XSS
使用安全的算法以避免整型溢出
不接受外部重定向以防止自由重定向攻擊
授權給受保護的頁面,以防止權限提升攻擊)
使用防止跨站請求偽造(CSRF)的令牌
驗證輸入
盡量使用正則表達式,因為它對于拒絕服務攻擊有較強的抵抗力。
為高價值的事務實現事務身份認證
不要硬編碼密碼
該列表列舉的可能只是程序員在實現用戶故事時需要考慮的安全約束中的一小部分。若將需要遵循的法規標準——諸如支付卡行業數據安全標準(PCI DSS)之類——考慮在內,約束還要增加不少。如果你開始添加其他NFR約束,例如可訪問性,約束列表會快速增長,轉眼間就會超過程序員的承受范圍。一旦列表變得臃腫,我們的經驗是,程序員往往會將它全部忽略,僅根據自己的記憶來應用NFR約束。而在很多不斷專業化的領域——例如應用安全——NFR的數量不斷增長,這給程序員的記憶力造成了沉重的認知負擔。因此,如何使用靜態分析技術偵測代碼中違背NFR約束之處就成了關注重點。研究表明,靜態分析可以偵測出的可預防缺陷最多不超過總數的40%,也就是說仍有大量的約束漏網,包括特定領域的安全控制,更別說在缺乏定制的情況下辨別靜態分析產生的“假陽性”結果也不是那么簡單。
應對NFR約束的挑戰
為了解決NFR約束過多的問題,我們需要做到以下四點:
按優先級排序:與用戶故事和缺陷一樣,NFR約束也應擁有不同的優先級,例如:相較于避開HTML中的不可信數據以防止持續的跨站腳本攻擊,對HTTP響應頭中的不可信數據進行編碼或校驗以防止HTTP響應拆分攻擊就不那么重要。因此我們假定程序員通常沒有足夠的時間處理所有約束,然后我們提供一種機制為如何定義約束的相對優先級提供建議。之所以說“建議”,是因為優先級有可能隨著具體情況的變化而變化,程序員需要自己作出判斷——對于他們的特定代碼,哪種相對優先級是適用的。你可以選用簡單的優先級設置,如“高、中、低”,也可以使用數字范圍,如1-10。
過濾:使用簡單的標準常常就可以為特定的用戶故事移除大量的NFR約束。舉例來說,假如你正在實現的用戶故事與表現層無關,那么就可以安全地忽略大量表現層相關的約束。使用標簽系統或者簡單的Excel過濾器,就可以為特定的用戶故事削減約束數量。以下是一些Web應用相關的安全性約束過濾器的范例:
用戶故事是否涉及用戶輸入;
用戶故事是否涉及保密數據,如密碼、信用卡信息以及非公開的財務數據;
用戶故事是否返回一個全新或修正過的用戶輸出,例如一個網頁;
用戶故事是否會暴露或使用來自RESTful 或SOAP API調用的數據;
用戶故事是否會訪問受保護的數據(例如,不是所有用戶都能查看或修改的數據)。
情境(Context):程序員在寫代碼或定義任務單(tickets)/ 用戶故事的時候更容易記起并應用約束。理想情況下,如果把約束列表內嵌入IDE或任務單系統,那么程序員就可以在編碼時獲取相關的約束。既然現在很多IDE都支持內嵌的Web瀏覽器,那么使用輕量級的網站或者SharePoint站點就可以實現這個目標。
框架:框架可以大幅減少約束產生的“稅收”。例如,像 Django這樣的框架自帶了CSRF防護,這意味著程序員可以安全地忽略該約束,除非他們主動繞過這個內建的功能。根據我們的經驗,多數大型的應用軟件都會采用某種形式的定制框架,這些框架可以無縫處理最高優先級的約束。雖然這樣的框架定制可能需要較高的先期投入,但如果你將約束看成一種基于用戶故事的“稅收”,那么減少約束數量就相當于永久性的降低了“稅率”。
驗證
雖然主動處理NFR很重要,但仍有必要進行驗證。如果你有手動代碼審查(Code Review)的經驗,就可以檢查用戶故事中作為驗收標準出現的NFR。然而,如果僅使用手動代碼審查,很多約束的驗證將是非常棘手或者繁重的。靜態分析工具則可以自動檢查編碼標準的遵守情況,其中一些產品特別關注安全方面。將你的靜態分析工具與持續集成過程整合在一起,可以幫助你始終遵守編碼標準。但也務必注意,不要一味依賴于代碼審查。防范特定領域缺陷——如HTTP參數篡改——的NFR要求對背后的業務領域有深刻的理解。將手動驗證與針對特定攻擊的自動測試結合起來,可以幫助我們建立一套對于特定領域缺陷擁有更強抵抗力的系統。
可見度
難以將安全需求集成進敏捷項目的另一方面原因是安全需求通常缺乏可見度。面向客戶的會議,如Scrum的Sprint評審會議),容易使開發人員產生一種固有的傾向,即實現用戶故事或修復缺陷時傾向于那些能直接改善用戶體驗的故事或缺陷。一部分非功能屬性,例如易用性和性能,對于系統的使用體驗有具體的影響,因此也比較容易向客戶展示。而另外一些——如安全性——卻很難在Sprint評審會議上給客戶留下很好的印象。實際上,某些安全特性,如賬號封鎖(Account Lockout),可能給客戶體驗帶來相當負面的影響。大多數安全特性對系統的影響,普通用戶很難察覺。因此,安全性NFR是不可見的,它們必須和可見度更好的特性競爭,以奪得寶貴的開發周期。在軟件開發初期,準確的說在程序員應該構建安全特性的時候,處理這些“隱形”需求的機會成本會特別高。
讓安全特性可見
對于敏捷團隊來說,沒有“銀彈”能讓安全需求在開發伊始就擁有最高優先級。但有一些方法可以讓安全NFR對客戶和/或PO可見。
圖形化安全用戶故事:如果你在應用程序安全方面足夠專業,就可以針對已知的安全弱點創建一套全面的安全控制。然后將它們與NFR用戶故事匹配起來,并繪制簡單的圖形,用以說明系統中已實現的和未實現的安全用戶故事數量。這個圖可以放在大型可視圖表中。
圖1:安全用戶故事圖
當然,這個圖沒必要局限于安全用戶故事,你可以將其他重要的NFR囊括進來。實際上,你可以使用故事點(Story Point)取代用戶故事數量,從而更準確的反映工作量。另外,你有可能希望圖中只記錄那些針對高風險安全問題的、擁有最高優先級的用戶故事或控制。每完成一個故事,“已完成”數量都會增加,客戶也會籍由此圖直觀地了解項目的進度。
展示可利用性(exploitability):沒有什么比可利用性展示更能讓人們理解一個安全漏洞的各個方面了。這是安全性滲透測試和漏洞評估的主要區別。你可以展示在上一版本的應用中如何成功地利用了漏洞,而在新的版本中卻沒辦法這么做了。然后你可以從對業務和/或客戶影響的角度解釋漏洞的方方面面。這非常有利于解釋為什么在安全控制上花的時間是合理的。
結論
主動處理NFR,特別是安全特性,在敏捷環境中非常重要。不少專家對于如何處理此類需求——特別是當它們與創建用戶故事相關時——給出了建議。全面地處理約束是個相當大的挑戰。記住本文討論的提議,你可以極大地增加維護一系列約束的價值。即使不能完全做到以上所提的四點內容以改善對約束的管理,但從長遠來看,任何一點改進都能帶來很高的回報。進行驗證能保證團隊始終遵守NFR。最后,提高安全特性的可見度,可以讓你證明用在NFR上的時間是合理的,就算它們對系統的改善不能反映到用戶體驗上。
最近在跟進某個項目的
質量管理,過程中有一些感受,總結下以便回顧。
第一,質量管理的重要性必須得到高層的支持
和之前ERP系統實施一樣,沒有得到高層全力支持的項目很容易中途流產。在
項目管理體系中,就體現為干系人的管理。
前期從每個項目干系人的立場和利益考慮,去協調干系人之間的關系是很慘重要的。這次的項目上來看,沒有高層的介入,使得項目組負責人和質量管理組負責人之間并沒有達成共識,在溝通交流上的成本代價很高。
第二,質量管理組和項目組之間必須達成相同的標準認知
質量管理采用的標準必須和項目組之間達成一致。在項目開始之前應該有專門的流程來保證。在項目中期去討論和修改標準會給項目帶來巨大的風險,同樣,沒有在前期達成共識,項目組合質量管理組之間也會有很大的溝通成本產生。
第三,質量標準一定要細化到可操作
在制定標準細節時,避免產生模棱兩可的寫法。沒有可操作性的標準還不如不要這樣的標準。
第四,和客戶之間確定和質量標準
沒有100%的質量標準,我們也不可能不計成本的去實現100%的質量。所以,合理權衡成本,質量和時間,制定滿足客戶須有的項目質量標準是很講究的。
用
TestNG測試后,自動會生成html的測試報告,不過相信大家都有感覺,自動生成的測試報告太難看了,所以我們又用了ReportNG來美化它。在 這里給大家再介紹一下比reportNG還要稍稍美觀一點的reporting tool: testNG-xslt.
其實testNG-xslt就是把testNG自動生成的測試報告testng-results.xml進行了一個轉換,把它的html輸出報告變得更漂亮 而已。因此用法也很簡單:
1. 在官方網站上下載testNG-xslt ,http://testng-xslt.googlecode.com/files/testng-xslt-1.1.zip
2. 解壓后把saxon-8.7.jar放到project的lib目錄下(在bulid路徑里也把這個lib加上)
3. 然后再把/src/main/resources/testng-results.xsl放到你的 test-output 目錄下
4. 在測試項目的根目錄下創建一個簡單的build.xml, 如下:
<?xml version="1.0" encoding="UTF-8"?> <project name= "testTng" basedir= "." default="transform"> <property name= "lib.dir" value= "lib" /> <path id= " test.classpath" > <!-- adding the saxon jar to your classpath --> <fileset dir= "${lib.dir}" includes= "*.jar" /> </path> <target name= "transform" > <xslt in= "G:/eclipse3.7/workspace/testTng/test-output/testng-results.xml" style= "G:/eclipse3.7/workspace/testTng/test-output/testng-results.xsl" out= "G:\eclipse3.7\workspace\testTng\test-output\index1.html " > <!-- you need to specify the directory here again --> <param name= "testNgXslt.outputDir" expression= "G:\eclipse3.7\workspace\testTng\test-output" /> <classpath refid= "test.classpath" /> </xslt> </target> </project> |
5.最后用 ant 運行這個 xml 就會在test-output 目錄下生成 index1.html,打開它就是測試報告了。
轉換前的測試報告:
轉換后的測試報告(是不是美觀很多呢):