測試驅動的設計與開發_第1頁
測試驅動的設計與開發_第2頁
測試驅動的設計與開發_第3頁
測試驅動的設計與開發_第4頁
測試驅動的設計與開發_第5頁
已閱讀5頁,還剩35頁未讀 繼續免費閱讀

VIP免費下載

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、測試驅動的設計和開發( Test Driven Design and Development )基礎篇111111你的代碼工作嗎? “這段代碼很簡單,不可能出錯” “我試過了,它是正常工作的呀” “我用Debugger測試過了,我遍歷了所有程序分支,內存中的值都是對的”最好的方法是寫一段另外的代碼來證明它,讓電腦來告訴我們它是工作的。111112XP中的測試 Unit Test Acceptance Test( Functional Test ) Regression Test Nightly Test Stress Test所有的測試都應該獨立地自動的運行111113什么是單元測試(Unit

2、 Test)單元測試是一段能夠放在批處理中自動運行的,用來測試Classes的程序。單元測試測試一小段代碼或一個足夠小的功能。單元測試程序調用這小段代碼或功能,并驗證返回的結果是否符合預先設定的結果。每個單元測試至少應該有兩個測試例子( Test Case ):NegativePositive單元測試是軟件工程的一個關鍵部分。111114什么是Acceptance TestAcceptance Test are programs or scripts configured to test thatpackages (groups of clusters of classes) meet ext

3、ernal requirements and achieve goals, such as performance. They include screen-driving programs that test GUIs from without.Acceptance Test是對軟件做End-To-End的測試,衡量軟件是否符合用戶需求的指標,也就是驗收測試。111115什么是Regression Test“Regression testing is the process of validating modified parts of the software and ensuring t

4、hat no new errors are introduced into previously tested code.”一句話,Regresstion Test就是要重新測試所有的代碼和功能。Regression Test和Development Test的不同在于Regression Test需要重用已經建立的所有的測試單元(Unit Test )和功能測試套件(Functional Test)。Regression Test的基礎是完整的自動單元測試和功能測試。111116什么是Nightly TestNightly Test就是每晚自動運行所有的Unit Test和Acceptanc

5、e Test。Nightly Test是XP中的Continuous Test的一個練習(Practice)。Nightly Test可以準確的反映項目開發的進度和質量。111117Nightly TestNightly Test是軟件開發中一個保證開發之質量的最有效的方法,也是衡量軟件之質量和開發效率的最好的指標。Nightly Test就是每天工作結束,所有的代碼都Check in到Source Control后,自動運行所有的Unit Test和Function Test。測試的結果應該自動分發給開發人員和管理層。兩個指標數值:測試例子的通過率 單元測試必須是100%通過。Functio

6、nal Test 應該按計劃的通過。單元測試的覆蓋率 表明有多少Class被測試過和測試的完善程度。111118測試優先的編程在寫任何代碼之前,先寫它的Unit Test。“Never write a line of functional code without a broken test case” Kent BeckTest-First Programming是一種測試技術嗎?Test-First Programming首先是一種分析方法。它迫使程序員仔細思考要做什么和不要做什么(而不是如何具體的實現)。特別是各種例外的情況,并用程序語言正式的寫下來。這就好像在程序員的任務和程序員之間簽

7、訂了一個清晰的正式合同。Test-First Programming是一種設計方法。Unit Test測試的事程序,而不是一個想法。程序員必須清晰的定義程序的界面才能寫出它的Unit Test。而這時程序員是不知道(也不需要知道)里面的具體邏輯是如何實現的。程序員只需要考慮Class的界面和功能(Responsibility)。啊,你在做OO設計了。Test-First Programming是一種質量控制方法( Quality Control )。如何控制質量呢?如何知道我的程序是否運行呢?我會不會漏了什么?運行一下Unit Test。Test-First Programming是一種重構和

8、優化的方法。我們總希望自己的代碼可以漂亮,運行的效率高,所以我們會不斷地去改進。可是如何保證改進和優化后的質量呢?會不會越改越糟?答案還是Unit Test。Test-First Programming不是通常意義上的測試技術,它的目的也不是僅僅用來測試你的代碼。Test-First Programming是一種面向對象的開發方法。111119什么是Test-Driven Design (TDD)Test-Driven Design是一種開發風格,它要求程序員做到:在寫產品代碼之前,先寫它的單元測試( Unit Tests )沒有單元測試的Class不允許作為產品代碼單元測試例子決定了如何寫產

9、品代碼不斷地成功運行所有的單元測試例子不斷的完善單元測試例子Test-Driven Design是把需求分析,設計,質量控制量化的過程!1111110為什么會出現TDD現實中的設計(Design)和測試(Testing):面對一個新的開發任務,往往第一個念頭就是如何去實現它呢?“好像是這樣做的” 感覺上差不多了。抓起任務就開始編碼,一邊寫,一邊修改和設計。哎,時間很緊。我先把任務實現了,然后再好好測試。還是不工作,時間不多了。做個快速但丑陋的修改吧。等有空來再來重新整理這些代碼吧。用Debugger運行幾次代碼,走完所有的我認為可能的分支。我感覺這些代碼應該行了。提交吧。哎,我也知道該寫一些自

