版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、1,測試驅(qū)動的設(shè)計和開發(fā)( Test Driven Design and Development )基礎(chǔ)篇,天馬行空官方博客:http:/ ;QQ:1318241189;QQ群:175569632,2,你的代碼工作嗎,這段代碼很簡單,不可能出錯” “我試過了,它是正常工作的呀” “我用Debugger測試過了,我遍歷了所有程序分支,內(nèi)存中的值都是對的” 最好的方法是寫一段另外的代碼來證明它,讓電腦來告訴 我們它是工作的,天馬行空官方博客:http:/ ;QQ:1318241189;QQ群:175569632,3,XP中的測試,Unit Test Acceptance Test( Functio
2、nal Test ) Regression Test Nightly Test Stress Test 所有的測試都應(yīng)該獨立地自動的運行,4,什么是單元測試(Unit Test,單元測試是一段能夠放在批處理中自動運行的,用來測試Classes的 程序。單元測試測試一小段代碼或一個足夠小的功能。單元測 試程序調(diào)用這小段代碼或功能,并驗證返回的結(jié)果是否符合預(yù)先設(shè) 定的結(jié)果。 每個單元測試至少應(yīng)該有兩個測試例子( Test Case ): Negative Positive 單元測試是軟件工程的一個關(guān)鍵部分,5,什么是Acceptance Test,Acceptance Test are progr
3、ams or scripts configured to test that packages (groups of clusters of classes) meet external requirements and achieve goals, such as performance. They include screen-driving programs that test GUIs from without. Acceptance Test是對軟件做End-To-End的測試,衡量軟件是否符合 用戶需求的指標(biāo),也就是驗收測試,6,什么是Regression Test,Regress
4、ion testing is the process of validating modified parts of the software and ensuring that no new errors are introduced into previously tested code.” 一句話,Regresstion Test就是要重新測試所有的代碼和功能。 Regression Test和Development Test的不同在于Regression Test 需要重用已經(jīng)建立的所有的測試單元(Unit Test )和功能測試套件(Functional Test)。 Regress
5、ion Test的基礎(chǔ)是完整的自動單元測試和功能測試,7,什么是Nightly Test,Nightly Test就是每晚自動運行所有的Unit Test和Acceptance Test。 Nightly Test是XP中的Continuous Test的一個練習(xí)(Practice)。 Nightly Test可以準確的反映項目開發(fā)的進度和質(zhì)量,天馬行空官方博客:http:/ ;QQ:1318241189;QQ群:175569632,8,Nightly Test,Nightly Test是軟件開發(fā)中一個保證開發(fā)之質(zhì)量的最有效的方法,也 是衡量軟件之質(zhì)量和開發(fā)效率的最好的指標(biāo)。 Nightly
6、Test就是每天工作結(jié)束,所有的代碼都Check in到Source Control后,自動運行所有的Unit Test和Function Test。測試的結(jié)果 應(yīng)該自動分發(fā)給開發(fā)人員和管理層。 兩個指標(biāo)數(shù)值: 測試例子的通過率 單元測試必須是100%通過。Functional Test 應(yīng)該按計劃的通過。 單元測試的覆蓋率 表明有多少Class被測試過和測試的完善程度,天馬行空官方博客:http:/ ;QQ:1318241189;QQ群:175569632,9,測試優(yōu)先的編程,在寫任何代碼之前,先寫它的Unit Test。 “Never write a line of functional
7、code without a broken test case” Kent Beck Test-First Programming是一種測試技術(shù)嗎? Test-First Programming首先是一種分析方法。它迫使程序員仔細思考要做什么和不要做什么(而不是如何具體的實現(xiàn))。特別是各種例外的情況,并用程序語言正式的寫下來。這就好像在程序員的任務(wù)和程序員之間簽訂了一個清晰的正式合同。 Test-First Programming是一種設(shè)計方法。Unit Test測試的事程序,而不是一個想法。程序員必須清晰的定義程序的界面才能寫出它的Unit Test。而這時程序員是不知道(也不需要知道)里面
8、的具體邏輯是如何實現(xiàn)的。程序員只需要考慮Class的界面和功能(Responsibility)。啊,你在做OO設(shè)計了。 Test-First Programming是一種質(zhì)量控制方法( Quality Control )。如何控制質(zhì)量呢?如何知道我的程序是否運行呢?我會不會漏了什么?運行一下Unit Test。 Test-First Programming是一種重構(gòu)和優(yōu)化的方法。我們總希望自己的代碼可以漂亮,運行的效率高,所以我們會不斷地去改進。可是如何保證改進和優(yōu)化后的質(zhì)量呢?會不會越改越糟?答案還是Unit Test。 Test-First Programming不是通常意義上的測試技術(shù),
9、它的目的也不是僅僅用來測試你的代碼。 Test-First Programming是一種面向?qū)ο蟮拈_發(fā)方法,10,什么是Test-Driven Design (TDD,Test-Driven Design是一種開發(fā)風(fēng)格,它要求程序員做到: 在寫產(chǎn)品代碼之前,先寫它的單元測試( Unit Tests ) 沒有單元測試的Class不允許作為產(chǎn)品代碼 單元測試例子決定了如何寫產(chǎn)品代碼 不斷地成功運行所有的單元測試例子 不斷的完善單元測試例子 Test-Driven Design是把需求分析,設(shè)計,質(zhì)量控制量化 的過程,11,為什么會出現(xiàn)TDD,現(xiàn)實中的設(shè)計(Design)和測試(Testing):
10、面對一個新的開發(fā)任務(wù),往往第一個念頭就是如何去實現(xiàn)它呢? “好像是這樣做的” 感覺上差不多了。 抓起任務(wù)就開始編碼,一邊寫,一邊修改和設(shè)計。 哎,時間很緊。我先把任務(wù)實現(xiàn)了,然后再好好測試。 還是不工作,時間不多了。做個快速但丑陋的修改吧。等有空來再來重新整理這些代碼吧。 用Debugger運行幾次代碼,走完所有的我認為可能的分支。我感覺這些代碼應(yīng)該行了。提交吧。 哎,我也知道該寫一些自動的單元測試來把剛才在Debugger中的測試走一遍。可是那是很多的活啊。 這種情況要作自動測試太復(fù)雜了。還是手工作一下測試好了,12,為什么會出現(xiàn)TDD(Continue,程序員心中的測試: 很郁悶的工作。對
11、啊,程序員該做些新的,有創(chuàng)意的東西嘛。寫一些新的功能會更有趣些。 我知道這些代碼會工作的。我的經(jīng)驗和感覺都這樣告訴我。只要沒人亂改我的代碼,應(yīng)該就沒問題。再說這些邊緣情況幾乎不可能出現(xiàn)了。 測試是QA的工作。 自動測試太花時間(我要趕Deadline),不值得,13,如何面對這些現(xiàn)實和想法,Test-Driven Design and Development 真的能行? 試一試,14,如何做Test Driven Design and Development,再開發(fā)一個新的功能之前 首先確定你要做什么(不是要如何做!) 比如說一個論壇的增加用戶的功能,我們需要又一個method來增加一個用戶:
12、 public void addAccount( Account account ) 當(dāng)然包括成功增加一個用戶(在數(shù)據(jù)庫中插入一條紀錄) 還包括如果已經(jīng)由一個相同的用戶,應(yīng)該返回一個用戶已存在的消息 OK,我們知道這個method中的這段代碼要做什么,而且這段代碼也足夠簡單,天馬行空官方博客:http:/ ;QQ:1318241189;QQ群:175569632,15,如何做Test Driven Design and Development(Continue,然后為這個功能(Method)寫單元測試例子( Unit Test ) 單元測試例子要覆蓋這個Method的 “做什么”。 所以我們至
13、少有了兩個測試例子: Test Case 1: 測試成功增加一個用戶 Test Case 2: 測試增加一個已存在的用戶 其他邊緣情況測試: Test Case 3: 傳入的Account對象為NULL,16,如何做Test Driven Design and Development(Continue,寫Production代碼 我們清楚知道這段代碼需要做什么。因為我們有另一段代碼擺在那里,清晰的表明這段代碼的Contracts。 不用多,也不能少,只需要能實現(xiàn)再Unit Test中的Contracts和能夠通過它的Unit Test,17,如何做Test Driven Design and
14、Development(Continue,運行Unit Test 如果順利通過,你已經(jīng)很好的完成了你的任務(wù)。 如果沒通過,修補代碼直到能通過Unit Test為止。 如果出現(xiàn)在Unit Test中沒預(yù)先設(shè)定的結(jié)果,在Unit Test中增加一個Test Case,修補代碼直到通過所有的Test Case為止,18,TDD和PSP,Personal Software Process的Development,Design,Code,Build,Test,Test-Driven Design and Development,Analysis,Code Unit Test,Code,Build,Run
15、 Test,Analysis,Design,19,XP采用了TDD,TDD是Extreme Programming中必須遵行的一個方法。TDD是XP中Pair Programming的工作模式。 XP中把測試驅(qū)動的設(shè)計和開發(fā)做到極致。TDD的整個流程由兩個程序員一起執(zhí)行。 XP正是因為采用了TDD才能夠做到每天的代碼都是Production Code和每個小的Release都能提供具備Production質(zhì)量的代碼并投入使用。 有了TDD,XP才能降低風(fēng)險,去擁抱變化。 有了TDD,XP才能在計劃的時間內(nèi)完成計劃質(zhì)量的代碼。 有了TDD,XP才能減少CodeFix環(huán)節(jié),從而減少項目成本。 有了
16、TDD,XP Team才能對自己的工作充滿自信,20,TDD防止Over-Engineering,在開發(fā)中采用TDD,可以有效的避免過度設(shè)計和開發(fā)。如果程序員 不愿為一個Method寫測試例子或者認為現(xiàn)在沒有必要測試改Method, 那這個Method多半是現(xiàn)在不需要的,21,TDD,程序員和管理層,對程序員來說,通過運行Unit Test和Functional Test,每天下班的時 候都可以清楚的知道自己的代碼是work的。 對管理層來說,通過Nightly Test的結(jié)果,每天一早都清楚的知道項 目的質(zhì)量和開發(fā)進度,22,XP中誰來寫Tests,Developer: Unit Test
17、Acceptance Test( Functional Test ) Customer: Acceptance Test Customer為每一個User Story寫Functional Test。但通常用戶并不 具備設(shè)計和開發(fā)Functional Test的能力,需要程序員的幫助,23,什么時候?qū)慣ests,如果你要寫一個新的功能,請先寫她的測試例子 如果你要在沒有經(jīng)過測試的代碼上寫新的功能,請先寫目前代碼的測試例子 如果你要Fix一個Bug,請先為這個Bug寫一個測試例子 如果你要Refactor沒有測試過的代碼,請先寫一個測試例子 如果你發(fā)現(xiàn)一個邊緣例外值,請為她寫一個測試例子,24,
18、Extreme Unit,JunitJava Class的測試Framework JFCUnitJava Swing app的測試Framework CatusJava Server Side( EJB, Servlet )的測試Framework HTMLUnitHtml Page的測試Framework HTTPUnitHtml Page的測試Framework CPPUnitC+測試Framework .NetUnit.Net app的測試Framework,25,Junit( A sample,Junit是由kent Beck和Erich Gamma 編寫的一個open source的
19、測試 框架,用來編寫可重復(fù)的測試例子。 測試論壇中的增加用戶method public 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 ) throws SQLException, AccountAlreadyExist
20、Exception,26,Junit( A sample,1.為對應(yīng)的Java Class建立一個TestCase。Unit Test Case應(yīng)該放在 和Business Class相同的Package中,但在不同的的物理位置。 package org.redsoft.forum.dao.mysql import junit.framework.TestCase; import junit.framework.TestSuite; import junit.framework.Test; public class AccountDAOmySqlTest extends TestCase pu
21、blic AccountDAOmySqlTest(String name) super(name);,27,Junit( A sample,2. Override setUp() and tearDown() 如果需要,可以在setUp()中初始化需要的全局變量,資源等(比如 Database Connection, File I/O或Mock Objects等) 相應(yīng)的,可以在tearDown()中釋放資源(Database Connection,File I/O和Mock Objects等) public class AccountDAOmySqlTest extends TestCase
22、 private MysqlFixture mysqlFixtureIns = new MysqlFixture(); public void setUp() throws Exception mysqlFixtureIns.setUp(); public void tearDown() throws Exception mysqlFixtureIns.tearDown();,28,Junit( A sample,3.為被測試的Method寫Test Case public void testAddAccountNormal() AccountDAOmySql dao = new Accoun
23、tDAOmySql(); 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(Expecting charles,account.getPasswo
24、rd(),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();,29,Junit( A sample,public void testAddAccountAlreadyExist() Ac
25、countDAOmySql 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 AccountNotFoundException notFound ) notFound.print
26、StackTrace(); fail(Unexpected exception: + notFound.toString() ); catch( final AccountAlreadyExistException ex ) / Pass try dao.removeAccount( account.getUserName() ); catch( final SQLException sql ) sql.printStackTrace(); fail(Unexpected exception );,30,Junit( A Sample,運行這個Unit Test。 Junit提供兩種運行界面:
27、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.AccountDAOmySqlTest,31,Junit( A Sample,Text界面( junit.textui.TestRunner,32,Junit Test Suite,Test Suite用來運行所
28、有的Unit Tests Test Suite的數(shù)型結(jié)構(gòu): 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中的所有AllTest Suite,
29、33,Junit Test Suite,package 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 suite suite.addTest(org.redsoft.forum.dao.mysql.AllTests.suite(); / 加
30、入本package level中的Unit Test case suite.addTestSuite(MysqlDataSourceTest.class); return suite; /EOC,34,JFC Unit,一個Junit的Extension,用來測試Swing-based的Application。 一個最簡單的Sample:測試一個Login Screen,35,JFC Unit,代碼片斷:設(shè)置測試環(huán)境 private LoginScreen loginScreen = null; private TestHelper helper = null; public LoginScr
31、eenTest( 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 = null; helper.cleanUp
32、( 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, loginScreen, 0 ); assertNotNull( Could n
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度國際勞務(wù)派遣成本控制與審計合同樣本4篇
- 2025年度個人知識產(chǎn)權(quán)質(zhì)押貸款合同模板7篇
- 2025年度科技園區(qū)建設(shè)策劃合同模板4篇
- 二零二五年度出租車租賃合同車輛維修及保養(yǎng)2篇
- 二零二五年度盤扣腳手架租賃合同包含運輸保險與賠償4篇
- 2025年度智能電梯安全維保服務(wù)合同2篇
- 法律文書房屋租賃合同
- 銀行按揭貸款合同樣書
- 二零二五年度農(nóng)產(chǎn)品電商平臺物流配送服務(wù)合同8篇
- 二零二五年度電梯房租賃與裝修一體化合同4篇
- 【寒假預(yù)習(xí)】專題04 閱讀理解 20篇 集訓(xùn)-2025年人教版(PEP)六年級英語下冊寒假提前學(xué)(含答案)
- 2024年智能監(jiān)獄安防監(jiān)控工程合同3篇
- 2024年度窯爐施工協(xié)議詳例細則版B版
- 幼兒園籃球課培訓(xùn)
- 【企業(yè)盈利能力探析的國內(nèi)外文獻綜述2400字】
- 統(tǒng)編版(2024新版)七年級《道德與法治》上冊第一單元《少年有夢》單元測試卷(含答案)
- 100道20以內(nèi)的口算題共20份
- 高三完形填空專項訓(xùn)練單選(部分答案)
- 護理查房高鉀血癥
- 項目監(jiān)理策劃方案匯報
- 《職業(yè)培訓(xùn)師的培訓(xùn)》課件
評論
0/150
提交評論