您的位置:軟件測(cè)試 > 開(kāi)源軟件測(cè)試 > 開(kāi)源單元測(cè)試工具 >
AOP@Work: 對(duì)方面進(jìn)行單元測(cè)試
作者:網(wǎng)絡(luò)轉(zhuǎn)載 發(fā)布時(shí)間:[ 2013/3/12 17:03:58 ] 推薦標(biāo)簽:

簡(jiǎn)介:AOP 使編寫(xiě)特定于應(yīng)用程序的橫切關(guān)注點(diǎn)測(cè)試比任何時(shí)候都要容易了 。 要了解其原因以及如何實(shí)現(xiàn),請(qǐng)聽(tīng) Nicholas Lesiecki 介紹測(cè)試面向方面的代 碼 所具有的好處,并展示在 AspectJ 中測(cè)試橫切行為的樣式。

在過(guò)去五年中廣泛采用的程序員測(cè)試是由顯著的生產(chǎn)率和得到的代碼質(zhì)量所 驅(qū) 動(dòng)的。不過(guò),在面向方面編程(AOP)出現(xiàn)之前,為橫切行為(如安全、事務(wù)管 理 或者持久性)編寫(xiě)測(cè)試很困難。為什么呢?因?yàn)檫@些行為沒(méi)有很好地模塊化。如 果沒(méi)有可測(cè)試的單元,那么很難編寫(xiě)出單元測(cè)試。隨著 AOP 的普及,編寫(xiě)與 橫 切關(guān)注點(diǎn)在目標(biāo)系統(tǒng)中的實(shí)現(xiàn)無(wú)關(guān)的、對(duì)其進(jìn)行檢查的測(cè)試已變得可行并且值得 去做。

在本文中,我將介紹測(cè)試用方面實(shí)現(xiàn)的橫切行為的一組技術(shù)。重點(diǎn)放在方面 的 單元測(cè)試,但是我也展示了有助于建立對(duì)面向方面應(yīng)用程序的信任度的其他模式 。很快您會(huì)看到,測(cè)試方面涉及許多與測(cè)試對(duì)象相同的技巧和概念,并且有許 多相同的做法和設(shè)計(jì)好處。

本文的撰寫(xiě)基于我在 AspectJ 中的經(jīng)驗(yàn)。許多概念應(yīng)當(dāng)可以移植到其他 AOP 實(shí)現(xiàn)中,但是有些概念是特定于語(yǔ)言的。請(qǐng)參閱 下載 以下載本文源代碼,請(qǐng)參 閱 參考資料 以下載完成例子所需要的 Aspectj 和 AJDT。

面向方面代碼的單元測(cè)試

應(yīng)用程序的好的自動(dòng)測(cè)試集應(yīng)當(dāng)像圖 1 那樣:以隔離的、對(duì)各個(gè)類的測(cè)試構(gòu) 成一個(gè)廣泛的基礎(chǔ),使測(cè)試覆蓋面廣,并能迅速分離出錯(cuò)誤。在這之上是集成的 、端到端的系統(tǒng)測(cè)試,它驗(yàn)證各單元是否可以協(xié)調(diào)工作。如果這些層是良構(gòu)的并 且頻繁運(yùn)行,那么它們結(jié)合在一起可以增加對(duì)于應(yīng)用程序行為的信任度。

在金字塔底部的單元測(cè)試很重要,這有幾個(gè)理由。首先,它們幫助您產(chǎn)生那 些 在集成測(cè)試中難于再現(xiàn)或者需要繁瑣步驟才能再現(xiàn)的關(guān)注點(diǎn)用例。其次,由于它 們涉及的代碼更少,因此它們運(yùn)行起來(lái)通常更快(因此可以更經(jīng)常地運(yùn)行它們) 。第三,它們可以幫助您思考每個(gè)單元的接口和要求。好的單元測(cè)試要求單元間 的松散耦合,這是在測(cè)試條件下讓測(cè)試得以運(yùn)行的條件。

圖 1. 分層的測(cè)試

但是橫切行為會(huì)怎么樣呢?想像一位客戶的要求:“在執(zhí)行對(duì) ATM 類的任何 操作之前要檢查調(diào)用者的安全憑證。”當(dāng)然可以(并且應(yīng)該)針對(duì)這項(xiàng)要求編寫(xiě) 集成測(cè)試。不過(guò),非面向?qū)ο蟮拈_(kāi)發(fā)環(huán)境使得編寫(xiě)“在操作之前檢查安全性”這 種行為的單元測(cè)試很難將這種行為分離出來(lái)。這是因?yàn)樾袨榛烊氲搅四繕?biāo)系統(tǒng)中 ,讓人很難把握或者用工具分析。但是如果用方面開(kāi)發(fā),那么可以將這些行為 表示為建議(advice),應(yīng)用到所有匹配某個(gè)切點(diǎn)(pointcut)的操作,F(xiàn)在行 為可以很好地用單元表示,可以在隔離的情況下測(cè)試或者在 IDE 顯示它。

面向方面的代碼在哪里出現(xiàn)問(wèn)題了

