• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    讓軟件改進過程實現自動化

    發布: 2007-4-22 19:34 | 作者: Joe Walk…  | 來源: 賽迪     | 查看: 37次 | 進入軟件測試論壇討論

    領測軟件測試網


    顧愷翻譯 

    概要

    幾年前每個人都被Quality 軟件的問題所困擾。Quality 中的Q 之所以大寫就是為了強調單詞的重要性。引入了消耗幾個小時的程序和檢查過程、以及大量的文書工作,就是為了設法減少軟件的故障率。就是前不久,這種趨勢已經演變為更為輕便的處理過程,該過程使用了輕便的軟件和極端編程。這仍然是一個積極的轉變因為保證軟件品質仍然是重要的。有些分析家估計:有60%的軟件故障可自動檢測出來。那么我們能做的就是在昨天的質量裝置恐龍和今天的困惑之間建一座橋梁,以便讓問題解決的又快又代價低?作者Joe Walker 測試了不同類型的故障和七種工具以幫助你揭示他們的真面目。

    有許多免費工具可以輕而易舉的報告你的代碼有什么故障,然后幫助你改進代碼的質量。而且因為故障常常是主觀方面的,大部分工具可以配置以適合你的本地代碼類型。

    但是一開始你就有減少故障的義務。這聽起來好像是一個簡單的問題——肯定對于每個人來說軟件質量必須擺在第一位。但是,花費最少時間來修改代碼往往看起來更加合理一些。任何保存壽命短的軟件應該編輯的盡可能少,而且編寫沒有人閱讀的單行文檔也是毫無意義的。我在想有多少塊文檔花費在編寫和檢查方面的時間比某人閱讀他們節省的時間多呢?因此,我們的目的就是把值得我們提高作品質量的工作和浪費資源的工作區別開來。

    你想在提高代碼質量方面走多遠?

    存在以下幾種故障種類。我給出的工具在它們攻擊的故障類型方面有區別。我根據他們的嚴重性確定了四種不同的故障類,從困擾用戶的普通故障到阻止代碼重新使用的有組織的故障都有:

    ·Current bugs: 當前故障阻止軟件的正確運行。它們困擾用戶并且可(或者應該)通過你的軟件測試顯示出來。當前故障與潛在故障截然不同。

    ·Latent bugs: 這些故障當前不產生問題。但是它們潛伏著,在以后才出現。阿里安5號火箭的失敗就是由于一個浮點到整數轉換錯誤引起的,當前面的火箭速度較慢時處于睡眠期;但是速度較快的阿里安 5卻觸發了這個問題。千年病毒也是一個潛伏故障的例子,只有當環境改變時它才浮出水面。使用傳統的測試方法測試潛伏病毒要困難得多,并且找到他們就需要具有遠見的人詢問:“什么改變才能讓故障從黑暗中走出來?

    ·Accident-waiting-to-happen bugs: 代碼可以既簡單又安全,或者他也可以是一團糟,等著絆倒那些對他們的編輯結果想得不多的可憐的程序員。一般而言,代碼越老,就越有可能出現明顯生銹的刀口;并且某些工業證據也表明:長時間沒有重構的代碼一般七年之后也就不再需要重新編寫了。

    ·Poorly organized bugs: 組織不好的代碼不容易重新使用并且常常包含對代碼的過多依賴,其實有些是不必要的。因此它更有可能受其他代碼位中的故障影響。編碼標準致力于解決這種類型的問題,但是編碼標準不能完全解決問題。他們不能停止問題如循環的依賴性,它使得你毫無機會來維持可重新使用的代碼。

    這些問題根據他們的嚴重性組織的比較粗糙。當前故障一般比潛伏故障更難以解決,而潛伏故障依次的比等待發生的故障或者組織故障更加令人擔心。

    下列代碼包含了上述四種故障案例。認出它們后獎勵一下你自己:

    
    1: public static void main(String[] args)
    2: {
    3:     System.out.println(toUpperCase('q'));
    4: }
    5:
    6: private static char toUpperCase(char main)
    7: {
    8:     return (char) (main - 31);
    9: }
    

    這里有一個當前故障因為行8應該讀。


    這種簡單問題不解決,程序也不會運轉。與其辛苦計算出q的大寫字母為Q,還不如設法勸說我們相信答案就是R。

    這里有一個潛伏故障因為遲早有人會設法得到ß 或者某數的大寫版本,而不是任何明智的東西。

    一個小小的等待發生事故的故障是由于行6中的某些傻變量名引起的。main 并沒有真正的描述什么正在進行,而且還用方法名來迷惑我們。更好的代碼如下:

    如果該代碼描述了為什么她要從小寫字母盤上的字符減去32,那么它會安全的多。

    最后如果你將toUpperCase()方法變為公用的,并為方便其他類的使用將它變為實際類——甚至你可以使用下面的標準Sun微系統提供的方法,那么代碼就組織得更好一些:



    你想在哪里止?

    你什么時候停止調整和提高你的代碼呢?這個問題沒有一個真正的答案;這取決于你和你的項目。商業項目常常只關注于ROI (投資回報),因此它主要解決當前故障,并且通過實現編碼標準解決這個問題很容易。

    我們常?吹缴虡I項目無意中采取了某些步驟來阻止潛伏故障的解決,它們實現了一個嚴格的變化控制程序,該程序將代碼修改與產生的故障聯系在一起來幫助測試。要開發隊伍足夠忠誠于軟件品質,以致于關心某人的軟件而且不設置障礙,這實在是太難了。

    在更具有啟迪性的開發環境里,大家都承認重構是創造高品質軟件的至關重要的組成部分。重構就是逐步穩固你代碼的組織以避免等待發生事故的過程。

    但是即使是最關注品質的開發者也有他們的限制。你真的關心你注釋中的標點符號嗎?或者你真的關心方法是否是以最合理的順序聲明的嗎?

    Reasoning Inc.最近研究了不同商業和開源項目的品質,并據此發表大字標題。該公司針對不同的商業選擇分析了Linux TCP/IP堆棧的源代碼、Apache Web服務器、和Tomcat 。有趣的是, Reasoning公司還運行了下面描述的免費工具版本,然后手工分析結果以刪除錯誤證據。他的結果出現了一些異常,但是它表明:開源關注于品質由此產生的回報比品質軟件本身產生的回報明顯要大得多。

    我鑒別的七種工具可幫助顯示故障,他們與Reasoning 公司的方法類似,并且在某些情況下也能幫助解決這些故障。我還將這些工具用于我最近的項目之一:DocTree。 DocTree 產生一個動態的裝載Webpage,它包含到一萬個類的Java文檔的深度鏈接,這些類來自于許多重要的Java軟件項目。DocTree不是一個很大的項目,但是它足夠成為這七種工具的有用的測試案例。該資源可從java.net (見 Resources)處下載,所以你可以利用Ant看到這些工具是如何在同一個基礎上運行。 有幾個工具有繪圖用戶界面(GUIs)。但是,把它們當作你的構造過程(如,從一個Ant構造腳本)的一部分來運行可能更有意義。運行這些工具花的時間越少,繼續提高你的軟件就越有可能。

    使用工具如CruiseControl、 Anthill是相當容易的,或者甚至是使用簡單的cron 每晚寄出當作電子郵件給予你結果的構造,也是相當容易的。在建立了這樣一個程序后,它就比GUI容易使用。

    讓我們看看這七種工具:

    ·FindBugs

    ·PMD/CPD

    ·Checkstyle

    ·Jalopy/Jacobe

    ·JDepend

    ·JUnit

    ·Eclipse

    FindBugs

    FindBugs主要解決當前和潛伏故障。它尋找普通問題和常常顯示某處出錯的小處代碼。

    FindBugs顯示的一些故障案例包括:

    ·返回不穩定靜態數據的方法

    ·Get方法不同步的地方顯示Get方法;set方法同步的地方顯示set方法

    ·Iterator類定義過程中出現的問題

    ·無意義的控制流程語句

    ·存在NullPointerException的地方;引用值與Null的多余比較的地方

    FindBugs 處于非;钴S的開發中,并且你可以擴展它,通過插入機制將自定義檢查包括進來。

    FindBugs在DocTree找到了一個相當嚴重的潛伏故障:一個類定義了equals(),但沒有定義hashcode()。這在當前配置中不會引起任何問題。但是,如果以后在DocTree迭代中,使用了Hashtable 或者HashMap中的類,就會出現假的結果。FindBugs也找到了一些次要的潛伏故障如異常上的信息流一直沒有關閉直到出現碎片整理和其他次要問題。隨著顯示的問題的增長,你軟件上的故障數就會減少。

    FindBugs使用字節碼分析來生成他的故障報告。

    下面是創建FindBugs 報告的Ant 目標的DocTree項目片段:



    PMD/CPD

    PMD是非?勺远x的,并能找出這四種故障類的問題。但是,他最擅長于尋找組織故障和事故等待發生的故障。與FindBugs不同,PMD使用源代碼分析,與編譯器工作方式類似,除了它生成故障報告而不是字節碼之外。PMD 是我為這篇文章測試的最可自定義的工具之一,主要是因為她有一個很酷的特征:允許你使用XPath引擎訪問源代碼解析器的輸出。這個解析器產生一棵樹,樹中的節點屬于你程序的一部分。所以一個類節點將包含用于每個變量和方法的字節點。方法節點也會包含用于該方法內的語句的字節點。如果他是一篇使用XPath的XML文檔,PMD允許你訪問這棵樹。

    所以一旦你理解了XPath和關于解析器如何從你的源代碼中生成節點樹的一些基本概念,你就能輕而易舉的添加新的法則。例如:來自PMD文檔的下列表達式演示了如何檢查當語句是否使用了波形括號:

    它將尋找樹(//)中任何地方沒有包含Block(用于某些波形括號的解析器術語)的當語句。

    PMD檢測的問題案例有:

    ·空塊

    ·為方法計算的過多的參數。

    ·過長的類或者過長的輸入清單

    ·不能使用的域,方法和變量

    ·壞掉的雙檢查鎖定

    這些檢查中有些是很主觀的。個人最好封裝的組件就是它過長的類。所以,感謝你能配置PMD來檢查你認為重要的問題。當你第一次使用PMD來檢查更大的項目時跳躍式檢查尤為重要。如果你一開始運行的檢查為空,PMD將生成七年的解決價值,所以從更加重要的檢查開始很有好處。

    CPD (復制/粘貼 檢測器)是檢測項目內的復制和粘貼代碼的相關設備。大量的復制代碼顯示出:開發者不使用繼承或者創建庫就可以找出類似的代碼和復制的任何東西、故障等等。

    來自DocTree 項目的PMD Ant 目標看起來如下:



    Checkstyle

    Checkstyle 與PMD相當相似,盡管它在尋找組織故障方面更為出色。與 PMD一樣,它使用編譯器前端來生成他的故障報告。PMD提供更廣泛的范圍內的更多檢查。但是,Checkstyle是更可配置的。雖然某些檢查會交迭,但Checkstyle的檢查中有許多不在PMD內,反之亦然。對大部分來說只要擁有他們中的一個便以足夠。

    Checkstyle 可尋找:

    ·不能使用的或者多余的輸入

    ·空格更好的地方不使用跳格符,反之亦然

    ·不遵循命名標準的變量、方法或者類

    ·過分復雜的分配或者返回語句

    來自DocTree的Checkstyle Ant目標如下:



    Jalopy/Jacobe

    Jalopy和Jacobe是幫助解決事故等待發生故障和組織故障的代碼格式程序。Jalopy是開源,但是他沒有出現在活躍的開發中。Jacobe 可免費使用,但不是開源。

    記住使用任何代碼格式程序可嚴重的毀壞你使用源代碼控制系統揭示某些代碼后的歷史紀錄的功能。當引入故障時使用源代碼控制系統分析發生的變化是很普通的。但是,源代碼格式程序的普遍使用不必作任何實際修改就能夠改變你項目中的源代碼行的重要率。如果你需要重新格式化你項目的源代碼,你應該盡可能早的完成,盡管接受它你不能夠追蹤重新格式化之前的修改,或者當該代碼由于某些其他原因需要編輯的時候,逐步重新格式化。

    JDepend

    JDepend在你的源代碼周圍生成了無數個度量,包括來自于主序列的傳入和傳出的耦合和分配。不幸的是,據我的經驗,這些度量常常是毫無意義的,除非你已經理解了你正在測試的代碼;并且如果你理解了,他也只告訴你你已經知道的東西,但是,JDepend對于識別循環依賴性特別有用。循環依賴性是組織故障,它可引起維護問題和產生不能重新使用的代碼。

    例如:如果你有三個軟件包A, B和C,并且 A依賴于B, B依賴于C, 而且C 依賴于 A,那么如果不都得到你就不可能重新使用他們。如果這些軟件包中任何一個使用了GUI代碼,那么當你不注意的下載了GUI代碼到你的企業JavaBeans (EJB)或者 servlet中,即使你感興趣的代碼不是GUI代碼,那么你就會想為什么你的服務器代碼快要死了。

    來自于DocTree 的JDepend Ant 目標看起來如下:



    JUnit

    JUnit是大家熟知的工具,它可幫助你為你的軟件編寫自動的單元測試;我這里不想詳細討論它為什么那么有名。想了解更多信息請看Resources 。我想說在本文提到的所有工具中,JUnit 最有可能幫助你找出你代碼中的故障,盡管要付出代價。JUnit需要你花費相當多的時間為你的代碼編寫測試案例,但是很有可能這個時間花得很值。

    Eclipse

    IDEs 總是一個使人激動的話題。當你考慮免費工具時,Eclipse有幾種可集成到編譯器上的檢測工具如 FindBugs ,并且正在開發中的第3 版本包含了更多這種檢測。Eclipse 海配送一個代碼格式程序,他雖然不如Jalopy 或者Jacobe高級,但是更加可行因為它可以裝在編輯器內。

    Eclipse 編譯器在當前和即將上市的版本中執行的高級檢測包括:

    ·意外的boolean賦值 (e.g., if (a = b))

    ·不能到達的捕捉塊

    ·隱藏字段或者變量的局部變量聲明

    ·不能使用的變量、輸入、字段和給出的聲明

    項目集成

    將你的項目與jar和配置文件集成而且不使你的項目過大或者迷惑 jar文件,這是一個挑戰。如果你的代碼倉庫包含許多項目,你恰好想將這些工具用在這些項目上,那么你將面臨某些倉庫嚴重膨脹的危險。

    我建議你建立一個包含你想使用的工具的獨立項目,然后從你的Ant 構造文件中引用他們。這樣就不出現在想要使用工具的隊組成員中分配工具的問題。對于那些不需要使用工具的成員來說他們是可選的,并且他們不會占據倉庫太多的空間。

    故障解決

    自動品質檢測可減少你軟件中故障數,從而增強它的品質和可持續性。在你安裝了工具之后,你可以用非常小的代價——時間和金錢都是——來維護質量控制。在實現本文列出的任何策略之前,明白的定義你對于不同等級的品質有多看重以及消除某種故障有多值得,這是很重要的。這種分析對于不同的項目將產生不同的結果。好消息是調試工具將你從沉重的基礎工作中解救出來,并且允許你自主地安排他們的使用和你管理軟件品質的方法。

    
    <target name="web.jdepend" depends="jar">
      <mkdir dir="${target.temp}/jdepend"/>
      <mkdir dir="${target.web}/jdepend"/>
      <jdepend format="xml" fork="yes"
          outputfile="${target.temp}/jdepend/jdepend-report.xml">
        <sourcespath>
          <pathelement path="${source.java}/main"/>
        </sourcespath>
        <classpath>
          <dirset dir="${target.classes}"/>
          <fileset dir="${source.jar}" includes="**/*.jar"/>
          <fileset dir="${support.tools}/jdepend24" includes="**/*.jar"/>
        </classpath>
      </jdepend>
      <style
          basedir="${target.temp}/jdepend"
          destdir="${target.web}/jdepend"
          includes="jdepend-report.xml"
          style="${support.tools}/jdepend26/jdepend.xsl"/>
    </target>
    

    
    <target name="web.checkstyle">
      <mkdir dir="${target.temp}/checkstyle"/>
      <mkdir dir="${target.web}/checkstyle"/>
      <taskdef resource="checkstyletask.properties">
        <classpath>
          <fileset dir="${support.tools}/checkstyle31"
              includes="**/*.jar"/>
        </classpath>
      </taskdef>
      <copy file="${support.tools}/checkstyle31/custom.xml"
          overwrite="true"
          tofile="${target.temp}/checkstyle/custom.xml">
        <filterset>
          <filter token="source.java"
              value="${basedir}/${source.java}"/>
          <filter token="target.checkstyle"
              value="${basedir}/${target.temp}/checkstyle"/>
        </filterset>
      </copy>
      <checkstyle config="${target.temp}/checkstyle/custom.xml"
          failOnViolation="false">
        <fileset dir="${source.java}/main"
            includes="**/*.java"/>
        <formatter type="plain"/>
        <formatter type="xml"
            toFile="${target.temp}/checkstyle/checkstyle_errors.xml"/>
      </checkstyle>
      <style
          basedir="${target.temp}/checkstyle"
          destdir="${target.web}/checkstyle"
          includes="checkstyle_errors.xml"
          style="${support.tools}/checkstyle31/checkstyle-noframes.xsl"/>
    </target>
    

    
    <target name="web.pmd">
      <taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask">
        <classpath>
          <fileset dir="${support.tools}/pmd121" includes="**/*.jar"/>
        </classpath>
      </taskdef>
      <mkdir dir="${target.web}/pmd"/>
      <pmd rulesetfiles="${basedir}/${support.tools}/pmd121/ruleset.xml"
          shortFilenames="true">
        <formatter type="html" toFile="${target.web}/pmd/index.html"/>
        <fileset dir="${source.java}/main" includes="**/*.java"/>
      </pmd>
    </target>
    

    
    //WhileStatement[not(Statement/Block)]
    

    
    <target name="web.findbugs" depends="jar">
    <mkdir dir="${target.web}/findbugs"/>
    <taskdef name="findbugs"
        classname="edu.umd.cs.findbugs.anttask.FindBugsTask">
      <classpath>
        <fileset dir="${support.tools}/findbugs066"
            includes="**/*.jar"/>
      </classpath>
    </taskdef>
    <findbugs home="${support.tools}/findbugs066"
        output="text"
        outputFile="${target.web}/findbugs/report.txt"
        reportLevel="low" sort="text">
      <class location="${target.jar}/${ant.project.name}.jar"/>
      <sourcePath path="${source.java}/main"/>
    </findbugs>
    </target>
    

    
    3: System.out.println(Character.toUpperCase('q'));
    

    
    6: private static char toUpperCase(char lower)
    

    
    8: return (char) (main - 32);
    

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>