摘要
在測試自動化中,測試代碼中不僅僅包含測試邏輯,還包含許多其他代碼,比如URL拼接、html/xml解析、訪問UI控件,等等。若把測試邏輯與這些無關代碼混在一起,測試邏輯將會很難理解,也不容易維護。本文會介紹如何用分層結構來解決測試自動化中遇到的這些問題。在這個分層結構中,測試自動化代碼會被分成三層:(1)測試用例層,表達應用程序的測試邏輯。(2)領域層,用業務領域術語來給待測系統建模,封裝HTTP請求、瀏覽器控制、結果解析邏輯等,給測試用例層提供一個接口。(3)待測系統層,第2層構建在這一層之上。
問題
QA的工作包括設計測試用例、探索性測試(exploratory testing)及回歸測試,等等。這些工作有的依靠QA的聰明才智, 而有的卻只是重復勞動(例如回歸測試)。隨著系統中不斷地加入新功能,回歸測試這類工作耗費的時間也越來越多。
測試自動化可以解決這個問題。測試自動化后,重復性的勞動會由計算機來做,而測試用例都用計算機程序來表述, 因此QA可以從重復勞動中解脫出來,有更多的時間用在創造性的工作上來。
在測試自動化中,測試代碼并不僅僅包含測試邏輯,也包含許多其他的支撐代碼,例如URL拼接、HTML/XML解析、UI控件訪問等。 例如要測試一個能接受不同搜索參數,并返回包含特定信息的XML(例如用戶數據)的web服務,測試代碼需要:
1. 根據待測操作拼接URL
2. 使用HTTP庫發起HTTP請求
3. 讀取web服務器返回的信息,并解析數據
4. 對比返回的數據與期望數據
解決方法
軟件開發領域曾遇到過同樣的問題,并找到了解決方法,即‘層次結構’(Layered Architecture)。引用《領域驅動設計--軟件核心復雜性應對之道》('Domain-driven design: tackling complexity in the heart of software')一書:
“分層結構的價值在于每一層只關注于程序的特定方面。這使得每個方面的設計都很緊湊,也更容易理解。當然,使用層次結構的最重要原因是把各個重要的方面都分隔開。“
雖然測試自動化領域關注的是測試領域,但是所遇到的問題的本質卻是一樣的,因此可以應用相似的解決方案:
測試用例層包含許多測試用例。這些測試用例都是基于領域層的。領域層用領域語言封裝了待測系統。
領域層直接訪問待測系統。
例子
假設我們要測試一個restful web服務。通過這個web服務,我們可以用電話作為關鍵字搜索客戶信息。
要調用這個web服務,需要發起以下格式的HTTP請求:
http://{endpoint}/subscribers?telephoneNumber={telephoneNumber}
服務端返回的以豎線分割的數據包含客戶的姓名、電話、地址及其他信息:
13120205504|ST|C|SQ|112|||FIRST|ST|W|Riverfront|BC|010|68930432|
測試這個服務的用例為:(1)用能精確匹配一個用戶的電話作為關鍵字搜索,(2)用能精確匹配多個用戶的電話作為關鍵字搜索,(3)用 不完整電話作為關鍵字搜索等。用例的完整程度完全取決于QA的想象能力。
對于每個測試用例,執行的數據基本上都一樣:(1)拼裝包含電話號碼關鍵字的URL,(2)用HTTP庫發出HTTP GET請求,(3)解析數據, (4)把真實值與期望值做比較。為了避免上面提到的問題,我們在這里采用分層結構:
測試用例層
這一層的具體實現方式與采用的測試框架有關。在這個例子中,我們采用C#及NBehave。
[Story]
public class SearchCustomerbyTelephoneNumberStory: TestBase
{
[Scenario]
public void SearchWithAPhoneNumberWhichHasAnExactMatch()
{
story.WithScenario("Search with a phone number which has a exact match")
.Given(AN_ACCOUNT_WITH_PHONE_NUMBER, "01068930432", EMPTY_ACTION)
.When(SEARCH_WITH, "01068930432",
SEARCH_WITH_ACTION)
.Then(ACCOUNT_INFORMATION_SHOULD_BE_RETURNED, "13120205504",
原文轉自:http://www.uml.org.cn/Test/200911196.asp