流程說明
1、測試人員填寫bug并提交給開發組長,Bug的狀態為New;
2、開發組長次日工作前對bug確認是否有效。有效的bug,狀態變化為open,并分配給開發人員;bug無效或者延期修改的,將bug狀態變化為Rejected,同時也在comment中注明原因。
3、開發人員上班的第一件事情是查看自己有幾個bug需要修改。
4、開發人員修改bug,修改完成并進行單元測試后,將bug的狀態變為fixed,在comment中說明修改方法;
5、測試人員每天查看自己提交的bug的狀態變化,應該成為每個測試人員的例行行為;
6、當bug的狀態變為fixed時,測試人員打開該bug,開始對該bug進行回歸測試;
7、如果該bug回歸測試通過,則狀態變為closed。否則bug的狀態變為reopen(必須說明reopen、closed狀態變化原因或者操作過程);
8、如果回歸測試通過,可是修改的同時又引入新的bug,則重新提交bug,狀態為new。如果需要的時候注明相關聯的bug號;
9、只有當所有的bug狀態為closed,才可發布版本。
注:每當bug狀態改變后,必須給出相應的注釋和說明,以便查看bug生命周期的變化情況。

與其他語言的模型相比,finally 關鍵字是對 Java 異常處理模型的最佳補充。finally 結構使代碼總會執行,而不管有無異常發生。使用 finally 可以維護對象的內部狀態,并可以清理非內存資源。 如果沒有 finally,您的代碼就會很費解。例如,下面的代碼說明,在不使用 finally 的情況下您必須如何編寫代碼來釋放非內存資源:
- import java.net.*;
- import java.io.*;
- class WithoutFinally
- {
- public void foo() throws IOException
- {
- //在任一個空閑的端口上創建一個套接字
- ServerSocket ss = new ServerSocket(0);
- try
- {
- Socket socket = ss.accept();
- //此處的其他代碼...
- }
- catch (IOException e)
- {
- ss.close(); //1
- throw e;
- }
- //...
- ss.close(); //2
- }
- }
|
這段代碼創建了一個套接字,并調用 accept 方法。在退出該方法之前,您必須關閉此套接字,以避免資源漏洞。為了完成這一任務,我們在 //2 處調用 close,它是該方法的最后一條語句。但是,如果 try 塊中發生一個異常會怎么樣呢?在這種情況下,//2 處的 close 調用永遠不會發生。因此,您必須捕獲這個異常,并在重新發出這個異常之前在 //1 處插入對 close 的另一個調用。這樣就可以確保在退出該方法之前關閉套接字。
這樣編寫代碼既麻煩又易于出錯,但在沒有 finally 的情況下這是必不可少的。不幸的是,在沒有 finally 機制的語言中,程序員就可能忘記以這種方式組織他們的代碼,從而導致資源漏洞。Java 中的 finally 子句解決了這個問題。有了 finally,前面的代碼就可以重寫為以下的形式:
- import java.net.*;
- import java.io.*;
- class WithFinally
- {
- public void foo2() throws IOException
- {
- //在任一個空閑的端口上創建一個套接字
- ServerSocket ss = new ServerSocket(0);
- try
- {
- Socket socket = ss.accept();
- //此處的其他代碼...
- }
- finally
- {
- ss.close();
- }
- }
- }
|
finally 塊確保 close 方法總被執行,而不管 try 塊內是否發出異常。因此,可以確保在退出該方法之前總會調用 close 方法。這樣您就可以確信套接字被關閉并且您沒有泄漏資源。在此方法中不需要再有一個 catch 塊。在第一個示例中提供 catch 塊只是為了關閉套接字,現在這是通過 finally 關閉的。如果您確實提供了一個 catch 塊,則 finally 塊中的代碼在 catch 塊完成以后執行。
finally 塊必須與 try 或 try/catch 塊配合使用。此外,不可能退出 try 塊而不執行其 finally 塊。如果 finally 塊存在,則它總會執行。(無論從那點看,這個陳述都是正確的。有一種方法可以退出 try 塊而不執行 finally 塊。如果代碼在 try 內部執行一條 System.exit(0); 語句,則應用程序終止而不會執行 finally 執行。另一方面,如果您在 try 塊執行期間撥掉電源,finally 也不會執行。)
七、詳細設計
詳細設計還得從數據庫開始。作為專業菜鳥,我們要把所有的SQL語句都放在存儲過程當中,不要放在程序里。這樣做的好處是:容易修改、維護,執行速度快、減少數據傳輸量。存儲過程可以簡單的理解為在SQL服務器上創建小函數,它們有名字、參數,通過調用這些小函數,我們可以完成對表的增、刪、查、改操作,相當于把SQL語句放在了服務器上,并且是經過編譯的,執行速度快。在程序中,我們不必再寫復雜的SQL語句,直接寫存儲過程名稱就可以了。
具體如何使用存儲過程,可以參考這篇博文:http://www.51testing.com/html/60/n-814760.html
一定要仔細研究上邊那篇文章,因為這是數據庫使用的經典例子,把他搞懂了使用數據就沒什么問題了,我就偷個懶,不在重復寫啦。
如果遇到一些問題,或許這篇文章會幫你:http://www.51testing.com/html/59/n-814759.html
另外,可以看出,本教程的例子,班級表依賴年級表,學生表依賴班級表,所以在刪除記錄時,必須級聯刪除,級聯刪除可以在程序中完成,但我還是比較喜歡放在SQL觸發器中。觸發器的使用方法和存儲過程大同小異,在這就不贅述了,可以google。
詳細設計還是要用到UML圖,這回用的一般是時序圖和流程圖,其他的雖然重要,但是比較少用,具體的還是google。
很遺憾的告訴大家,教程到此就結束了,細節上遠遠沒有結束,存儲過程具體代碼、各層的代碼都沒有寫,UML的圖還有很多沒畫,但那些都是細節知識,本教程的目的是宏觀指導,本小菜也需要繼續學習,時間非常有限,所以只能寫這么多了。
剩下的基本上都是寫代碼,我寫出來也沒啥意思,開發一個項目,基本的流程都在這呢,我主要不是教大家寫代碼,而不是告訴大家一個項目的流程,體會一個稍微大點的程序是怎么設計出來的,分享一下我自己的經驗。跟著這個教程走,就是再菜,也是專業菜鳥!
教程中涉及大量知識點,都需要大家耐心的去查閱資料,不怕不會,就怕不知道,剛開始會用就可以了,隨著學習的深入,再去搞懂細節原理。我學這些東西也不是一天兩天就學成的,是大約一年半的積累,希望大家能靜下心來,踏實學習。
最后,恭祝大家都能成為IT界的精英!
相關鏈接:
菜鳥也能飛:SQL數據庫實戰專業教程(一)
菜鳥也能飛:SQL數據庫實戰專業教程(二)SQLHelper包:

DAL包:

BLL包:

UI包:
六、概要設計
數據庫分析完了,基礎已經搞定,接下來就是對程序的初步設計。如何設計呢?如果是小程序,用腦子想想,也就算設計完了,但是如果是稍微復雜點的系統,恐怕就不行了。概要設計還是要借助于UML圖,現在你知道它有多重要了吧?我們先來設計程序的大致結構,可以用UML的包圖。作為專業水準的菜鳥,我們要用三層架構來設計程序。所謂三層架構,就是把程序分為基本的三層,分別為:UI層(用戶界面層)、BLL層(業務邏輯層)、DAL層(數據訪問層)。把程序分成三層,好處不言而喻,從此你就再也見不到所有東西都在一個窗體里混亂的情形,如果什么地方需要修改,再也不用去改動整個工程。每一層都有各自的功能,從UI層到DAL層,它們是向下依賴的。其中,UI層只負責顯示界面,不應該有邏輯(有效性驗證的邏輯還是可以有的),所有的功能都是通過調用BLL層完成;BLL層負責程序的所有邏輯組織,它通過調用DAL層完成復雜的操作,然后提供一個簡潔的接口讓UI層調用,相當于一個大外觀層,BLL層的類,可以按照窗體寫,也就是說每一個窗體對應一個BLL層的類,類的各種方法完成窗體的所有功能;DAL層負責訪問數據庫,數據庫中每一個表,在DAL層中都有一個與之對應的操作類,通過該操作類,可以實現對對應表的一切操作。前邊提到的實體類,就是為三層架構服務的,三層之間一般都是通過實體類傳遞數據,這樣簡潔、方便,實體類就相當于一個容器。注意,還有一個層,也可以不單獨作為一個層的DBHelper,這個部分負責最低級的與數據庫交互代碼,比如連接數據庫、插入數據、查詢數據等等,把這些最基本的代碼提煉到一個單獨的層中有利于代碼的復用,使程序更加精煉。欲知其他知識,請輕點google,我說到此為止。獻上一張三層架構的示意圖:

再來一個數據庫、DAL操作類、實體類的關系,這個有點亂,剛開始不好理解,多想想就知道啦:

有了上邊的分析,我們就可以用Rational Rose畫程序包圖了,提一個小技巧,Rose的包理論上應該在包圖里畫,但是那樣沒法畫類,所以還是建議在類圖里畫包,用包把類圖分成幾個大部分,然后在每個部分里畫特定的類,這樣雙擊包直接就可以看到該包中的類了。根據三層架構,我們可以畫出下邊的包圖:

整體架構就是這樣了,接下來就搞定每個包里都有什么類。
1、原始單據與實體之間的關系
可以是一對一、一對多、多對多的關系。在一般情況下,它們是一對一的關系:即一張原始單據對應且只對應一個實體。在特殊情況下,它們可能是一對多或多對一的關系,即一張原始單證對應多個實體,或多張原始單證對應一個實體。這里的實體可以理解為基本表。明確這種對應關系后,對我們設計錄入界面大有好處。
〖例1〗:一份員工履歷資料,在人力資源信息系統中,就對應三個基本表:員工基本情況表、社會關系表、工作簡歷表。這就是“一張原始單證對應多個實體”的典型例子。
2、主鍵與外鍵
一般而言,一個實體不能既無主鍵又無外鍵。在E—R圖中,處于葉子部位的實體,可以定義主鍵,也可以不定義主鍵(因為它無子孫),但必須要有外鍵(因為它有父親)。
主鍵與外鍵的設計,在全局數據庫的設計中,占有重要地位。當全局數據庫的設計完成以后,有個美國數據庫設計專家說:“鍵,到處都是鍵,除了鍵之外,什么也沒有”,這就是他的數據庫設計經驗之談,也反映了他對信息系統核心(數據模型)的高度抽象思想。因為:主鍵是實體的高度抽象,主鍵與外鍵的配對,表示實體之間的連接。
3、基本表的性質
基本表與中間表、臨時表不同,因為它具有如下四個特性:
(1)原子性。基本表中的字段是不可再分解的。
(2)原始性。基本表中的記錄是原始數據(基礎數據)的記錄。
(3)演繹性。由基本表與代碼表中的數據,可以派生出所有的輸出數據。
(4)穩定性。基本表的結構是相對穩定的,表中的記錄是要長期保存的。
理解基本表的性質后,在設計數據庫時,就能將基本表與中間表、臨時表區分開來。
4、范式標準
基本表及其字段之間的關系,應盡量滿足第三范式。但是,滿足第三范式的數據庫設計,往往不是最好的設計。
為了提高數據庫的運行效率,常常需要降低范式標準:適當增加冗余,達到以空間換時間的目的。
〖例2〗:有一張存放商品的基本表,如表1所示。“金額”這個字段的存在,表明該表的設計不滿足第三范式,因為“金額”可以由“單價”乘以“數量”得到,說明“金額”是冗余字段。但是,增加“金額”這個冗余字段,可以提高查詢統計的速度,這就是以空間換時間的作法。
在Rose2002中,規定列有兩種類型:數據列和計算列。“金額”這樣的列被稱為“計算列”,而“單價”和“數量”這樣的列被稱為“數據列”。
表1商品表的表結構
商品名稱商品型號單價數量金額
電視機29吋2,50040100,000
5、通俗地理解三個范式
通俗地理解三個范式,對于數據庫設計大有好處。在數據庫設計中,為了更好地應用三個范式,就必須通俗地理解
三個范式(通俗地理解是夠用的理解,并不是最科學最準確的理解):
第一范式:1NF是對屬性的原子性約束,要求屬性具有原子性,不可再分解;
第二范式:2NF是對記錄的惟一性約束,要求記錄有惟一標識,即實體的惟一性;
第三范式:3NF是對字段冗余性的約束,即任何字段不能由其他字段派生出來,它要求字段沒有冗余。
沒有冗余的數據庫設計可以做到。但是,沒有冗余的數據庫未必是最好的數據庫,有時為了提高運行效率,就必須降低范式標準,適當保留冗余數據。具體做法是:在概念數據模型設計時遵守第三范式,降低范式標準的工作放到物理數據模型設計時考慮。降低范式就是增加字段,允許冗余。
6、要善于識別與正確處理多對多的關系
若兩個實體之間存在多對多的關系,則應消除這種關系。消除的辦法是,在兩者之間增加第三個實體。這樣,原來一個多對多的關系,現在變為兩個一對多的關系。要將原來兩個實體的屬性合理地分配到三個實體中去。這里的第三個實體,實質上是一個較復雜的關系,它對應一張基本表。一般來講,數據庫設計工具不能識別多對多的關系,但能處理多對多的關系。
〖例3〗:在“圖書館信息系統”中,“圖書”是一個實體,“讀者”也是一個實體。這兩個實體之間的關系,是一個典型的多對多關系:一本圖書在不同時間可以被多個讀者借閱,一個讀者又可以借多本圖書。為此,要在二者之間增加第三個實體,該實體取名為“借還書”,它的屬性為:借還時間、借還標志(0表示借書,1表示還書),另外,它還應該有兩個外鍵(“圖書”的主鍵,“讀者”的主鍵),使它能與“圖書”和“讀者”連接。
7、主鍵PK的取值方法
PK是供程序員使用的表間連接工具,可以是一無物理意義的數字串,由程序自動加1來實現。也可以是有物理意義的字段名或字段名的組合。不過前者比后者好。當PK是字段名的組合時,建議字段的個數不要太多,多了不但索引占用空間大,而且速度也慢。
8、正確認識數據冗余
主鍵與外鍵在多表中的重復出現,不屬于數據冗余,這個概念必須清楚,事實上有許多人還不清楚。非鍵字段的重復出現,才是數據冗余!而且是一種低級冗余,即重復性的冗余。高級冗余不是字段的重復出現,而是字段的派生出現。
〖例4〗:商品中的“單價、數量、金額”三個字段,“金額”就是由“單價”乘以“數量”派生出來的,它就是冗余,而且是一種高級冗余。冗余的目的是為了提高處理速度。只有低級冗余才會增加數據的不一致性,因為同一數據,可能從不同時間、地點、角色上多次錄入。因此,我們提倡高級冗余(派生性冗余),反對低級冗余(重復性冗余)。
9、E--R圖沒有標準答案
信息系統的E--R圖沒有標準答案,因為它的設計與畫法不是惟一的,只要它覆蓋了系統需求的業務范圍和功能內容,就是可行的。反之要修改E--R圖。盡管它沒有惟一的標準答案,并不意味著可以隨意設計。好的E—R圖的標準是:結構清晰、關聯簡潔、實體個數適中、屬性分配合理、沒有低級冗余。
10、視圖技術在數據庫設計中很有用
與基本表、代碼表、中間表不同,視圖是一種虛表,它依賴數據源的實表而存在。視圖是供程序員使用數據庫的一個窗口,是基表數據綜合的一種形式,是數據處理的一種方法,是用戶數據保密的一種手段。為了進行復雜處理、提高運算速度和節省存儲空間,視圖的定義深度一般不得超過三層。若三層視圖仍不夠用,則應在視圖上定義臨時表,在臨時表上再定義視圖。這樣反復交迭定義,視圖的深度就不受限制了。
對于某些與國家政治、經濟、技術、軍事和安全利益有關的信息系統,視圖的作用更加重要。這些系統的基本表完成物理設計之后,立即在基本表上建立第一層視圖,這層視圖的個數和結構,與基本表的個數和結構是完全相同。并且規定,所有的程序員,一律只準在視圖上操作。只有數據庫管理員,帶著多個人員共同掌握的“安全鑰匙”,才能直接在基本表上操作。請讀者想想:這是為什么?
11、中間表、報表和臨時表
中間表是存放統計數據的表,它是為數據倉庫、輸出報表或查詢結果而設計的,有時它沒有主鍵與外鍵(數據倉庫除外)。臨時表是程序員個人設計的,存放臨時記錄,為個人所用。基表和中間表由DBA維護,臨時表由程序員自己用程序自動維護。
12、完整性約束表現在三個方面
域的完整性:用Check來實現約束,在數據庫設計工具中,對字段的取值范圍進行定義時,有一個Check按鈕,通過它定義字段的值城。
參照完整性:用PK、FK、表級觸發器來實現。
用戶定義完整性:它是一些業務規則,用存儲過程和觸發器來實現。
13、防止數據庫設計打補丁的方法是“三少原則”
(1)一個數據庫中表的個數越少越好。只有表的個數少了,才能說明系統的E--R圖少而精,去掉了重復的多余的實體,形成了對客觀世界的高度抽象,進行了系統的數據集成,防止了打補丁式的設計;
(2)一個表中組合主鍵的字段個數越少越好。因為主鍵的作用,一是建主鍵索引,二是做為子表的外鍵,所以組合主鍵的字段個數少了,不僅節省了運行時間,而且節省了索引存儲空間;
(3)一個表中的字段個數越少越好。只有字段的個數少了,才能說明在系統中不存在數據重復,且很少有數據冗余,更重要的是督促讀者學會“列變行”,這樣就防止了將子表中的字段拉入到主表中去,在主表中留下許多空余的字段。所謂“列變行”,就是將主表中的一部分內容拉出去,另外單獨建一個子表。這個方法很簡單,有的人就是不習慣、不采納、不執行。
數據庫設計的實用原則是:在數據冗余和處理速度之間找到合適的平衡點。“三少”是一個整體概念,綜合觀點,不能孤立某一個原則。該原則是相對的,不是絕對的。“三多”原則肯定是錯誤的。試想:若覆蓋系統同樣的功能,一百個實體(共一千個屬性)的E--R圖,肯定比二百個實體(共二千個屬性)的E--R圖,要好得多。
提倡“三少”原則,是叫讀者學會利用數據庫設計技術進行系統的數據集成。數據集成的步驟是將文件系統集成為應用數據庫,將應用數據庫集成為主題數據庫,將主題數據庫集成為全局綜合數據庫。集成的程度越高,數據共享性就越強,信息孤島現象就越少,整個企業信息系統的全局E—R圖中實體的個數、主鍵的個數、屬性的個數就會越少。
提倡“三少”原則的目的,是防止讀者利用打補丁技術,不斷地對數據庫進行增刪改,使企業數據庫變成了隨意設計數據庫表的“垃圾堆”,或數據庫表的“大雜院”,最后造成數據庫中的基本表、代碼表、中間表、臨時表雜亂無章,不計其數,導致企事業單位的信息系統無法維護而癱瘓。
“三多”原則任何人都可以做到,該原則是“打補丁方法”設計數據庫的歪理學說。“三少”原則是少而精的原則,它要求有較高的數據庫設計技巧與藝術,不是任何人都能做到的,因為該原則是杜絕用“打補丁方法”設計數據庫的理論依據。
14、提高數據庫運行效率的辦法
在給定的系統硬件和系統軟件條件下,提高數據庫系統的運行效率的辦法是:
(1)在數據庫物理設計時,降低范式,增加冗余,少用觸發器,多用存儲過程。
(2)當計算非常復雜、而且記錄條數非常巨大時(例如一千萬條),復雜計算要先在數據庫外面,以文件系統方式用C++語言計算處理完成之后,最后才入庫追加到表中去。這是電信計費系統設計的經驗。
(3)發現某個表的記錄太多,例如超過一千萬條,則要對該表進行水平分割。水平分割的做法是,以該表主鍵PK的某個值為界線,將該表的記錄水平分割為兩個表。若發現某個表的字段太多,例如超過八十個,則垂直分割該表,將原來的一個表分解為兩個表。
(4)對數據庫管理系統DBMS進行系統優化,即優化各種系統參數,如緩沖區個數。
(5)在使用面向數據的SQL語言進行程序設計時,盡量采取優化算法。
總之,要提高數據庫的運行效率,必須從數據庫系統級優化、數據庫設計級優化、程序實現級優化,這三個層次上同時下功夫。
上述十四個技巧,是許多人在大量的數據庫分析與設計實踐中,逐步總結出來的。對于這些經驗的運用,讀者不能生幫硬套,死記硬背,而要消化理解,實事求是,靈活掌握。并逐步做到:在應用中發展,在發展中應用。
自動化測試架構之說
測試人員經常想象——在無人值守的情況下,每天晚上測試工具自動運行成千上萬的測試用例,第二天早晨去上班,一打開電腦就能看到所有的測試任務已全部執行完畢,測試報告也整整齊齊地出現在我們面前。如果能親身經歷這種場景,一定會感到無比興奮和輕松!這種情景不是夢想,也并不遙遠,完全是可以實現的,只要借助一套靈活、可擴展的自動化測試框架即可幫助我們實現夢想。
為何要建立自動化測試架構
在過去幾十年中,自動化測試已經有了良好的發展。最初的測試工具只提供了簡單的捕捉/回放功能:記錄鍵盤和鼠標的操作,并捕捉屏幕,然后通過播放所記錄的操作進行驗證。這樣的腳本很難維護,從而要求開發功能和靈活性更強的測試工具,并能將這些工具很好地整合起來,使整個自動化測試過程的各個部分或各個階段能很好地銜接起來。這就需要構造一個完整的自動化體系,形成自動化測試的流水線,使整個測試過程一氣呵成。這其中,不僅要包括自動化測試的執行,還要包括自動化測試腳本的開發、軟件包自動部署以及測試報告自動生成等,才能將自動化開發、執行和日常工作融合在一起。這一切都需依賴于自動化測試架構。
針對上述討論,我們深知自動化測試所面臨的挑戰。面對挑戰,必須采取以下這些相應的對策,通過構建適應性很強的自動化測試框架來解決一系列問題。
1)需求頻繁的變化要求自動化測試具有一個靈活的適應機制。我們知道,建造商品住房時,如果只澆灌混凝土框架,沒有砌墻,那么住戶就有更大的靈活性來設計自己的家,可以滿足住戶更多的個人需求。在某些商場、寫字樓的建筑上,這種考慮表現得更為充分,保留了很大的靈活空間供商家租用和裝修。
2)單元測試、集成測試和系統測試等的自動化實施能共享某些平臺和機制,讓這些測試有機地結合起來。例如,房屋的各個功能模塊,包括臥室、會客廳、廚房、衛生間、窗戶、屋頂等都要有框架支撐,才能形成實用的、功能完整的住宅。
3)大規模軟件團隊的協作和硬件資源的使用效率都要求一個良好的基礎設施來支撐自動化測試。例如,房屋的各個單元之間需要通過布置電線、水管、暖氣管、有線電視等網絡,才能有機地結合起來,更好地支撐各個功能之間的協調和使用,更好地為住宅的主人服務。
從上面這些舉例可以得知,自動化測試也不例外,在進行具體的單元自動化測試、功能自動化測試和系統自動化測試之前,先要建立一個清晰的框架,才能包容自動化測試的各個功能單元,使將來各項自動化測試任務有機地結合起來,順利地開展工作。
解決什么問題
作為自動化測試框架,最根本的是要構造一個良好的工作空間,能夠容納各種類型測試工具的執行,以使這些工具能夠相互兼容,共享測試數據。如果能夠像Windows 操作系統那樣支持即插即用,任何測試工具都可以動態、方便地加入系統或從系統中移除,則再好不過。
其次,自動化測試框架需要能夠監控測試執行的過程,包括監控測試對象資源(如CPU、內存等)的使用,及時收集來自不同測試工具的測試結果,并將這些結果進行歸類和分析,生成相應的測試報告,通過郵件和網站等發布出去。
再者,為了讓測試能夠在某個特定時刻(例如晚上)自動執行,自動化測試框架應具有事先安排(schedule)任務能力,并能夠支持維護測試環境和管理測試資源,包括管理硬件資源列表、支持測試狀態查詢和自動分發測試任務到相應的測試機器上,并在規定的時間內完成測試任務。
最后,自動化測試框架還應能支持自動化測試的前期任務,支持測試腳本的錄制、編輯和調試,支持測試腳本的快速開發和良好的維護性,而且能夠支持測試用例、測試套件(test suite)和其他測試活動的管理。
要構建良好的自動化測試框架,還需要提供一些基礎設施來支持自動化測試,例如郵件服務、跨平臺的通信服務、分布式開發和運行環境等,如圖2-7 所示,一個良好的自動化測試框架應具有下列能力。
1)提供非常有效的測試工作流程模型,如對任務安排、執行、通知結果和生成報告等完整的過程支持。
2)支持多種腳本語言的錄制、編輯、調試和回放等集成開發環境。
3)完成各類測試任務的執行。
4)有良好的擴充能力,如和第三方插件、工具的集成。
5)具有數據驅動、關鍵字驅動等腳本模式的支持。
6)具有分布式處理、遠程調用等不同的運行方式。
7)能獲取測試覆蓋率。

