qileilove

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

          軟件測(cè)試實(shí)驗(yàn)學(xué)習(xí)筆記系列3--單元測(cè)試

          單元測(cè)試

            從軟件測(cè)試V模型,單元測(cè)試是軟件測(cè)試的基礎(chǔ),四個(gè)方面看出單元測(cè)試的重要性:

            1.時(shí)間方面—系統(tǒng)集成節(jié)約很多的時(shí)間

            2.測(cè)試效果--單元測(cè)試是測(cè)試階段基石,能夠發(fā)現(xiàn)深層次的問題

            3.測(cè)試成本--單元測(cè)試階段問題容易發(fā)現(xiàn)

            4.產(chǎn)品質(zhì)量--單元測(cè)試好壞影響軟件產(chǎn)品的質(zhì)量.

            圖1:軟件測(cè)試V模型

            軟件代碼越來越多,軟件單元越來越多,單元代碼越來越復(fù)雜?,F(xiàn)代編程語言是的單元測(cè)試自動(dòng)化實(shí)現(xiàn)變得可能。XUnit框架是eXtreme Programming(XP) 的核心概念。

            單元測(cè)試工具的一個(gè)重要的功能就是測(cè)試自動(dòng)化,測(cè)試自動(dòng)化的基礎(chǔ)就是測(cè)試框架。最典型和最流行的單元測(cè)試是以JUnit測(cè)試框架為基礎(chǔ)的xUnit測(cè)試框架。

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

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

            1xUnit單元測(cè)試框架

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

            Xunit框架的主要優(yōu)點(diǎn)是提供了一個(gè)自動(dòng)測(cè)試的解決方案。自動(dòng)測(cè)試概念很重要,有了自動(dòng)測(cè)試,我們就可以在開發(fā)軟件項(xiàng)目中實(shí)施持續(xù)集成。

            1.1xUnit介紹

            KentBeck—Smalltalk Sunit—Erich Gamma-- Junit

            框架結(jié)構(gòu)表現(xiàn)的概念--->xUnit:一些簡(jiǎn)單的編寫測(cè)試的規(guī)則--->移植到三十多種語言中(Python,C++,.NET,Html, JavaScript ,Ruby等)

            xUnit是一個(gè)基于測(cè)試的單元測(cè)試框架,運(yùn)行測(cè)試用例,反饋測(cè)試結(jié)果以及記錄測(cè)試日志的一系列基礎(chǔ)軟件設(shè)施。TestCase,TestSuite,TestResult,xUnit.framework.Assert,TestResult,TestListener,TestRunner.

            圖2,xUnit 測(cè)試框架

            Xunit的原則:

            先編寫測(cè)試代碼,然后編寫符合測(cè)試的代碼

            測(cè)試代碼不需要覆蓋所有的細(xì)節(jié),但是需要覆蓋主要的功能和可能出錯(cuò)的地方

            發(fā)現(xiàn)Bug后,首先編寫對(duì)應(yīng)的測(cè)試用例,然后在進(jìn)行調(diào)試

            不斷總結(jié)出現(xiàn)Bug的原因,對(duì)其他代碼也編寫相應(yīng)的測(cè)試用例

            每次編寫完代碼后,運(yùn)行所有以前的測(cè)試用例,驗(yàn)證對(duì)以前的代碼的影響,并把這種影響盡早消除

            不斷維護(hù)測(cè)試代碼,保證代碼變動(dòng)后能通過所有測(cè)試

            xUnit測(cè)試框架包括的4大要素:

            測(cè)試Fixtures:是一組認(rèn)定為被測(cè)對(duì)象或被測(cè)程序單元測(cè)試成功的預(yù)訂條件或預(yù)期結(jié)果的設(shè)定。Fixture就是被測(cè)試的目標(biāo)。

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

            測(cè)試執(zhí)行:單元測(cè)試的執(zhí)行-setUp()-->執(zhí)行測(cè)試動(dòng)作-->tearDown()

            測(cè)試斷言(Assert):實(shí)際上就是驗(yàn)證被測(cè)程序在測(cè)試中的行為或狀態(tài)的一個(gè)宏或者函數(shù),斷言失敗會(huì)引發(fā)異常,終止測(cè)試的執(zhí)行。

            測(cè)試用例的編寫:初始化Fixture-->按照某個(gè)測(cè)試功能和流程對(duì)Fixture進(jìn)行操作-->驗(yàn)證結(jié)果是否正確-->對(duì)Fixture相關(guān)的資源進(jìn)行釋放

           1.2Junit單元測(cè)試工具

            JUnit---SourceForge項(xiàng)目---IBMCommon Public License ---官網(wǎng):www.junit.org

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

            xUnit的目標(biāo):1.開發(fā)人員寫測(cè)試代碼,提供一個(gè)測(cè)試框架,減少重復(fù)性勞動(dòng)2.創(chuàng)建并保留測(cè)試,將測(cè)試集中在一起,用已有的測(cè)試創(chuàng)建新的測(cè)試。

            Junit的好處:

            可以使測(cè)試代碼與產(chǎn)品代碼分開

            針對(duì)某個(gè)類的測(cè)試代碼,通過較少的改動(dòng)便可以將其應(yīng)用于另一個(gè)類的測(cè)試

            易于集成到測(cè)試人員的構(gòu)建中,JUnit和Ant的結(jié)合實(shí)施增量開發(fā)

            Junit是公開源代碼的,可以進(jìn)行二次開發(fā)

            可以方便的對(duì)JUnit進(jìn)行擴(kuò)展

            Junit測(cè)試編寫的原則:

            簡(jiǎn)化測(cè)試的編寫,這種簡(jiǎn)化包括測(cè)試框架的學(xué)習(xí)和實(shí)際測(cè)試單元的編寫

            使測(cè)試單元保持持久性

            可以利用既有的測(cè)試來編寫相關(guān)的測(cè)試

            Junit的特征:

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

            測(cè)試驅(qū)動(dòng)設(shè)備使用共同的初始化變量或?qū)嵗?/p>

            測(cè)試包結(jié)構(gòu)便于組織和集成運(yùn)行

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

            JUnit共有7個(gè)包,核心的包就是junit.framework和junit.runner。Framework包負(fù)責(zé)整個(gè)測(cè)試對(duì)象的架構(gòu),Runner包負(fù)責(zé)測(cè)試驅(qū)動(dòng)。

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

            TestResult:負(fù)責(zé)收集TestCase所執(zhí)行的結(jié)果,客戶可以預(yù)測(cè)的Failure和沒有預(yù)測(cè)的Error。同時(shí)負(fù)責(zé)將測(cè)試結(jié)果轉(zhuǎn)發(fā)給TestListener(該接口由TestRunner集成)進(jìn)行處理

            TestRunner:客戶對(duì)象調(diào)用的起點(diǎn),負(fù)責(zé)對(duì)整個(gè)測(cè)試流程進(jìn)行跟蹤。能夠顯示返回的測(cè)試結(jié)果,并報(bào)告測(cè)試的進(jìn)度

            TestSuite:負(fù)責(zé)包裝和運(yùn)行所有的TestCase

            TestCase:客戶測(cè)試類所要繼承的類,負(fù)責(zé)測(cè)試時(shí)對(duì)客戶類進(jìn)行初始化以及測(cè)試方法的調(diào)用.

            兩個(gè)重要的接口:Test,TestListener

            Test:包含兩個(gè)方法:run(),countTestCases()-->用于對(duì)測(cè)試動(dòng)作特征的提取

            TestListener:addError(),addFailure(),startTest(),endTest()-->用于對(duì)測(cè)試結(jié)果的處理以及測(cè)試驅(qū)動(dòng)開發(fā)的動(dòng)作的特征的提取。

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

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

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

            1.3JUnit實(shí)例

            1.3.1. 開發(fā)工具:

            Eclipse、JUnit、Ant

            1.3.2. 編碼實(shí)現(xiàn)三角形類型判斷程序:

          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 表示不能構(gòu)成三角形
          */
          public int type (){
          //to be added
          }
          }

            1.3.3、基于 JUnit 設(shè)計(jì)測(cè)試用例,使得滿足如下條件

            (1)包含不能構(gòu)成三角形的測(cè)試用例

            (2)包含構(gòu)成等邊三角形的測(cè)試用例

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

            (4)包含構(gòu)成其他種類三角形的測(cè)試用例

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

            4、編寫 ant 腳本驅(qū)動(dòng)測(cè)試用例

            包括測(cè)試用例執(zhí)行和測(cè)試報(bào)表生成

            備注:個(gè)人使用的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;
           }
          }

            單個(gè)的測(cè)試用例:

          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());
           }
          }

            參數(shù)化的測(cè)試用例:

          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("期待類型和測(cè)試類型不同!",(int)expected,triangle.type());
           }
          }



            結(jié)合上述的兩個(gè)測(cè)試用例的測(cè)試用例集:

          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>

            運(yùn)行結(jié)果截圖:

            單個(gè)測(cè)試用的運(yùn)行截圖

            參數(shù)化測(cè)試用例的運(yùn)行截圖:

            測(cè)試用例集的運(yùn)行:


           ant腳本運(yùn)行

            1.首先cd 到相應(yīng)的java project的目錄下 cd java project/testSoftware

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

            3 參看結(jié)果:

          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腳本在當(dāng)前項(xiàng)目下生成了一個(gè)report文件夾,其中有相應(yīng)的測(cè)試用例執(zhí)行的報(bào)告

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

            在導(dǎo)入項(xiàng)目時(shí)可能出現(xiàn)的問題:

            原先我是在OpenJDK 7的環(huán)境下編寫這個(gè)測(cè)試程序的,后來從Ubuntu12.10換到Ubuntu12.04LTS后,系統(tǒng)安裝的JDK 是Open JDK 6,所以導(dǎo)入項(xiàng)目時(shí)出現(xiàn)了java.lang.UnsupportedClassVersionError: demo2/ParameterTestTriangle : Unsupported major.minor version 錯(cuò)誤,百度了一下找到了問題的原因:是因?yàn)槭褂酶甙姹镜腏DK編譯的Java class文件試圖在較低版本的JVM上運(yùn)行. 解決方法:

            一定要清理干凈已經(jīng)生成的文件

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

            修改JRE:

            修改編譯器:

            參考資料:

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

          相關(guān)文章:

          軟件測(cè)試實(shí)驗(yàn)學(xué)習(xí)筆記系列2 -- lint,splint的使用

          軟件測(cè)試實(shí)驗(yàn)學(xué)習(xí)筆記系列4--CppUnit

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


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


          網(wǎng)站導(dǎo)航:
           
          <2013年8月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 乃东县| 大姚县| 东城区| 台州市| 高淳县| 清苑县| 鸡西市| 安阳市| 醴陵市| 和政县| 油尖旺区| 镇沅| 镇宁| 永宁县| 广西| 林西县| 莎车县| 林周县| 昌乐县| 乌兰察布市| 钦州市| 大余县| 海安县| 石林| 连平县| 南昌市| 浪卡子县| 宜兴市| 南宫市| 宁津县| 镇安县| 滨海县| 新田县| 临洮县| 黄浦区| 滨州市| 定陶县| 九江县| 临沭县| 都昌县| 怀远县|