999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

單元測試方法在GIS開發中的應用研究

2012-12-21 01:18:08尤曉洺蔡先華
科技視界 2012年1期
關鍵詞:功能方法

尤曉洺 蔡先華

(東南大學交通學院地理信息工程系 江蘇 南京 210096)

單元測試方法在GIS開發中的應用研究

尤曉洺 蔡先華

(東南大學交通學院地理信息工程系 江蘇 南京 210096)

單元測試是在軟件測試中要進行的最低級別的測試活動,是保證軟件質量的第一環。然而由于GIS開發的一些復雜特征,很多GIS開發者放棄了編寫單元測試。本文針對GIS開發的特點,探討了GIS開發中的編寫單元測試的一些問題。包括如何在單元測試中加載第三方GIS組件許可,如何改善設計使單元測試易于編寫,如何在單元測試中和復雜組件對象交互等。通過對這些方法的應用,解決GIS開發中編寫單元測試的一些問題。

單元測試;GIS開發;NUnit

0 引言

隨著社會對GIS的需求越來越多,GIS軟件規模的不斷擴大,GIS軟件設計的復雜程度不斷提高,軟件開發中出現錯誤或缺陷的幾率也越來越大,如何保證GIS軟件的質量,使GIS軟件為社會提供穩定而且正確的服務,是一個值得研究的問題。軟件測試是驗證軟件質量的有效手段,而單元測試是保證軟件質量的第一環。然而據2008年的一份統計,超過48%的GIS開發者不編寫任何單元測試,這所導致的是他們的項目有超過50%成本都消耗在了系統維護上[1]。本文就如何在GIS開發中編寫單元測試進行討論。

1 單元測試簡介

單元測試是開發者編寫的一段可以自動執行的代碼,用于證明被測試代碼的行為和開發者所期望的一致[2]。所以單元測試應該是由程序員自己來完成的,它往往是對一個個基本的功能單元進行的測試。

舉一個簡單的例子,現在有一個編寫好的函數,函數的接受一個整型數組作為參數,返回這個數組中值最大的數??梢跃帉戇@樣一個單元測試用例:把數組{1,2,3,4}作為參數傳遞給這個函數,判斷這個函數的返回值的是否等于4,如果不是,就說明這個函數的代碼是錯誤的??梢允褂脝卧獪y試框架,如NUnit[3],編寫單元測試,斷言(Assert)這個函數在接受上述參數時的返回值為4,單元測試框架可以使這個測試和其它的單元測試自動執行,并報告哪些測試用例沒有通過。

好的單元測試測試應該是自動的、全面的、可重復的、獨立的和專業的[2]。正確的使用單元測試可以起到如下作用:驗證代碼行為;通過編寫單元測試,解除代碼中的耦合;單元測試可以作為軟件開發的文檔,它是可編譯、可運行的,與代碼同步;自動化的單元測試避免了代碼出現回歸。

本文以使用ArcGIS Engine for.Net進行GIS開發為例,使用為. Net開發而設計的自動測試框架NUnit,探討一下GIS開發中單元測試編寫的一些問題。如果使用Visual Studio進行開發,結合使用免費的TestDriven.Net Personal Version,可以非常方便快捷地在開發環境中執行和調試單元測試,幫助提高開發效率[5]。

2 在單元測試中加載第三方組件許可

在使用ArcGIS Engine中的對象(可以看作是ArcObjects的子集)時是需要加載許可的。同樣,在使用到ArcObjects的單元測試,也是需要加載許可的。單元測試不同于普通的應用程序,沒有顯式的程序入口,沒有明確的執行順序,它是被Test Runner加載并執行的,那如何在單元測試中加載許可是GIS開發中編寫單元測試所要解決的一個問題。如果只有少數幾個Test Fixture使用到了ArcObjects,可以在這些Test Fixture中標記了TestFixtureSetUp屬性的方法中加載許可,在標記了TestFixtureTearDown中卸載ArcObjects,如下:

如果有很多Text Fixture中都使用到了ArcObjects,這樣做會降低測試執行的效率,可以采用另外一種更通用的方法,在標注了SetUpFixture屬性的類中的SetUp方法加載許可,TearDown方法中卸載ArcObjects,如下:

在上述代碼中,標記了SetUp屬性的LoadLicense方法會在執行這個類AeLicenseLoader所在的命名空間中所有測試前執行,而標記了TearDown屬性的UnloadAoObjects方法會在執行完這個類所在的命名空間中所有的測試后執行。如果要為整個程序集(Assamble)提供運行許可,把類AeLicenseLoader置于全局命名空間即可,這樣在執行這個程序集任何測試前,會加載許可,執行完測試后,卸載ArcObjects。

3 優化設計使便于測試

有時候會發現很難對一些功能代碼編寫單元測試,這往往暗示著設計需要修改,不應該放棄編寫單元測試,需要做的是修改設計,分離代碼的關注點,直到代碼易于測試。易于測試的代碼往往有更好的結構和可維護性[2]。

例如有些程序員習慣將業務邏輯的代碼混雜在用戶界面的代碼中,這本身并不是一種優秀的設計,也使單元測試編寫起來變得非常困難。應該將業務邏輯的代碼和用戶界面的代碼進行分離,使用諸如三層架構(表示層、業務邏輯層和數據訪問層三層架構)或MVC(模型、視圖和控制器)模式等方法對代碼進行重構。這樣既改善了設計,也使單元測試的編寫變得容易。類似的,要避免編寫出職能過多的類,這樣的類不僅很難測試,也很難維護,是違背面向對象設計的原則的,應用一些模式,改善設計,使之易于測試。也可以通過實踐驅動測試開發,改善代碼的設計。

4 在單元測試中和復雜對象交互

然而ArcObjects是一個龐大而且復雜的系統,ArcObjects中的很多對象甚至是很難構建的,如果在功能代碼中使用到這些對象,真的需要為了編寫單元測試而構建這些對象嗎?

首先需要注意的是單元測試所測試的目標。編寫的單元測試是要測試自己編寫的功能代碼,而不是ESRI的ArcObjects。比如對一個面的緩沖區操作,對兩個幾何對象求交,或者是修改了Geodatabase中的一個要素的屬性值,這些類似的代碼只是對ArcObjects的簡單調用,如果對這些代碼的行為不確定,需要做的是參考ArcObjects的幫助文檔,當然如果對這些代碼的行為還是不確定,也可以編寫單元測試進行驗證,但是這樣做的代價往往會很高。

如果確定了ArcObjects對象的行為,要測試和ArcObjects中復雜對象進行交互的功能代碼時,我們可以使用Mock對象的技術[6],對功能模塊進行測試。這種測試方法的思想是用模擬的對象替代真實的對象,模擬出一個測試環境,對功能代碼進行測試,Mock對象就是真實對象在調試期的替代品。而且由于ArcObjects是基于接口的架構,正適合使用這種技術。可以自己編寫Mock對象,也可以使用現有的Mock對象框架,如NMock2、DotNetMock和RhinoMocks。

ArcObjects中一個經常到對象的類型是Feature類,而它的對象又是很難用代碼從頭構建的。下文中的CountyFeature類就使用到了表示一個縣域要素的對象,它對一個縣域要素進行了強類型化的封裝。部分代碼如下:

CountyFeature類的構造方法接受一個表示縣域要素的參數,縣域要素有一個字段的值是該縣域的政區代碼,這個代碼是符合中華人民共和國行政區劃代碼標準(GB2260-1995)的。根據這個縣域的政區代碼可以判斷這個要素是否是省直轄縣級市,CountyFeature類的一個屬性就實現了這個功能,它返回該縣域是否是省直轄縣級市?,F在編寫單元測試對這個功能代碼進行測試。那么就需要實例化CountyFeature類的對象,而CountyFeature類的構造方法需要一個IFeature類型的縣域要素作為參數。編寫測試時需要這個參數,獲得這個參數可以使用真實的數據,也就是說,使用包含縣域要素類的Geodatabase,假設這個數據是容易獲取的,但是仍然需要在單元測試代碼中編寫許多根本不是這個測試所需要關注的代碼,而且由于這些代碼訪問外部資源,測試運行的速度也會變慢,所以不應該使用這種方法。