10、動的單元測試來把剛才在Debugger中的測試走一遍。可是那是很多的活啊。這種情況要作自動測試太復雜了。還是手工作一下測試好了。1111111為什么會出現TDD(Continue)程序員心中的測試:很郁悶的工作。對啊,程序員該做些新的,有創意的東西嘛。寫一些新的功能會更有趣些。我知道這些代碼會工作的。我的經驗和感覺都這樣告訴我。只要沒人亂改我的代碼,應該就沒問題。再說這些邊緣情況幾乎不可能出現了。測試是QA的工作。自動測試太花時間(我要趕Deadline),不值得。1111112如何面對這些現實和想法Test-Driven Design and Development真的能行?試一試!1111

11、113如何做Test Driven Design and Development再開發一個新的功能之前首先確定你要做什么(不是要如何做!)比如說一個論壇的增加用戶的功能,我們需要又一個method來增加一個用戶:public void addAccount( Account account )當然包括成功增加一個用戶(在數據庫中插入一條紀錄)還包括如果已經由一個相同的用戶,應該返回一個用戶已存在的消息OK,我們知道這個method中的這段代碼要做什么,而且這段代碼也足夠簡單。1111114如何做Test Driven Design and Development(Continue )然后為這個

12、功能(Method)寫單元測試例子( Unit Test )單元測試例子要覆蓋這個Method的 “做什么”。所以我們至少有了兩個測試例子:Test Case 1: 測試成功增加一個用戶Test Case 2: 測試增加一個已存在的用戶其他邊緣情況測試:Test Case 3: 傳入的Account對象為NULL1111115如何做Test Driven Design and Development(Continue )寫Production代碼我們清楚知道這段代碼需要做什么。因為我們有另一段代碼擺在那里,清晰的表明這段代碼的Contracts。不用多,也不能少,只需要能實現再Unit Tes

13、t中的Contracts和能夠通過它的Unit Test。1111116如何做Test Driven Design and Development(Continue )運行Unit Test如果順利通過,你已經很好的完成了你的任務。如果沒通過,修補代碼直到能通過Unit Test為止。如果出現在Unit Test中沒預先設定的結果,在Unit Test中增加一個Test Case,修補代碼直到通過所有的Test Case為止。1111117TDD和PSPPersonal Software Process的DevelopmentDesignCodeBuildTestTest-Driven Des

14、ign and DevelopmentAnalysisCode Unit TestCodeBuildRun TestAnalysisDesign1111118XP采用了TDDTDD是Extreme Programming中必須遵行的一個方法。TDD是XP中Pair Programming的工作模式。XP中把測試驅動的設計和開發做到極致。TDD的整個流程由兩個程序員一起執行。XP正是因為采用了TDD才能夠做到每天的代碼都是Production Code和每個小的Release都能提供具備Production質量的代碼并投入使用。有了TDD,XP才能降低風險,去擁抱變化。有了TDD,XP才能在計劃

15、的時間內完成計劃質量的代碼。有了TDD,XP才能減少CodeFix環節,從而減少項目成本。有了TDD,XP Team才能對自己的工作充滿自信。1111119TDD防止Over-Engineering在開發中采用TDD,可以有效的避免過度設計和開發。如果程序員不愿為一個Method寫測試例子或者認為現在沒有必要測試改Method,那這個Method多半是現在不需要的。1111120TDD,程序員和管理層對程序員來說,通過運行Unit Test和Functional Test,每天下班的時候都可以清楚的知道自己的代碼是work的。對管理層來說,通過Nightly Test的結果,每天一早都清楚的知

16、道項目的質量和開發進度。1111121XP中誰來寫TestsDeveloper:Unit TestAcceptance Test( Functional Test )Customer:Acceptance TestCustomer為每一個User Story寫Functional Test。但通常用戶并不具備設計和開發Functional Test的能力,需要程序員的幫助。1111122什么時候寫Tests?如果你要寫一個新的功能,請先寫她的測試例子如果你要在沒有經過測試的代碼上寫新的功能,請先寫目前代碼的測試例子如果你要Fix一個Bug,請先為這個Bug寫一個測試例子如果你要Refactor

17、沒有測試過的代碼,請先寫一個測試例子如果你發現一個邊緣例外值,請為她寫一個測試例子1111123Extreme Unit JunitJava Class的測試FrameworkJFCUnitJava Swing app的測試FrameworkCatusJava Server Side( EJB, Servlet )的測試FrameworkHTMLUnitHtml Page的測試FrameworkHTTPUnitHtml Page的測試FrameworkCPPUnitC+測試Framework.NetUnit.Net app的測試Framework1111124Junit( A sample)J

