qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問 http://qaseven.github.io/

          分布式系統(tǒng)測(cè)試

          近半年在做分布式系統(tǒng)開發(fā)的同時(shí),也做了不少的測(cè)試工作,軟件工程教科書上描述軟件項(xiàng)目的流程,基本上都會(huì)提到單元測(cè)試、集成測(cè)試、壓力測(cè)試等名詞,但對(duì)這些詞匯一直停留在理論認(rèn)識(shí)階段。研究生階段做的項(xiàng)目,因?yàn)橐蟛桓撸旧弦矝]做什么測(cè)試工作;去年在實(shí)習(xí)的時(shí)候,因?yàn)闀r(shí)間有限,主要接觸單元測(cè)試和系統(tǒng)功能測(cè)試;直到現(xiàn)在才把這些詞匯都近距離的感受了一下。

            單元測(cè)試

             分布式系統(tǒng)的開發(fā)工作通常會(huì)被劃分成多個(gè)模塊,由不同的開發(fā)人員分別編寫程序,所以代碼的單元測(cè)試工作通常是針對(duì)單個(gè)模塊進(jìn)行的。如果模塊是獨(dú)立的,并 且功能集足夠小,單元測(cè)試是很容易做的,構(gòu)造一組case,盡量覆蓋所有的分支基本上就OK。但實(shí)際上分布式系統(tǒng)里很少有完全獨(dú)立的模塊,大部分的模塊都 會(huì)跟其他的模塊有依賴關(guān)系或是網(wǎng)絡(luò)通信等。

            對(duì)于有依賴的模塊的單元測(cè)試,理想情況下,依賴的模塊都已經(jīng)準(zhǔn)備好,并且被測(cè)試過沒有問題 (這個(gè)實(shí)際上是做不到的,而且模塊間有時(shí)還會(huì)存在相互依賴的情況),這種理想情況會(huì)嚴(yán)重影響開發(fā)效率,使得有依賴的模塊就只能串行開發(fā)測(cè)試。另外,如果依 賴的模塊在安裝、部署上需要花費(fèi)很長(zhǎng)的時(shí)間(比如是一個(gè)配置比較麻煩的server),那么每次單元測(cè)試都需要把server部署起來(lái),測(cè)試成本是很高的。

             實(shí)際單元測(cè)試的過程中,我們經(jīng)常會(huì)把依賴其他模塊的地方用簡(jiǎn)單的代碼代替,也就是做mock。最直觀的mock方式就是通過宏來(lái)控制,即如果是以 DEBUG模式運(yùn)行,執(zhí)行某段簡(jiǎn)單的代碼(mock),如果非DEBUG模式運(yùn)行,則執(zhí)行實(shí)際的代碼邏輯。比如通過下面一段代碼把“從網(wǎng)絡(luò)上獲取數(shù)據(jù)”在 DEBUG模式運(yùn)行時(shí)替換為“從本地內(nèi)存獲取數(shù)據(jù)”,那么在執(zhí)行單元測(cè)試時(shí),我們就不需要依賴網(wǎng)絡(luò)的對(duì)端來(lái)提供數(shù)據(jù),從而方便的測(cè)試代碼邏輯。而實(shí)際 fetch_data_from_network()的測(cè)試可延遲到功能測(cè)試階段。

          #ifndef DEBUG_MODE
              fetch_data_from_network();
          #else
              fetch_data_from_local_memory();
          #fi

             使用宏來(lái)控制有時(shí)會(huì)使得代碼讀起來(lái)很混亂,如果是使用C++開發(fā)(或其他面向?qū)ο缶幊陶Z(yǔ)言),更好的方式是借助多態(tài)的性質(zhì)來(lái)做mock,如下面一段代 碼,DataManager是一個(gè)負(fù)責(zé)管理數(shù)據(jù)的類,它需要從網(wǎng)絡(luò)上其他的服務(wù)里獲取數(shù)據(jù),MockDataManager是一個(gè)繼承自 DataManager的類,它從本地內(nèi)存獲取數(shù)據(jù),在測(cè)試時(shí),我們可以將DataManager的實(shí)例換成MockDataManager的實(shí)例來(lái)運(yùn)行 (必須是指針或是引用),這樣思路跟前面的思路其實(shí)是一樣的,只不過借助多態(tài),更清晰明了,需要做的事情更少。google test和google mock是開源的測(cè)試、以及mock框架,使用他們會(huì)使你的測(cè)試工作更簡(jiǎn)單,更有趣。

          class DataManager {
          public:
             DataManager();
             ~DataManager();
             virtual int fetch_data()
             {
                 fetch_data_from_network();
             }
             ...
          };

          class MockDataManager : public DataManager {
          public:
             virtual int fetch_data()
             {
                 fetch_data_from_local_memory();
             }
          };

             測(cè)試久了之后,你會(huì)發(fā)現(xiàn)測(cè)試的工作量往往跟代碼結(jié)構(gòu)的設(shè)計(jì)有很大的關(guān)系,如果代碼結(jié)構(gòu)本身毫無(wú)章法,再加進(jìn)去一堆為單元測(cè)試而寫的代碼邏輯,只會(huì)令代碼 看起來(lái)更加糟糕;如果設(shè)計(jì)之初就考慮測(cè)試需求,盡量把業(yè)務(wù)與邏輯層次分開降低模塊間依賴性,把可能需要mock測(cè)試的地方設(shè)計(jì)為虛基類等,在做測(cè)試的時(shí)候 需要做的工作就會(huì)很少,而且測(cè)試新增代碼不會(huì)打亂現(xiàn)在的代碼邏輯結(jié)構(gòu)。

          posted on 2013-05-20 10:44 順其自然EVO 閱讀(213) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 崇州市| 南昌县| 新郑市| 上杭县| 泽库县| 承德市| 仲巴县| 冕宁县| 寻乌县| 安远县| 板桥市| 肥城市| 伽师县| 建德市| 乐安县| 兴仁县| 剑川县| 鄯善县| 台南县| 汉沽区| 友谊县| 柳林县| 广饶县| 永春县| 泰来县| 崇信县| 兴宁市| 德安县| 香港| 永靖县| 桑植县| 招远市| 湟中县| 开鲁县| 白沙| 酒泉市| 灵石县| 九江县| 新化县| 平凉市| 青海省|