使用Mock對象就可以解決上述這個問題。判斷這個縣域是否是省直轄縣級市的功能代碼關注的只是縣域要素區域政區代碼字段的值,所以可以編寫一個帶有政區代碼的仿真縣域要素的對象,其他至于縣域要素到底有沒有其它字段等都不是這個測試所關心的內容。IFeature接口有9個屬性,4個方法,如果自己編寫這個Mock對象的話同樣會浪費很多時間,解決方法就是使用動態Mock對象,動態Mock對象會在運行時構建一個指定類型的 Mock對象。本文以NMock2中的動態Mock對象為例,編寫的對上述功能的測試代碼如下:

測試方法的第三行代碼表示,使當以指定參數調用 feature.get_Value方法時,返回regionCode的值。上述測試代碼隔離了和測試目標無關的內容,使測試專注于需要測試的功能。

Mock對象是一項很實用的技術,但由于需要編寫更多的代碼,特別是自己編寫Mock對象,無疑會加重項目的負擔,有時我們可以通過一些重構消除對Mock對象的依賴。

盡管使用了如上所述的方法,但在GIS開發中還是不可避免地需要使用到一些復雜的對象。典型的例子是ArcObjects中的幾何數據類型。例如需要自己實現兩個多邊形求交的功能,那么如何對這個功能進行測試。在測試代碼中需要構建兩個多邊形對象,還有這兩個多邊形求交后的正確結果,然后將真實的求交結果和正確望的結果進行比較,如果不相同,就說明我自己實現的這個功能是錯誤的。按照單元測試應該是全面的原則,需要編寫多個測試用例。對于那些簡單的多邊形對象,可以編寫代碼進行構建(新建一個多邊形對象,定義它的空間參考和所有節點)。如果是復雜的多邊形對象,這種方法會給編寫單元測試帶來較大的負擔,我們可以從一個文件中(如Shapefile)讀取一個多邊形,但是這樣做會牽扯到更多的與測試不相關的對象(如工作空間,要素類等對象),降低了單元測試編寫和執行的效率。ArcObjects中有個IXMLSerialize接口,ArcObjects中有超過340個類實現了這個接口,其中也包括幾何數據類,實現了這個接口的類,可以將這些類的對象序列化為xml,也可以從xml中構建這些對象??梢允褂眠@個功能在編寫單元測試時從xml中構建一些復雜的對象。一個名為ArcUnit的開源項目,實現了一個ArcMap的工具擴展,它可以將選中要素的Shape保存成xml文件,方便在編寫單元測試時構建復雜的幾何對象[7]。

5 結論

編寫單元測試本身是需要時間的,但是從長遠角度來看,單元測試對提高團隊開發的效率和軟件質量都有較大的作用,同時還能改善設計,提升bug修復的效率。因此,很有必要在GIS開發中編寫單元測試。在發現很難對一些功能代碼編寫單元測試時,優先考慮改善設計,再考慮使用Mock對象等其他技術方法,編寫單元測試。解決了GIS開發中編寫單元測試這些細節問題,實踐測試驅動開發,以單元測試作為開發過程的開端并且將測試引入到系統開發的全過程,保證了代碼的階段正確性,避免了沒有單元測試的GIS開發中后期集中測試產生問題時的舉步維艱,同時單元測試代碼這份可以運行的文檔可以指導其他開發者如何使用相應的功能代碼。

[1]Dave Bouwman.Developer Survey[EB/OL].http://blog.davebouwman.com/2008/ 06/04/developer-survey-unit-testing-other-tools/,2008.