18、unit是由kent Beck和Erich Gamma 編寫的一個open source的測試框架,用來編寫可重復的測試例子。測試論壇中的增加用戶methodpublic class AccountDAOmySql implements AccountDAO /* * Add a user account * * param Account - A account object that contains the user info,like userName, * password,email */public void addAccount( final Account account )

19、 throws SQLException, AccountAlreadyExistException1111125Junit( A sample)1.為對應的Java Class建立一個TestCase。Unit Test Case應該放在和Business Class相同的Package中,但在不同的的物理位置。package org.redsoft.forum.dao.mysqlimport junit.framework.TestCase;import junit.framework.TestSuite;import junit.framework.Test;public class A

20、ccountDAOmySqlTest extends TestCase public AccountDAOmySqlTest(String name) super(name);1111126Junit( A sample)2. Override setUp() and tearDown()如果需要,可以在setUp()中初始化需要的全局變量,資源等(比如Database Connection, File I/O或Mock Objects等)相應的,可以在tearDown()中釋放資源(Database Connection,File I/O和Mock Objects等)public class

21、 AccountDAOmySqlTest extends TestCase private MysqlFixture mysqlFixtureIns = new MysqlFixture();public void setUp() throws Exception mysqlFixtureIns.setUp();public void tearDown() throws Exception mysqlFixtureIns.tearDown();1111127Junit( A sample)3.為被測試的Method寫Test Casepublic void testAddAccountNorm

22、al()AccountDAOmySql dao = new AccountDAOmySql();Account account = new Account(USER_NAME,charles,charles_);try dao.addAccount( account ); Account account_new = dao.findByUserName( account.getUserName() ); assertEquals(Expecting charles,account.getUserName(),account_new.getUserName() ); assertEquals(E

23、xpecting charles,account.getPassword(),account_new.getPassword() ); assertEquals(Expecting ,account.getEmail(),account_new.getEmail() ); dao.removeAccount( account.getUserName() ); catch( final Exception e ) e.printStackTrace(); fail(Unexpected exception: + e.toString(); 1111128Junit( A sample)publi

24、c void testAddAccountAlreadyExist()AccountDAOmySql dao = null;Account account = null;try/ Add an Account dao.addAccount( account );fail(AccountAlreadyExistException expected);catch( final SQLException e ) e.printStackTrace();fail(Unexpected exception: + e.toString();catch( final AccountNotFoundExcep

25、tion notFound )notFound.printStackTrace();fail(Unexpected exception: + notFound.toString() ); catch( final AccountAlreadyExistException ex )/ Passtrydao.removeAccount( account.getUserName() );catch( final SQLException sql )sql.printStackTrace();fail(Unexpected exception );1111129Junit( A Sample)運行這個

26、Unit Test。Junit提供兩種運行界面:Swing(junit.swingui.TestRunner)C:sandboxforumjava -classpath ./classes;./lib/junit.jar;./lib/mysql_jdbc.jar;./lib/Tidy.jar;./lib/struts.jar junit.swingui.TestRunner org.redsoft.forum.dao.mysql.AccountDAOmySqlTest1111130Junit( A Sample)Text界面( junit.textui.TestRunner )1111131J

27、unit Test SuiteTest Suite用來運行所有的Unit TestsTest Suite的數型結構:org.redsoft.forum.AllTest|-org.redsoft.forum.dao.AllTest|-org.redsoft.forum.dao.mysql.AllTest|-org.redsoft.forum.util.AllTest每個Package Level都由一個AllTest Test Suite在每個Test Suite中,加入在本package level中的所有單元測試例子( Unit Test Cases )加入子Package level中的所

28、有AllTest Suite1111132Junit Test Suitepackage org.redsoft.forum.dao;public class AllTests public static void main(String args) junit.textui.TestRunner.run(suite();public static Test suite() TestSuite suite = new TestSuite();/ 加入子加入子package中的中的AllTest suitesuite.addTest(org.redsoft.forum.dao.mysql.All

29、Tests.suite();/ 加入本加入本package level中的中的Unit Test casesuite.addTestSuite(MysqlDataSourceTest.class);return suite;/EOC1111133JFC Unit一個Junit的Extension,用來測試Swing-based的Application。一個最簡單的Sample:測試一個Login Screen1111134JFC Unit代碼片斷:設置測試環境private LoginScreen loginScreen = null; private TestHelper helper =

30、null; public LoginScreenTest( String name ) super( name ); protected void setUp( ) throws Exception super.setUp( ); helper = new JFCTestHelper( ); loginScreen = new LoginScreen( LoginScreenTest: + getName( ) ); loginScreen.setVisible( true ); protected void tearDown( ) throws Exception loginScreen =

31、 null; helper.cleanUp( this ); super.tearDown( ); 代碼片斷:測試圖形界面JDialog dialog;JButton exitButton = ( JButton ) helper.findNamedComponent( ExitButton, loginScreen, 0 ); assertNotNull( Could not find the Exit button, exitButton ); JButton enterButton = ( JButton ) helper.findNamedComponent( EnterButton, l

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論