圖2-7 自動化測試框架要解決的問題
如果進一步抽象,自動化測試框架就是用來解決自動化測試中的公共問題的,包括公用的對象、公用的方法、公用的環境或數據等自動化測試框架的要素。
1)公用的對象。不同的測試用例會有一些相同的對象(如窗口、按鈕、菜單等)被重復使用,而這些公用的對象可以被抽取出來,在編寫腳本時隨時調用。如果需求發生變化,只需要修改這些公用對象的屬性即可,而不需要修改太多的測試腳本。而要做到這一點,就要求我們構建對象庫,并建立實體對象和邏輯對象之間的映射。
2)公用的方法。公用的方法比較多,相當于腳本的基礎函數,可以構成基礎函數庫,供上層腳本調用。
3)公用的環境或數據。許多測試用例會在相同的測試環境上運行或使用相同的測試數據,可將不同的測試環境或數據封裝起來,和測試用例進行靈活的組合,以增強腳本執行的靈活性,并覆蓋更廣的測試范圍,降低測試風險。
自動化測試框架應支持腳本錄制、腳本開發、測試用例和測試套件的創建和執行、遠程控制、分布式通信等功能,才能基本滿足測試自動化的需要。自動化測試框架還需要支持單元測試并與開發環境集成,如將集成開發環境Eclipse、軟件配置管理工具CVS/SubVersion 和軟件包構建工具Ant/Maven等集成到這個框架中,以支持每日構建和自動驗證測試。
如果自動化測試框架能管理測試項目、安排任務,將產品用戶需求和測試需求很好地結合起來,那么測試目標更明確,測試的效率會得到進一步提高。測試結果的分析也是很重要的,一般要求在自動化測試框架中得到解決。最重要的是易用,將各個工具集成起來,并能使這些工具更好地發揮作用。例如,openqa.org 社區提供了一個工具Bromine,它集成了Selenium Core/RC,非常容易跟蹤和管理測試項目、需求、測試計劃、測試用例和缺陷,可以監控缺陷的提交,將缺陷分派給相應的開發人員來瀏覽和分析測試結果。
一個理想的自動化測試框架能解決上述問題,提供一個分布式的通信平臺、友好的人機交互界面和開放式架構,將自動化測試中所需要的各個關鍵部分有機地集成起來,形成一個為自動化測試服務的、完整的、層次清楚的開發平臺和運行環境,如圖2-8 所示,其中各主要部分的功能如下。

