天天看點

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

點選檢視第一章 點選檢視第三章

第2章

流程圖

計算機領域很早就開始使用流程圖(flowchart)了,這可能是使用最早的一類行為模型。在20世紀60年代,工具供應商通常會提供一些具有可塑性的流程圖模闆,程式員可以據此繪制出更整齊的流程圖。IBM公司甚至提供了一個帶有基本标記的不同規格标準的流程圖模闆。前輩們開玩笑說,這是該領域的第一個CASE(計算機輔助軟體工程)工具。

2.1 定義與表示法

通常有兩種不同風格的流程圖示記形式。圖2-1所示為第一種,這是一種極簡風格的表示方式,隻有表示動作、決策和兩種頁連接配接符的符号。分頁連接配接符一般用于不能在一頁上顯示完全的大型系統中。傳統的分頁連接配接符使用大寫字母ABC…,第一個分頁連接配接符是A,與之對應的連接配接點也用A表示。

在流程圖使用的早期,因為比較關心系統的輸入/輸出裝置,是以開發出很多擴充的流程圖符号,如圖2-2所示,這裡面甚至有表示卡片式I/O的符号。

 

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

在這種流程圖示記方式中,“?流?”的部分使用帶箭頭的線段,表示從某個流程圖符号開始,在某個流程圖符号處結束。圖2-3是特濃咖啡自動售賣機的流程圖示例,利用這個咖啡機,可以用1歐元買到一小杯意大利特濃咖啡。後續我們還會使用這個案例讨論流程圖技術。

2.2 技術詳解

圖2-3中的流程圖能夠處理自動售賣機的銷售過程。接收歐元硬币,給出特濃咖啡。如果仔細觀察流程圖,可能會注意到,所有的箭頭都會在符号的頂部結束。這不是強制要求,但這樣做有助于了解。決策框隻能有一個入口,既然是決策過程,那麼至少應有兩個出口箭頭。在早先的Fortran年代,“Arithmetic IF”語句帶有3個輸出。這個鑽石形狀的框(決策符号框)的邊與底部頂點可以分别表示3種選擇(<、=、>)。在圖2-3中很容易看到這3個選項。如果多于3個選項(比如Case/Switch語句),每個選項對應一個連接配接箭頭即可。(辨別符是為使用者服務的,不必非要遵守條條框框)。過程框則最多隻有一個輸出箭頭。但它們可能有多個輸入箭頭。箭頭上的标簽通常表明決策框有幾個可能的出口,Yes/No、True/False或者數值顯示決策結果。從過程框發出的箭頭則沒有标簽。這樣表示過程框的過程是完整的,流程走向下一個框。框之間不會表達資訊或内容。使用者需要自己确定過程框的結果對于後續框是否可用(流程圖具有“記憶性”)。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

對于過程框和決策框來說,框内文本内容幾乎沒有限制,可以有不同的形式,這些形式的抽象程度也可以不同。框内文本可以簡明扼要,如圖2-3所示。或者也可以非常具體,甚至可直接是某種程式設計語言。例如“硬币是”決策框的輸出結果可以是1.00歐元、0.50歐元或0.20歐元三種形式。同樣,決策條件也可以表示為針對每一種硬币類型的二進制條件,如“是”或“否”。不管使用哪種方式,最好要保持一緻,如果不同抽象級别的文本表達混合在一起,那将是很讓人困惑的。流程圖的符号集可以支援結構化程式設計的3種基本結構:順序、選擇、循環。例如圖2-3所示的決策框表示了“選擇”結構,而圖2-3底部還有一處表示了“循環”結構:如果變量“總金額”與1歐元的比較結果是“小于”,就會傳回到投入硬币過程框。再看一下1歐元那個分支,它結束“提供特濃咖啡”這個過程框,這正是“順序”結構的例子。在結構化程式設計中,通常有“單一入口,單一出口”的設計慣例,但是這個慣例并不是強制要求,圖2-3所示例子是符合這個慣例的。

流程圖采用分層政策來處理不同抽象級别的過程。也就是說,一個高抽象級别的過程框可以擴充成一系列更詳細、單獨的流程圖。如果這樣做,那麼每一個低抽象級别的流程圖都應該被命名,以此來清晰地表明它是從某個高抽象級别的過程框擴充而來的,或者幹脆使用分頁連接配接符(隻是分頁連接配接符的方式顯得有些笨重)。本章結束部分的表2-4,總結了在流程圖中可以表達的控制事件。

2.3 案例分析

2.3.1 日期計算函數

