qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          軟件測試實驗學習筆記系列3--單元測試

          單元測試

            從軟件測試V模型,單元測試是軟件測試的基礎,四個方面看出單元測試的重要性:

            1.時間方面—系統集成節約很多的時間

            2.測試效果--單元測試是測試階段基石,能夠發現深層次的問題

            3.測試成本--單元測試階段問題容易發現

            4.產品質量--單元測試好壞影響軟件產品的質量.

            圖1:軟件測試V模型

            軟件代碼越來越多,軟件單元越來越多,單元代碼越來越復雜。現代編程語言是的單元測試自動化實現變得可能。XUnit框架是eXtreme Programming(XP) 的核心概念。

            單元測試工具的一個重要的功能就是測試自動化,測試自動化的基礎就是測試框架。最典型和最流行的單元測試是以JUnit測試框架為基礎的xUnit測試框架。

            XUnit根據語言不同可以分為:JUnit(Java),CppUnit(C++),DUnit(Delphi),NUnit(.Net),PhpUnit(PHP)

            按類型不同可以分為:JFCUnit(GUI測試),HttpUnit(對web應用訪問進行測試),JWebUnit(對HttpUnit的抽象封裝),StrutsTestCase(基于JUnit的Struts應用測試框架),HtmlUnit

            1xUnit單元測試框架

            測試軟件開發過程中必不可少的一部分,是軟件質量保證的重要手段。測試對象:代碼,需求文檔,設計文檔.代碼測試:單元測試,集成測試,系統測試和驗收測試。eXtremeProgramming—單元測試—xUnit測試框架。TDD以測試為開發中心,XP開發者大多使用開源的測試框架-xUnit家族。

            Xunit框架的主要優點是提供了一個自動測試的解決方案。自動測試概念很重要,有了自動測試,我們就可以在開發軟件項目中實施持續集成。

            1.1xUnit介紹

            KentBeck—Smalltalk Sunit—Erich Gamma-- Junit

            框架結構表現的概念--->xUnit:一些簡單的編寫測試的規則--->移植到三十多種語言中(Python,C++,.NET,Html, JavaScript ,Ruby等)

            xUnit是一個基于測試的單元測試框架,運行測試用例,反饋測試結果以及記錄測試日志的一系列基礎軟件設施。TestCase,TestSuite,TestResult,xUnit.framework.Assert,TestResult,TestListener,TestRunner.

            圖2,xUnit 測試框架

            Xunit的原則:

            先編寫測試代碼,然后編寫符合測試的代碼

            測試代碼不需要覆蓋所有的細節,但是需要覆蓋主要的功能和可能出錯的地方

            發現Bug后,首先編寫對應的測試用例,然后在進行調試

            不斷總結出現Bug的原因,對其他代碼也編寫相應的測試用例

            每次編寫完代碼后,運行所有以前的測試用例,驗證對以前的代碼的影響,并把這種影響盡早消除

            不斷維護測試代碼,保證代碼變動后能通過所有測試

            xUnit測試框架包括的4大要素:

            測試Fixtures:是一組認定為被測對象或被測程序單元測試成功的預訂條件或預期結果的設定。Fixture就是被測試的目標。

            測試集(TestSuite):一組測試用例,這些測試用例要求相同的測試Fixtures,從而保證不會出現管理的上的混亂

            測試執行:單元測試的執行-setUp()-->執行測試動作-->tearDown()

            測試斷言(Assert):實際上就是驗證被測程序在測試中的行為或狀態的一個宏或者函數,斷言失敗會引發異常,終止測試的執行。

            測試用例的編寫:初始化Fixture-->按照某個測試功能和流程對Fixture進行操作-->驗證結果是否正確-->對Fixture相關的資源進行釋放

           1.2Junit單元測試工具

            JUnit---SourceForge項目---IBMCommon Public License ---官網:www.junit.org

            ASP,C++,c#,Effel,Delphi,Perl,PHP,Python,REBOL,Smalltalk,Visual Basic。

            xUnit的目標:1.開發人員寫測試代碼,提供一個測試框架,減少重復性勞動2.創建并保留測試,將測試集中在一起,用已有的測試創建新的測試。

            Junit的好處:

            可以使測試代碼與產品代碼分開

            針對某個類的測試代碼,通過較少的改動便可以將其應用于另一個類的測試

            易于集成到測試人員的構建中,JUnit和Ant的結合實施增量開發

            Junit是公開源代碼的,可以進行二次開發

            可以方便的對JUnit進行擴展

            Junit測試編寫的原則:

            簡化測試的編寫,這種簡化包括測試框架的學習和實際測試單元的編寫

            使測試單元保持持久性

            可以利用既有的測試來編寫相關的測試

            Junit的特征:

            使用斷言方法來判斷期望值和實際值的差異,返回Boolean值

            測試驅動設備使用共同的初始化變量或實例

            測試包結構便于組織和集成運行

            支持圖形交互模式和文本交互模式

            JUnit共有7個包,核心的包就是junit.framework和junit.runner。Framework包負責整個測試對象的架構,Runner包負責測試驅動。

            JUnit有4個重要的類:TestSuite,TestCase,TestResult,TestRunner,前三個屬于Framework包,后一個類在不同的環境下是不同的。后一個類在不同的環境中是不同的,文本環境和圖形界面

            TestResult:負責收集TestCase所執行的結果,客戶可以預測的Failure和沒有預測的Error。同時負責將測試結果轉發給TestListener(該接口由TestRunner集成)進行處理

            TestRunner:客戶對象調用的起點,負責對整個測試流程進行跟蹤。能夠顯示返回的測試結果,并報告測試的進度

            TestSuite:負責包裝和運行所有的TestCase

            TestCase:客戶測試類所要繼承的類,負責測試時對客戶類進行初始化以及測試方法的調用.

            兩個重要的接口:Test,TestListener

            Test:包含兩個方法:run(),countTestCases()-->用于對測試動作特征的提取

            TestListener:addError(),addFailure(),startTest(),endTest()-->用于對測試結果的處理以及測試驅動開發的動作的特征的提取。

            Junit框架組成:TestCase(測junit.swingui.TestRunner試用例),TestSuite(測試集),TestResult(測試結果描述與記錄),TestListener(事件監聽者),TestFailure(測試失敗),AssertionFailedError.

            Junit和Eclipse的集成的處理可以參考《JUnit in Action》

            Junit的命令行處理:java junit.textui.TestRunner  xxx

            1.3JUnit實例

            1.3.1. 開發工具:

            Eclipse、JUnit、Ant

            1.3.2. 編碼實現三角形類型判斷程序:

          class Triangle{
          private double a, b, c;
          public Triangle ( double a, double b, double c ){
          this.a = a;
          this.b = b;
          this.c = c;
          }
          /*
          返回值為 1 表示是等邊三角形
          返回值為 2 表示是等腰三角形
          返回值為 3 表示是其他種類三角形
          返回值為-1 表示不能構成三角形
          */
          public int type (){
          //to be added
          }
          }

            1.3.3、基于 JUnit 設計測試用例,使得滿足如下條件

            (1)包含不能構成三角形的測試用例

            (2)包含構成等邊三角形的測試用例

            (3)包含構成等腰三角形的測試用例(提示:需要三個測試用例)

            (4)包含構成其他種類三角形的測試用例

            (5)三角形有一條邊是非正數

            4、編寫 ant 腳本驅動測試用例

            包括測試用例執行和測試報表生成

            備注:個人使用的JVM是Open JDK6.0,eclipse是3.8 Juno,JUnit使用的是4.11

           判斷三角形的java程序:

          package demo2;
          public class Triangle {
           private double a,b,c;
           public Triangle(double a,double b,double c){
            this.a =a;
            this.b =b;
            this.c =c;
           }
           /*
            * return value description:
            * 1.等邊三角形
            * 2.等腰三角形
            * 3.其他三角形
            * -1.不是三角形
            */
           public int type(){
            if(isTriangle()){
             if(a==b&&b==c){
              return 1;
             }else if(a==b||b==c||c==a){
              return 2;
             }else
              return 3;
            }
            else
             return -1;
            
           }
           //auxiliary method which is used to predicate weather three number consist of a triangle or not
           private boolean isTriangle(){
            if(Math.abs(a-b)<c&&Math.abs(a-c)<b&&Math.abs(b-c)<a 
               &&(a+b>c)&& (a+c >b)&& (b+c >a) )
             return true;
            return false;
           }
          }

            單個的測試用例:

          package demo2;
          import static org.junit.Assert.*;
          import org.junit.Test;
          public class TriangleTest {
           @Test
           public void testType(){
            Triangle triangle = new Triangle(12,12,4);
            assertEquals(2,triangle.type());
           }
          }

            參數化的測試用例:

          package demo2;
          import static org.junit.Assert.*;
          import static org.junit.Assert.assertEquals;
          import java.util.Arrays;
          import java.util.Collection;
          import org.junit.Test;
          import org.junit.runner.RunWith;
          import org.junit.runners.Parameterized;
          import org.junit.runners.Parameterized.Parameters;

          @RunWith(value = Parameterized.class)
          public class ParameterTestTriangle {
           private double expected;
           private double valueOne;
           private double valueTwo;
           private double valueThree;
           
           @Parameters
           //Double is a class type,double is a basic type.
           public static Collection<Object []> getTestParameters(){
             return Arrays.asList(new Object [][]{
              {2,12.3,13.5,13.5},
              {2,10,10,4},
              {2,34,5,34},
              {1,6.0,6.0,6.0},
              {1,23,23,23},
              {-1,1.0,4.0,9.0},
              {-1,10,3,15},
              {3,3.0,4.0,5.0},
              {3,12,24,33},
            });
           }
           
           public ParameterTestTriangle(double expected, double valueOne,
             double valueTwo,double valueThree){
            this.expected= expected;
            this.valueOne= valueOne;
            this.valueTwo= valueTwo;
            this.valueThree= valueThree; 
           }
           
           @Test
           public void testType(){
            Triangle triangle = new Triangle(valueOne,valueTwo,valueThree);
            assertSame("期待類型和測試類型不同!",(int)expected,triangle.type());
           }
          }



            結合上述的兩個測試用例的測試用例集:

          package demo2;

          import org.junit.runner.RunWith;
          import org.junit.runners.Suite;
          import org.junit.runners.Suite.SuiteClasses;

          @RunWith(value = Suite.class)
          @SuiteClasses(value={ ParameterTestTriangle.class,TriangleTest.class})
          public class TestSuite {
          }

            編寫的ant腳本如下:

          <project name ="first build.xml" default ="report">
              <target name="clean" >
                  <delete dir="dist"/>
                  <delete dir="bin/demo"/>
               <delete dir="report"/>
              </target>
              <target name="compile" depends="clean">
                  <javac srcdir="src" destdir="bin" includes="demo2/*.java" 
                   includeantruntime="true" classpath ="lib\junit.jar"/> 
              </target> 
           <target name="test" depends="compile">
            <mkdir dir="report/html"/>
               <junit printsummary="yes" haltonerror="false" haltonfailure="false" 
                   fork="yes" >
                 <formatter type="plain" usefile="false"/>
                 <formatter type="xml"/>
                 <test name="demo2.TestSuite"
                       todir="report"/>
                 <classpath>
                   <pathelement location="bin"/>   
                  <pathelement location="lib\junit.jar"/>
                 </classpath>
               </junit>
            
               <junitreport todir="report">
                 <fileset dir="report">
                   <include name="TEST*.xml"/>
                 </fileset>
                 <report format="frames" todir="report/html"/>
               </junitreport>
             </target>
             <target name="report" depends="test">
               <echo>Hello world</echo>
             </target>   
          </project>

            運行結果截圖:

            單個測試用的運行截圖

            參數化測試用例的運行截圖:

            測試用例集的運行:


           ant腳本運行

            1.首先cd 到相應的java project的目錄下 cd java project/testSoftware

            2. 輸入ant 或者ant -f build.xml

            3 參看結果:

          Buildfile: /home/xiajian/project file/java project/testSoftware/build.xml
          clean:
          [delete] Deleting directory /home/xiajian/project file/java project/testSoftware/report
          compile:
          test:
          [mkdir] Created dir: /home/xiajian/project file/java project/testSoftware/report/html
          [junit] Running demo2.TestSuite
          [junit] Testsuite: demo2.TestSuite
          [junit] Tests run: 10, Failures: 0, Errors: 0, Time elapsed: 0.097 sec
          [junit] Tests run: 10, Failures: 0, Errors: 0, Time elapsed: 0.097 sec
          [junit]
          [junit] Testcase: testType[0] took 0.002 sec
          [junit] Testcase: testType[1] took 0 sec
          [junit] Testcase: testType[2] took 0 sec
          [junit] Testcase: testType[3] took 0 sec
          [junit] Testcase: testType[4] took 0 sec
          [junit] Testcase: testType[5] took 0 sec
          [junit] Testcase: testType[6] took 0 sec
          [junit] Testcase: testType[7] took 0 sec
          [junit] Testcase: testType[8] took 0.001 sec
          [junit] Testcase: testType took 0 sec
          [junitreport] Processing /home/xiajian/project file/java project/testSoftware/report/TESTS-TestSuites.xml to /tmp/null2022323935
          [junitreport] Loading stylesheet jar:file:/usr/share/ant/lib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl
          [junitreport] Transform time: 564ms
          [junitreport] Deleting: /tmp/null2022323935
          report:
          [echo] Hello world
          BUILD SUCCESSFUL

            ant腳本在當前項目下生成了一個report文件夾,其中有相應的測試用例執行的報告

            備注:關于這里的JUnit的實例的代碼,我放到了在百度網盤上創建了一個公共鏈接,有興趣的可以研究一下,這實例位于testSoftware/src/demo2的中.網盤連接:http://pan.baidu.com/share/link?shareid=1294418402&uk=556148328

            在導入項目時可能出現的問題:

            原先我是在OpenJDK 7的環境下編寫這個測試程序的,后來從Ubuntu12.10換到Ubuntu12.04LTS后,系統安裝的JDK 是Open JDK 6,所以導入項目時出現了java.lang.UnsupportedClassVersionError: demo2/ParameterTestTriangle : Unsupported major.minor version 錯誤,百度了一下找到了問題的原因:是因為使用高版本的JDK編譯的Java class文件試圖在較低版本的JVM上運行. 解決方法:

            一定要清理干凈已經生成的文件

            替換成正確的JDK--修JDK的jre以及相的編譯器(修改的方法是右擊項目屬性build path和build compiler中修改)

            修改JRE:

            修改編譯器:

            參考資料:

            [1]軟件測試實驗指導教程/蔡建平, 清華大學出版社, 2009.11
            [2] JUnit實戰(第二版)/Peter Tahchiev等著,王魁譯, 人民郵電出版社,2012.4
            [3]軟件測試v模型的圖片來源:http://leochael.blog.163.com/blog/static/1309571200741181733167/
            [4]出現的java錯誤:http://zhidao.baidu.com/question/455404569.html

          相關文章:

          軟件測試實驗學習筆記系列2 -- lint,splint的使用

          軟件測試實驗學習筆記系列4--CppUnit

          posted on 2013-08-09 10:21 順其自然EVO 閱讀(372) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2013年8月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 兴文县| 惠安县| 岗巴县| 平昌县| 德安县| 乌恰县| 平顶山市| 扶余县| 大埔县| 两当县| 松桃| 满洲里市| 永靖县| 岑溪市| 宜都市| 甘南县| 莱西市| 栾城县| 海安县| 绵阳市| 通化市| 泊头市| 隆昌县| 富锦市| 桃江县| 娄烦县| 岳阳县| 东丰县| 偃师市| 共和县| 托克托县| 大渡口区| 探索| 宁安市| 建阳市| 会昌县| 临海市| 洪湖市| 武宁县| 霍州市| 松原市|