[2]Andy Hunt,Dave Thomas,Matt Hargett.Pragmatic Unit Testing in C#with Nunit,Second Edition[M].The Pragmatic Bookshelf,2007.

[3]NUnit.org.NUnit Documentation[EB/OL].http://www.nuint.org/.

[4]NCover LLC[EB/OL].http://www.ncover.com/.

[5]TestDriven.Net.Quickstart[EB/OL].http://www.testdriven.net/quickstart.aspx.

[6]Roy Osherove.The Art of Unit Testing with Examples in.NET[M].Greenwich:Manning,2009.

[7]Brian Noyle,David Bouwman.Unit Testing for Esri Developers[J].ArcUser,2010,Winter:38-41.

王靜]

猜你喜歡
功能方法
也談詩的“功能”
中華詩詞(2022年6期)2022-12-31 06:41:24
學習方法
關于非首都功能疏解的幾點思考
懷孕了,凝血功能怎么變?
媽媽寶寶(2017年2期)2017-02-21 01:21:24
“簡直”和“幾乎”的表達功能
用對方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
賺錢方法
捕魚
中西醫結合治療甲狀腺功能亢進癥31例
主站蜘蛛池模板: 国产永久无码观看在线| 日韩欧美高清视频| 午夜a级毛片| 波多野结衣视频网站| 亚洲 欧美 偷自乱 图片| 亚洲成a∧人片在线观看无码| 青青青伊人色综合久久| 制服丝袜国产精品| 国内精品久久人妻无码大片高| 国产91熟女高潮一区二区| 精品国产免费第一区二区三区日韩| 中文字幕在线播放不卡| 日本a级免费| 美女被躁出白浆视频播放| 日韩毛片视频| 久久黄色免费电影| 综合天天色| 欧美中文一区| 青青草a国产免费观看| 香蕉伊思人视频| 亚洲日本中文字幕乱码中文| 黄色网页在线播放| 成人欧美在线观看| 狠狠亚洲婷婷综合色香| 免费亚洲成人| 毛片视频网| 国产成人精品第一区二区| 日韩av资源在线| 亚洲精品成人7777在线观看| 不卡午夜视频| 在线观看国产精品日本不卡网| 色综合久久88| 欧美一区日韩一区中文字幕页| 国产在线观看人成激情视频| 免费看黄片一区二区三区| 女高中生自慰污污网站| 国产成人高清在线精品| 成人在线观看不卡| 欧美精品亚洲精品日韩专| 亚洲AⅤ无码国产精品| 亚洲精品免费网站| a级毛片免费在线观看| 国产成人av一区二区三区| 亚洲成a人片7777| 国产色网站| 亚洲福利片无码最新在线播放| 亚洲成人免费在线| 国产国语一级毛片| 国产中文一区a级毛片视频| 午夜欧美在线| 欧美在线一二区| 亚洲第一综合天堂另类专| 2021国产精品自拍| 久久精品只有这里有| 亚洲av无码成人专区| 亚洲欧美成人网| 国产黄在线免费观看| 91久久青青草原精品国产| 国产日本欧美亚洲精品视| 日本亚洲欧美在线| 欧美一区二区三区香蕉视| 99免费在线观看视频| 久久人妻xunleige无码| 特级aaaaaaaaa毛片免费视频| 亚洲国产欧美目韩成人综合| 自拍亚洲欧美精品| 最近最新中文字幕在线第一页| 精品剧情v国产在线观看| 日韩精品成人在线| 在线视频一区二区三区不卡| 国产无吗一区二区三区在线欢| 日韩欧美网址| 国产黑丝视频在线观看| 国产精品女熟高潮视频| 一级成人a毛片免费播放| 极品国产一区二区三区| 精品一区国产精品| a级毛片免费网站| 国产凹凸一区在线观看视频| 永久天堂网Av| 国产三级毛片| 国产综合在线观看视频|