NextDate函數是測試圈裡非常流行的一個例子,它非常簡單,很容易找到測試用例的預期輸出。(給定某個日期,NextDate函數傳回下一個日期。)圖2-4和圖2-5采用分層流程圖方式将功能進行了分解。變量lastDay的數值通過其他方式計算出來,然後與決策框中的日期進行比較。如果某個變量可以在多處指派,那麼必須保證最終計算出來的數值在運作過程中不會互相改寫。在NextDate流程圖中,有3個值被配置設定給nextDay、nextMonth和nextYear。決策框要求這3個指派必須是互斥的。在這些計算過程中使用到了GoTo語句,當使用流程圖來建立主要的行為模型時,使用GoTo語句是一種常用作法。在流程圖中可以清晰地看到,NextDate函數的邏輯是很嚴密的。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

2.3.2 風寒指數表

著名的風寒指數(密歇根州或者其他寒冷地區)是由兩個變量構成的函數:每小時風速V和攝氏溫度T。其公式如下所示:

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

其中,W是人臉的表面溫度,以華氏度為機關;T是空氣溫度,以華氏度為機關,

-20≤T≤50;V是風速,以mile/h(1mile?=?1609.34m)為機關,3≤V≤73。

基于圖2-6所示的流程圖可以完成一個類似表2-1的表格,請注意其中的循環嵌套。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

(例子中的數值範圍是随意制定的,在密歇根州,這是真實情況!)風寒表格中溫度的範圍是-20℉≤T≤50℉,每次遞增5℉;風速範圍是3≤V≤73,每次遞增5mile/h。

2.3.3 保費計算流程圖

圖2-7是1.8.1節中定義的保費計算問題的流程圖模型。

2.3.4 車庫門控系統流程圖

圖2-8是1.8.2節中定義問題的流程圖模型。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

2.4 基于流程圖派生的測試用例

流程圖中的路徑可以直接推導出抽象的測試用例。由于流程圖可以顯示并發的路徑,是以很容易手工設計出相關的抽象測試用例。從圖2-7所示的保費計算流程圖中可以看到關于年齡和保費變量的并發路徑。毫無疑問,并發路徑應該是互斥的。(測試用例也可以利用某個指定流程圖的語義内容派生出來,但這反過來又要求手動推導測試用例生成。)通常來說,從流程圖中不可能直接設計出具體的測試用例,因為流程圖隻顯示了需要完成的過程,并不實際執行這些過程。

(對于類似Fortran這樣的程式來說,流程圖很好用。)而對于事件驅動型應用來說,流程圖的形式就顯得不太适合了。從接下來給出的事件驅動示例,可以清晰看出以下幾個問題。

  • 事件可以表示為決策的輸出或者過程(過程框)。
  • 由于沒有專門的事件辨別符,是以事件隻能表示為流程圖中有明确語義的内容。
  • 需要具有洞察力和領域經驗才能識别與上下文相關的輸入事件。

2.4.1 保費計算問題的測試用例

圖2-7所示的流程圖中一共有40條不同的路徑,其中36條對應着表2-2列出的使用等價類測試方法生成的測試用例。年齡和出險次數變量由變量的取值範圍來定義,是以從表面上看,隻需要測試某種形式的邊界值就足夠充分了。将每個等價類中的邊界值映射到相同的乘法和加法函數集合中,它們會在結果中産生大量的備援,因而這并無太大價值。圖2-9顯示了表2-2中測試用例1的路徑。

表2-2顯示了保費計算問題的抽象測試用例和具體測試用例。抽象測試用例可以從流程圖中直接設計出來(MBT工具可以完成這個過程)。實際數值則需要從需求中擷取。從圖2-7中給定的文本可以看出,對于MBT工具來說,直接生成測試用例需要的實際數值還是很困難的。我主要使用電子表格中的替換功能來完成這部分工作,這樣還不算太麻煩。通常來說,電子表格是MBT工具很順手的一個補充。

下面是圖2-8所示路徑對應的測試用例1中的抽象和具體測試用例。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

2.4.2 車庫門控系統的測試用例

在車庫門控系統的流程圖中有兩個循環:一個是停下并重新開機正在關閉的門,另一個是停下并重新開機正在打開的門。(一個是在關門過程中停下或者重新開機,一個是在開門過程中停下或者重新開機。)如果假設輸入事件和輸出過程是同時發生的,那麼數學家會說,在圖2-8所示的流程圖中,存在一個含有不同路徑的可數無窮路徑集合。在實際生活中,我家的車庫門需要大概13s關閉或者開啟,而停止/重新開機序列需要大概1s,是以,實際上車庫門流程圖隻有一個有限數目的可能路徑。圖2-10顯示了其中一條路徑,該路徑由下面的測試用例來表示。圖2-10所示的流程圖符号是有編号的,以表示路徑的追蹤和命名。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

表2-3包含車庫門流程圖中的5條不同路徑。我們先簡要描述一下每條路徑(也可以視之為使用者場景),然後再使用按系列編号的流程圖符号來較長的描述它們。5條路徑涵蓋了每個流程圖符号和流程圖中的每條邊。另外還有些路徑是針對光束被打斷之後的過程的,這些路徑也包括每個上下文的控制裝置的輸入事件。對于工具來說,很難從流程圖中設計出詳細的、類似使用用例(use case,從使用者角度考慮的使用場景)的測試用例。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