圖2-8 自動化測試框架示意圖
1)綜合管理平臺:可以將自動化測試中所有的工作內容管理起來,相當于一個統一的入口(Portal),可以瀏覽每部分的內容。
2)基于業務驅動的腳本集成開發環境:可便于構造關鍵字驅動的腳本,為此要建立軟件系統的對象庫,并將這些對象映射為腳本中的邏輯對象,以減少軟件需求變化對腳本的影響。這個集成開發環境還包括腳本錄制、編輯等功能,并能和CVS、Ant 等工具集成。其中庫函數可以看做是關鍵字列表和關鍵字實現,而對象映射可以看做是由對象庫和映射關系構成的。
3)安排(Schedule)測試任務:使任務可以定時啟動,自帶執行測試任務。
4)監控測試資源:在測試過程中,能夠及時發現問題,發出警告,并保留(記錄)相關數據。
5)控制中心(控制器):驅動測試工具,可以調用測試任務,并將測試任務、測試腳本等分發給遠程機器。
6)遠程機器執行測試任務:通過代理實現,而代理由控制中心來控制。
相關鏈接:
工具介紹
Firebug: 這個不介紹了,居家旅行殺人越貨必備的Firefox插件
YSlow: 當Firefox瀏覽網頁時,可以分析網站的頁面(基于Yahoo 14條評分原則),并告訴你為了提高網站性能,如何基于某些規則而進行優化
ShowSlow:收集YSlow的測試結果并顯示出來
思路整理
使用Selenium編寫測試用例依次訪問需要測試的站點,設置YSlow每打開一個頁面自動運行測試,并將測試報告發送到指定的ShowSlow服務器,建議可以和我前幾天說的自動化框架搭配使用,何樂而不為:)
環境配置
搭建本地ShowSlow平臺
默認情況下YSlow的結果會發送到ShowSlow(印象中),但這顯然不符合天朝國情,同時也及其不和諧,還好ShowSlow開源網站提供源碼可以在本地搭建一個平臺來收集YSlow的信息。主要采用Apache+PHP+Mysql這個框架,但是很不幸的告訴各位我嘗試過獨自手工搭建上述環境,弄壞了兩臺虛擬機(Win 2003)都未遂,主要在于沒有相關經驗,在此推薦使用 AppServ傻瓜化一體式安裝吧(請盡情鄙視我,謝謝)
1.先用SVN將源碼下載到本地,并放置于Apache的WWW文件夾下(請猛擊我)
2.修改ShowSlow文件夾下的config.sample.php重命名為config.php,里面$db,$user,$pass可以根據實際情況修改
3.創建第2步中你填寫的數據庫,MySQL我也不太會,高手無視我
//創建一個數據庫,名字和第二步你填寫的保持一致
create database ‘DBName‘;
//切換到新建的數據庫
use ‘DBName’;
// 將ShowSlow文件夾的tables.sql(數據庫表)導入到新建的數據庫中,注意無分號
source c:\tables.sql
//查看下是否導入成功了,貌似有個表名叫ShowSlow2,汗
show tables;
配置YSlow
1.打開Firefox輸入:about:config(我保證會很小心的)
2.filter中輸入:yslow
3.修改以下三條數據
extensions.yslow.beaconUrl = http://localhost/showslow/beacon/yslow/
如果測試和服務器不在同一機器上,請將localhost改成實際地址
extensions.yslow.beaconInfo = grade
extensions.yslow.optinBeacon = true
4.重啟Firefox,have fun 
還等什么?開始你的測試之旅吧,查看測試報告的URL是:http://localhost/showslow/
PS:Google的Page Speed和YSlow差不多,也支持發送報告至ShowSlow,有興趣的同學可以試試
在幾年的測試工作中,大部分工作內容都是在編寫測試腳本(或測試程序)。而測試腳本設計寫主要包含應用測試腳本和底層測試腳本的設計。甭管是哪種,設計他們的目的是實現測試用例的輸入\輸出平臺,設計方向都是自動化測試方向。使測試實施中盡量提高自動化測試程度,從而使測試人員把更多的心思或經歷投入到測試設計中。測試腳本設計也是測試設計之一。
大多數人可能認為,測試腳本只要實現測試用例數據的輸入就好了,只要能輸入測試數據和得到預期的測試結果數據就可以了。個人認為,這種想法是初級的,膚淺的。測試腳本的設計不僅要求能實現測試數據的輸入和輸出,同時也要考慮測試腳本結構的合理性,及可維護性。同時更要考慮到測試腳本的正確性和可靠性。想想,如果測試程序都不可靠了,那他產生的輸出還可靠嗎?良好的腳本組織結構固然重要,所以各公司可能有不同的腳本框架來保證,測試腳本結構的合理性和可維護性。我所經歷的腳本設計,從開始的流水式腳本設計到結構化腳本設計,再由結構化腳本設計到框架腳本設計,再到最后框架腳本設計和測試平臺配合使用的設計,逐步精化設計,逐步簡化設計,逐步自動化執行。可以說在這方面的技術已經相當的成熟了。但是唯一不足的就是同一腳本,在不同平臺或回歸測試時,多少都會有個別用例測試不通過,而不通過的原因經過分析會發現是腳本存在的問題。
所以,腳本設計時的調試僅僅是保證測試腳本正確的一種有效的手段。但腳本設計時,個人認為不僅要從開發的角度,同時還要從測試專業角度來考慮設計,如數組邊界處理,死循環處理,空指針,類型轉換等。
總之,良好的編程習慣和基礎能夠幫助測試設計人員更好的開發測試腳本,但利用專業的測試知識去開發測試腳本,能夠更好的避免由于測試腳本的問題而引發的測試缺陷。從而增加測試結果可靠性和縮短測試周期的一種有效的,高效的方法和手段。
由于受到極限編程的影響,在最近的幾年時間里單元測試逐漸成為我軟件開發過程中一個不可或缺的重要組成部分。極限編程要求我們對我們所完成的每一項功能都要進行單元測試并且要很好的管理這些測試,我們不應該在所有的單元測試通過之前去集成任何新的功能。這種做法的好處就是可以讓開發人員對自己所寫的代碼充滿信心(而不是盲目的毫無根據的自負)。
最開始我認為既然已經有了單元測試了,就沒有必要再去花時間在功能測試上了,可我現在知道這是一個錯誤的想法:單元測試和功能測試是有很大的不同的。我花了很長的時間才了解到單元測試和功能測試的差異所在,我也知道了怎樣更好的運用單元測試和功能測試來完善我們的軟件開發流程。
這篇文章探究了單元測試和功能測試的不同點以及我們可以怎樣運用這兩種測試來支持我們的軟件開發。
測試和軟件開發過程
作為一個開發人員來講,測試是相當重要的,我們必須要堅持在整個軟件開發流程中測試我們的代碼,而不僅僅把測試作為軟件開發的一個特殊階段的產物:測試絕對不應該成為你在軟件提交前一天才開始的一個例行公事。你怎么才能知道我們的軟件已經可以發布了?你怎么知道我修正了這個小bug的時候沒有引發一個更嚴重的系統bug?你怎么知道當前的系統是否可以擴展一些現在沒有想到功能呢?測試!單元測試和功能測試必須成為我們在軟件開發流程中的一個有機組成部分。
單元測試應該成為你寫代碼的一個核心部分,尤其是在項目時間比較緊張但是我們仍然要保證質量的時候。單元測試十分重要,你甚至應該在你的代碼寫出來之前就應該完成單元測試。
單元測試:
-》有助于盡可能地重現最有效的設計
-》有助于提供一個最佳的文件組織結構
-》有助于確定一個類是否完成
-》讓開發人員對自己的代碼充滿信心
-》是快速重構的基礎
單元測試有助于形成系統化的并可以不斷改進的設計文檔,這些文檔在軟件開發的過程中有著極其重要的意義。大多時候將用例文檔化形成一個類要比僅僅羅列一大堆編碼的實際用例好,看看單元測試:它提供一系列有規律的輸入或數據,用一系列的實際用例來告訴我們所寫的類做了些什么。這樣的話這個設計文檔就總是最新的,因為我們必須通過單元測試。
你應該在寫代碼之前寫單元測試,這樣做的好處就是為自己提供了一個可以測試的設計方案,這就可以幫助你想的更加完善,這樣會使設計變得簡單。你不必擔心將來會怎樣,也不必花時間去實現一些不必要的功能。首先寫單元測試還有助于幫你了解代碼在什么時候完成:當所有的測試都通過之后,我們的任務也就完成了。
最后,單元測試讓你對自己代碼有高度的自信,這有助于我們做出更加好的產品。當你修改了自己的代碼之后,我們來運行我們的測試,如果有問題的話我們可以迅速找出來我們的修改產生了在什么地方哪些破壞。
功能測試甚至比單元測試更加重要,因為它是用來檢測我們的系統是否達到可以發布的要求。功能測試是用來確定我們的系統是否是一個可用的系統。
功能測試:
-》確定是否實現用戶需求的一個有效方法
-》讓用戶和開發人員了解到我們的系統已經實現了這些用戶需求
傳統的開發過程是從實際使用中確定是否實現用戶需求的,通常人們需要花費大力氣才可以搞清楚這些實際用例并設法概括它們,當他們完成了這些工作之后他們手中無非多了一張紙而已,而功能測試就像是自己確定實際用例一樣。極限編程闡述了這些觀念,極限編程需要提前定義這些功能(這一過程需要項目組和用戶共同完成),而功能測試就是它的產物,如果沒有功能測試的話,我們不可能完成的很漂亮。
功能測試可以檢查出單元測試遺留下的一些軟件缺陷,讓開發人員對自己的代碼更加有信心,因為單元測試仍然會遺留下很多bug,它可能會覆蓋到代碼的各個部分但是卻不能覆蓋到系統的各個部分。功能測試可以揭露一些單元測試沒有涉及的問題。當然一個自動化的可持續運行的功能測試不可能找出系統中的所有問題,但它可以找出更多的單元測試找不到的bug。
本文中考慮的軟件測試過程專指第三方的軟件測試過程,即在測試的過程中,不涉及開發人員的修復過程。
度量和分析的目的是開發和維持一個用于支持項目信息需要的度量能力。通過對項目的度量,一方面可以逐漸豐富和完善公司的度量財富庫,從而為項目經理進行項目工作量、進度等的預估時提供可靠的參考依據;另一方面,通過度量分析,項目經理可以有效的對項目情況進行監控,當度量分析報告中提供的結果超過了一定的閾值時,項目經理就應該采取相應的措施,也就是說度量分析有利于項目經理做出正確的管理和技術決策以及采取適當的糾正活動。
從軟件生存周期模型中來看,人們常常直觀的認為軟件測試僅僅是軟件生存周期中軟件編碼完成之后的一個或幾個階段。而實際上,軟件測試本身也是一個過程,它可以進一步具體的分成若干個階段性活動,如:測試計劃、測試設計、測試執行、測試總結。對測試過程的度量必須涉及到測試過程中的各個階段的度量,包括規模、工作量、進度、缺陷等等。下面著重介紹下測試設計和測試執行階段與效率和質量相關的度量。
(1)測試設計
軟件測試設計階段主要工作是測試用例的設計與開發,在這個階段可度量項包括:
● 用例生產率
用例生產率 = 測試用例個數(個數)/ 設計用例的時間(小時)。
在項目組中度量時,既可以得到每個項目組成員的用例生產率,從而來衡量其生產率;也可以得到項目組的用例生產率,與公司的度量財富庫中的用例生產率進行比較,可得到自己項目組的整體水平。
● 用例質量
在用例寫完進入測試執行階段之前或是寫用例的過程中,都會有對用例進行評審的過程,用例質量可以通過評審中發現的問題來評價。用例質量 = 評審問題個數 / 用例個數。
(2)測試執行
軟件測試執行階段,是在準備好的測試環境上依次執行各測試用例并詳細記錄每一步測試結果,提交缺陷記錄的過程。在這個階段可度量項包括:
● 用例執行率
用例執行率 = 執行的用例個數 / 執行測試的時間。通過這個派生度量即可以得到項目組每個成員的用例執行率,同樣也可以得到項目組的平均用例執行率。
● 用例有效率
用例有效性 = 發現的缺陷個數 / 用例個數。用例有效性的可比性在項目之間不是很大,因為各個軟件項目質量的好壞會直接影響到用例的有效性,若項目質量較好,則同樣的用例個數發現的缺陷較少,若項目質量較差,則同樣的用例個數發現的缺陷較多,但若在同一個項目中進行比較,還是有一定的可比性可言的。
● 缺陷發現率
缺陷發現率 = 缺陷個數 / 執行測試的時間。前面提到用例執行率可以看出項目組成員的工作效率,但并不能保證其質量,通過項目組成員各自發現的缺陷個數除以各自所花的時間,通過缺陷發現率這個指標來關注項目組成員的工作質量。
● 缺陷等級分布
對項目組發現的缺陷,按缺陷等級進行分類統計,得到系統的各個等級的缺陷分布情況。
● 模塊缺陷率
模塊缺陷率 = 該模塊發現的缺陷個數 / 該模塊的用例個數。這樣可以得到它與其他模塊的橫向比較。