在討論對(duì)方面進(jìn)行單元測(cè)試的技術(shù)之前,我要簡(jiǎn)單討論錯(cuò)誤類型。橫切行為 分 為兩個(gè)主要部分:行為做什么(我稱之為橫切功能)和行為用在什么地方(我稱 之為橫切規(guī)范)。回到 ATM 的例子,橫切功能檢查調(diào)用者的安全憑證。橫切規(guī) 范 檢查 ATM 類中每一個(gè)公共方法。

為了實(shí)現(xiàn)的真正信任度,需要同時(shí)檢查功能和規(guī)范(或者不嚴(yán)格地說(shuō),建議 和 切點(diǎn))。在完成這個(gè)例子的過(guò)程中,我將強(qiáng)調(diào)給定的測(cè)試模式是驗(yàn)證橫切功能、 規(guī)范,還是兩者同時(shí)驗(yàn)證。

注意我將重點(diǎn)放在測(cè)試切點(diǎn)、建議和支持它們的代碼上。類型間聲明(和其 他 方面功能)當(dāng)然是可測(cè)試的。我在本文中展示的一些技巧稍加修改可以對(duì)它們 使用。它們還有自己的一組技巧,其中許多是很直觀的。不過(guò)為了節(jié)省篇幅,我 決定不在本文中明確地討論它們。

測(cè)試模式編目

我將本文寫(xiě)成測(cè)試面向方面代碼的模式的編目。對(duì)于每種模式,我描述了它 針 對(duì)哪種類型的錯(cuò)誤,對(duì)該模式進(jìn)行總結(jié),提供一個(gè)例子并討論該模式的優(yōu)缺點(diǎn)。 編目分為四節(jié):

測(cè)試完整的單元 :此節(jié)展示了測(cè)試完整的系統(tǒng)部分(換句話說(shuō),同時(shí)測(cè)試方 面和非方面類)的模式。這種技術(shù)是在沒(méi)有使用方面時(shí)獲得橫切行為信任度的惟 一方法,并在使用方面時(shí)仍然是一種重要的工具。

使用可視化工具 :這里描述的兩種模式利用了 AspectJ IDE 對(duì) Eclipse 的 支持,也稱為 AJDT。嚴(yán)格地講,使用可視化工具檢查應(yīng)用程序的橫切結(jié)構(gòu)不是 一 種測(cè)試技術(shù)。不過(guò),它可幫助您理解并獲得對(duì)應(yīng)用程序的橫切關(guān)注點(diǎn)的信任。

使用委派 :此節(jié)展示可以幫助將前面提到的兩類錯(cuò)誤分開(kāi)的兩種模式。通過(guò) 將一些邏輯從建議中分離到 helper 類中(或者方法中),可以編寫(xiě)與橫切規(guī)范 無(wú)關(guān)的、檢查應(yīng)用程序橫切行為的測(cè)試。

使用 mock 目標(biāo) :后一節(jié)包括三種模式,它們使用模擬真實(shí)建議目標(biāo)的 “mock 目標(biāo)”類,可以在不將方面集成到真正目標(biāo)的條件下測(cè)試聯(lián)結(jié)點(diǎn)匹配和 建 議行為。

Highlighter 方面

為了展示這個(gè)編目中的樣式,我使用了一個(gè)實(shí)現(xiàn)突出顯示搜索術(shù)語(yǔ)(即在搜 索 結(jié)果中突出顯示用戶的查詢術(shù)語(yǔ))的方面。我實(shí)現(xiàn)了與在上一例子中展示的方面 非常相像的一個(gè)方面。該系統(tǒng)要在結(jié)果匯總頁(yè)、細(xì)節(jié)頁(yè)和應(yīng)用程序的其他一些地 方中突出顯示術(shù)語(yǔ)。我在本文中展示的這個(gè)例子只橫切一個(gè)類,但是原理是一樣 的。清單 1 包含 Highlighter 方面的一個(gè)實(shí)現(xiàn):

清單 1. Highlighter 定義了突出顯示行為

public aspect Highlighter{
 /* ITDs to manage highlighted words */
 private Collection Highlightable.highlightedWords;

 public Collection Highlightable.getHighlightedWords() {
   return highlightedWords;
 }
 public void Highlightable.setHighlightedWords(Collection
   highlightedWords){
  this.highlightedWords = highlightedWords;
 }

 public pointcut highlightedTextProperties() :
   (
   execution(public String getProduct())
  || execution(public String getTitle())
  || execution(public String getSummary())
  );

 String around(Highlightable highlightable) :
   highlightedTextProperties() && this(highlightable)
 {
   String highlighted = proceed(highlightable);
  for (String word : highlightable.getHighlightedWords()) {
   Pattern pattern = patternForWord(word);
   Matcher matcher = pattern.matcher (highlighted);
   highlighted = matcher.replaceAll("      "bold">$0");
  }
     return highlighted;
 }

private Pattern patternForWord (String word) {
 return Pattern.compile("\b\Q" + word + "\E\b",
  Pattern.CASE_INSENSITIVE);
} 
}

上一頁(yè)12345下一頁(yè)
軟件測(cè)試工具 | 聯(lián)系我們 | 投訴建議 | 誠(chéng)聘英才 | 申請(qǐng)使用列表 | 網(wǎng)站地圖
滬ICP備07036474 2003-2017 版權(quán)所有 上海澤眾軟件科技有限公司 Shanghai ZeZhong Software Co.,Ltd