表2-4包括從圖2-8所示流程圖中設計出的手工測試用例資訊。從中我們可以看出,流程圖的定義存在一些“小問題”,原因如下:

1)輸入事件看上去既可以是決策框的輸出,也可以是過程框中表示的一個過程;

2)事件上下文(狀态)看上去是與過程框對應的過程,也可以說是決策框的輸出;

3)有兩個潛在的死循環:正在開門或者關門時停止。

除非具有領域經驗,否則,利用輸入事件/輸出過程對是沒有辦法定位下一步操作的。

2.5 優勢與局限

流程圖有很多優勢。如果任何一種表達方式已經使用了數十年,那麼它肯定還是有可取之處的。對于流程圖來說,這個優勢就很容易了解。由于過程框和決策框裡面的文本可以使用自然語言,是以流程圖使客戶和開發者之間具有更好的互動性。就連美國的IRS都是用流程圖來解釋複雜的稅務代碼的。如我們之前所說,流程圖能夠表達基本的結構化程式設計架構。其中,還有沒有明确說明的地方,這就是對于流程圖中“存儲器”功能的使用。如果一個變量在過程框中被賦予一個值,那麼該變量在後續需要保持這個數值。在圖2-3中可以清楚地看到,變量“總金額”被定義之後,在之後的循環中可以再次定義它。任何“形式化好的”流程圖都可以使用指令式和結構化的程式設計語言進行編碼。如示例中所示,流程圖支援幾種級别的抽象,是以它們具有可擴充性,能夠描述大型而且複雜的應用。另一個優勢是,它們可以用來描述複雜的計算和算法。最後一個優勢是有些控制過程或者行為可以通過流程圖中不同的路徑來表達。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

流程圖也有些限制。由于流程圖的本質是将過程式列化,是以很難表達事件驅動的系統,因為在事件驅動的系統裡面,獨立事件可能以任何順序發生。此外,流程圖很難描述被描述系統需要操作的外部裝置的上下文。雖然面向裝置的I/O符号可以完成這個工作,但是需要很多擴充。流程圖幾乎沒有辦法表達資料,除非是在過程框或者I/O框裡面。過程框和決策框裡面的文本可以包含變量名,但這是很粗淺的表達。資料表達都如此困難,表達資料結構以及資料之間的關系就更難了。同樣,對于描述事件,它也有很多潛在的困難。從圖2-8中可以看到,裝置控制信号有時表示為過程框,有時又顯示為決策框的輸出。表2-5将流程圖的描述能力與第1章定義的标準清單進行了對比。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章
帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

2.6 經驗教訓

在20世紀60年代晚期,電話交換機系統開發實驗室需要将所有的互動系統源代碼的流程圖文檔提供給營運公司。當時,源代碼大概是30萬行的彙程式設計式。在這個過程中,軟體工程師需要向圖案部送出手繪流程圖,六周以後,軟體工程師就可以得到非常完美的流程圖。在這六周内,如果設計師想要對流程圖進行修改,那麼他們可以将原始草圖替換成修改之後的草圖,以免在圖案部裡重新排隊。

同時,我的管理團隊中的一位數學家參加了一次研讨會,會上他看到一個程式,這個程式能夠在CalComp繪圖機上畫出離散部件電路圖。我們研究了技術資料後,決定将電路圖符号替換成流程圖符号,結果就産生了AELFLow系統[Jorgensen和Papendick 1970]。這是我們學到的第一個經驗:為了使繪圖機能夠得到認可,我們向每個部門展示了他們如何從繪圖機上獲益。推銷了幾周之後,我們最終得到許可購買了最小的繪圖機。6個月之後,我們有了最大的繪圖機。AELFlow系統非常有效,不僅節約了返工的時間,而且提高了設計文檔的整體可用性。相比彙編代碼,流程圖更容易從技術角度進行描述。從各方面來看,AELFlow系統都是真正的CASE工具,這比術語CASE的使用要早得多。

這裡關鍵的教訓是:變革是很難引入的,它需要時間、耐心和對企業的認知,同時也需要教育訓練。盡管對于AELFLow系統來說,教育訓練是很少的一部分。Gartner Hype的周期是相當精确的,盡管持續的間隔可能有變化(如圖2-11所示)。準備引入MBT的組織一定要經曆宣傳周期。我的觀點是,期望膨脹的峰值期源于MBT産品的銷售團隊,泡沫破裂的幻滅期則源于不同模式的不充分的教育訓練和教育。穩步爬升的複蘇期開始于合适的工具和良好的模式教育,實質生産的成熟期則随着市場的關注度和占有率而保持。

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

參考文獻

帶你讀《基于模型的測試:一個軟體工藝師的方法》之二:流程圖第2章

繼續閱讀