開發(fā)人員必備的技能——單元測試

說起軟件測試四個(gè)字唇礁,想必大家腦海中浮現(xiàn)的有集成測試、系統(tǒng)測試、黑盒測試筒饰、白盒測試等晋柱,可能就是沒想到會(huì)有單元測試。 對(duì)于大學(xué)是學(xué)習(xí)軟件工程專業(yè)出身的同學(xué)來說可能會(huì)聽過這四個(gè)字琢融,對(duì)工作好幾年的職場老鳥可能也聽過但是沒實(shí)際用過居多界牡。絕大多數(shù)的開發(fā)人員都是忙于把手頭的工作開發(fā)好,并不會(huì)把單元測試納入工作范疇漾抬,他們會(huì)說宿亡,我連功能開發(fā)都忙不過來了,哪有時(shí)間去做單元測試纳令,況且還要寫測試代碼挽荠,那不是重復(fù)寫一篇代碼功能嗎?但平绩,單元測試真的不值得花時(shí)間去做嗎圈匆,那是因?yàn)榭赡苣悴⒉磺宄卧獪y試的投入產(chǎn)出比有多高,下面就簡單介紹單元測試到底能給開發(fā)人員帶來多少好處捏雌。

  • 什么是單元測試
  • 為什么要做單元測試
  • 不寫單元測試借口
  • 主流框架 JUnit 和 TestNG
  • Android 中的單元測試
  • 小結(jié)

什么是單元測試

單元測試本質(zhì)上也是代碼跃赚,與普通代碼的區(qū)別在于它是驗(yàn)證代碼正確性的代碼⌒允可簡單做個(gè)定義:單元測試是開發(fā)人員編寫的纬傲、用于檢測在特定條件下目標(biāo)代碼正確性的代碼。

軟件開發(fā)天生就具有復(fù)雜性肤频,沒人敢打包票說自己寫的代碼一點(diǎn)問題都沒有叹括,或者不經(jīng)測試就能保證代碼正確運(yùn)行,可能你在這個(gè)執(zhí)行路徑下能夠執(zhí)行着裹,殊不知還有其他路徑领猾,有一一去驗(yàn)證過嗎米同,因此,要保證程序的正確性就必須要對(duì)我們代碼進(jìn)行嚴(yán)格測試摔竿。

舉個(gè)簡單例子:比如有個(gè)計(jì)算類面粮,里面有個(gè) add 方法,操作就是兩個(gè)數(shù)進(jìn)行相加继低。

public class Calculator {
    public int add(int one, int another) {
        //只是簡單的兩個(gè)數(shù)相加
        return one + another;
    }
}

常規(guī)做法:假如你寫好了這個(gè)方法熬苍,你想進(jìn)行驗(yàn)證 add 方法的正確性,需要寫個(gè)使用 add 方法的 main 函數(shù)袁翁,首先實(shí)例化 Calculator 類柴底,然后調(diào)用 add 方法并傳入兩個(gè)參數(shù),比如 1 和 2粱胜。然后你運(yùn)行這個(gè)工程柄驻,看得出結(jié)果是否為 3 ,如果是 3 焙压,則表明我這個(gè)方法寫的沒有錯(cuò)誤鸿脓,可能就不測試了,就繼續(xù)開發(fā)后續(xù)的功能涯曲,如果不是 3 野哭,則返回去看看代碼中哪里出錯(cuò)了,重新進(jìn)行調(diào)試幻件,甚至有時(shí)候肉眼還看不出代碼哪里出錯(cuò)拨黔,此時(shí)就引入斷點(diǎn)去查看,在此期間绰沥,很大一部分時(shí)間就花在斷點(diǎn)篱蝇、調(diào)試、運(yùn)行上揪利。

單元測試做法:首先會(huì)利用 JUnit 測試框架(至于這個(gè)框架后面介紹)寫一段測試代碼态兴,如下:

public class CalculatorTest {
    public void testAdd() throws Exception {
        Calculator calculator = new Calculator();
        int sum = calculator.add(1, 2);
        Assert.assertEquals(3, sum);
    }
}

這里的 CalculatorTest 是 Calculator 對(duì)應(yīng)的測試類,這里的 testAdd 對(duì)應(yīng)著 add 的測試方法疟位,進(jìn)行測試一般分為三步驟:

  • setup瞻润。一般是 new 出你要測試的那個(gè)類,比如: Calculator calculator = new Calculator();
  • 執(zhí)行操作甜刻。一般是調(diào)用你要測試的那個(gè)方法绍撞,獲得運(yùn)行結(jié)果: int sum = calculator.add(1, 2);
  • 驗(yàn)證結(jié)果。驗(yàn)證得到的結(jié)果跟預(yù)期中是一樣的: Assert.assertEquals(3, sum);

看到 Assert 這個(gè)關(guān)鍵詞了嗎得院,這里可以理解為斷言或者期望值傻铣,根據(jù)入?yún)⒌闹担谕袀€(gè)什么值輸出祥绞,而不是靠肉眼去驗(yàn)證是不是自己想要的值非洲,是直接通過判斷值是否相等性來驗(yàn)證會(huì)具有更客觀性鸭限。

以上介紹的只是單元測試一點(diǎn)點(diǎn),那它能給我們帶來哪些更多好處呢两踏?

為什么要做單元測試

通常我們在做任何工作會(huì)先考慮它的回報(bào)败京,編寫代碼更是如此。如果單元測試的作用不大梦染,沒有人會(huì)愿意再寫一堆無用的代碼赡麦,那么單元測試到底能夠給我們帶來什么優(yōu)點(diǎn)呢?如下:

  • 便于后期重構(gòu)帕识。單元測試可以為代碼的重構(gòu)提供保障泛粹,只要重構(gòu)代碼之后單元測試全部運(yùn)行通過,那么在很大程度上表示這次重構(gòu)沒有引入新的BUG肮疗,當(dāng)然這是建立在完整晶姊、有效的單元測試覆蓋率的基礎(chǔ)上。
  • 優(yōu)化設(shè)計(jì)族吻。編寫單元測試將使用戶從調(diào)用者的角度觀察帽借、思考珠增,特別是使用TDD驅(qū)動(dòng)開發(fā)的開發(fā)方式超歌,會(huì)讓使用者把程序設(shè)計(jì)成易于調(diào)用和可測試,并且解除軟件中的耦合蒂教。
  • 文檔記錄巍举。單元測試就是一種無價(jià)的文檔,它是展示函數(shù)或類如何使用的最佳文檔凝垛,這份文檔是可編譯懊悯、可運(yùn)行的、并且它保持最新梦皮,永遠(yuǎn)與代碼同步炭分。
  • 具有回歸性。自動(dòng)化的單元測試避免了代碼出現(xiàn)回歸剑肯,編寫完成之后捧毛,可以隨時(shí)隨地地快速運(yùn)行測試,而不是將代碼部署到設(shè)備之后让网,然后再手動(dòng)地覆蓋各種執(zhí)行路徑呀忧,這樣的行為效率低下,浪費(fèi)時(shí)間溃睹。

等等而账,講了這么多優(yōu)點(diǎn),無非就是良好的接口設(shè)計(jì)因篇、正確性泞辐、可回歸笔横、可測試、完善的調(diào)用文檔咐吼、高內(nèi)聚狠裹、低耦合,這些優(yōu)點(diǎn)已經(jīng)足以讓我們對(duì)單元測試重視起來了汽烦,但是個(gè)人覺得還有更重要的原因涛菠。

  • 首先,帶來自信撇吞。在接手一個(gè)新的項(xiàng)目俗冻,或者說是參與一個(gè)新的項(xiàng)目開發(fā)時(shí),往往這種情況是你半途參加進(jìn)去的牍颈,你需要對(duì)已有的代碼結(jié)構(gòu)進(jìn)行解讀和理解迄薄,對(duì)于業(yè)務(wù)的理解,對(duì)于代碼個(gè)中各個(gè)模塊關(guān)系的理解煮岁。如果一開始就理財(cái)出錯(cuò)讥蔽,很可能修改后的代碼會(huì)引起更多的BUG出現(xiàn),到那時(shí)候又需要修復(fù)更多的BUG画机,改了一個(gè)地方冶伞,很有可能會(huì)莫名其妙地影響另外一個(gè)地方,這種現(xiàn)象是很常見的步氏。還有一種情況响禽,假設(shè)你修改的功能沒問題,但是需要去測試驗(yàn)證荚醒,在測試的時(shí)候就需要考慮這個(gè)功能點(diǎn)它原有的測試路徑有哪些芋类,又需要一一去驗(yàn)證功能路徑,以證明本次修改對(duì)于已存在的功能點(diǎn)不造成影響界阁。這其中就存在著很大的時(shí)間成本侯繁,導(dǎo)致效率不高。那是否存在著這么一種方式泡躯,我需要修改我想改動(dòng)的地方贮竟,不需要關(guān)心修改完之后它所造成的影響,也不需要關(guān)心它的測試回歸性精续,有坝锰,此時(shí)就是單元測試登場的時(shí)候。寫單元測試代碼重付,可以讓我自己寫的代碼足夠自信顷级,它是經(jīng)得起考驗(yàn)的。
  • 其次确垫,更快反饋弓颈。對(duì)于有一定編程經(jīng)驗(yàn)的開發(fā)人員來說帽芽,當(dāng)他拿到一個(gè)新需求的時(shí)候,首先想到的不是動(dòng)手 Coding 翔冀,而是會(huì)先想想代碼的結(jié)構(gòu)导街,有些類,數(shù)據(jù)結(jié)構(gòu)該是如何纤子,然后才開始敲代碼搬瑰。如果沒有單元測試,一般流程基本是這個(gè)模塊功能全部寫完才開始測試控硼,比如利用 MVP 架構(gòu)的功能泽论。一般都是開始 Model 模塊,然后完善 Presenter 模塊,最后寫 View 模塊卡乾,等這幾個(gè)模塊都寫完了翼悴,再把 APP 跑起來,驗(yàn)證自己寫的功能模塊是否符合需求幔妨,沒有符合則繼續(xù)回去修改代碼鹦赎,這中間需要花費(fèi)很長的時(shí)間才能知道當(dāng)下自己寫的代碼是否符合要求,是否正確误堡。那有沒有一種即時(shí)反饋的方式呢古话,有,寫單元測試即可埂伦,當(dāng)你寫完一個(gè)函數(shù)煞额,馬上就匹配一個(gè)單元測試函數(shù),這樣即寫即測的方式可以保證你當(dāng)場寫的代碼馬上進(jìn)行修改沾谜,測試通過一個(gè),就表示完成一個(gè)小的功能點(diǎn)胀莹,最后基跑,把函數(shù)組裝起來,就是我們想要大的功能點(diǎn)描焰。
  • 最后媳否,節(jié)約時(shí)間。對(duì)于 Android 開發(fā)來說荆秦,一遍一遍的運(yùn)行 APP 篱竭,然后執(zhí)行相應(yīng)的用戶操作,看界面是否正確的顯示步绸,通過這種方式來測試功能掺逼,其實(shí)是非常浪費(fèi)時(shí)間,而且效率不高瓤介,而用單元測試吕喘,可以幾乎不用打開 APP 來執(zhí)行,當(dāng)然有些需要一些資源文件的是需要 APP 運(yùn)行條件氯质,絕大部分的功能在單元測試階段就能驗(yàn)證完畢,那么速度就相對(duì)快很多拱礁。此外觅彰,單元測試還能幫忙減少 BUG 钮热,從而減少調(diào)試 BUG 的時(shí)間,一些低級(jí)犯的錯(cuò)誤在單元測試階段就能避免掉隧期。

不寫單元測試借口

很多開發(fā)人員不寫單元測試飒责,最重要的一個(gè)原因是他們并不知道單元測試能夠帶來什么好處,甚至根本不了解單元測試這個(gè)詞仆潮,那自然就像平行線般與之毫無交集宏蛉。還有一個(gè)比較重要的原因是一些開發(fā)人員的編程思想還處在一個(gè)相對(duì)初級(jí)的階段,開發(fā)軟件只管實(shí)現(xiàn)功能性置,什么高內(nèi)聚拾并、低耦合、重構(gòu)鹏浅、設(shè)計(jì)嗅义、可測試等認(rèn)為太過專業(yè),對(duì)于這些名詞以及意義還不了解隐砸,這自然不會(huì)考慮使用了之碗。還有一些非思想層面的理由,如下:

  • 單元測試太花時(shí)間了季希。軟件開發(fā)工作那么忙褪那,代碼都寫不完哪有時(shí)間寫單元測試。這可能是開發(fā)人員用的最多的借口式塌,從某些方面來說博敬,這不能算借口,因?yàn)楹芏嚅_發(fā)人員確實(shí)在工作上投入的時(shí)間特別多峰尝。但真的是這樣的嗎,你有沒有想過派诬,導(dǎo)致加班的原因也許就是花了太多時(shí)間在手動(dòng)測試默赂、調(diào)試程序上:或許你沒有考慮到靈活性與設(shè)計(jì),使得在需求發(fā)生變更時(shí)你需要花很多時(shí)間在復(fù)雜的代碼堆中完成特定的功能奈辰,而這些修改又可能引入新的 BUG ,又將導(dǎo)致你需要進(jìn)行耗時(shí)的手動(dòng)測試瑟啃、調(diào)試等等,如此反復(fù)错负,代碼將變得越來越亂,越來越難以維護(hù)油航,最終導(dǎo)致無休止的加班怕享。
  • 測試不是我的工作沙合。測試確實(shí)不是開發(fā)人員的工作绊率,但單元測試確實(shí)是開發(fā)人員的工作,測試包含很多種藐俺,而只有單元測試是開發(fā)人員的工作范疇。開發(fā)人員為應(yīng)用編寫代碼菱父,那么自然需要保證代碼的正確性,而單元測試正是這種保證代碼正確性的白盒測試梆奈,也就是在了解代碼內(nèi)部結(jié)構(gòu)邏輯的情況下進(jìn)行有目的的測試,既然說到了解代碼清酥,那么開發(fā)者自然是最權(quán)威的人焰轻。因此辱志,編寫單元測試并且為測試人員提交正確的代碼進(jìn)行其他測試是開發(fā)人員的職責(zé)所在。
  • 代碼都編譯通過了已球,還測什么忆某。一般來說,這是一個(gè)不會(huì)放在嘴上但可能藏在心里的借口棒坏。代碼編譯通過只能說你寫的代碼符合語法要求坝冕,并不代表能保證正確性。
  • 代碼原來就沒有單元測試磨澡,并且難以測試。這個(gè)問題基本是接受和維護(hù)別人開發(fā)的代碼厦酬,而原來的代碼本身就沒有單元測試了仗阅,再加入如果代碼的耦合性較高,那么就更難以為這些代碼寫單元測試筹裕。此時(shí)正是你了解代碼時(shí)候,首先為能夠測試的部分添加單元測試,保證這些可測試的部分不會(huì)被污染豪治,然后在對(duì)代碼有足夠的了解之后再對(duì)代碼進(jìn)行重構(gòu),降低代碼的耦合性掩浙,并且慢慢補(bǔ)充測試用例,使得代碼的耦合性谬墙、可測試性慢慢建立起來。

主流框架 JUnit 和 TestNG

JUnit 是一個(gè) Java 語言的單元測試框架造虎,它是 xUnit 單元測試架構(gòu)體系的一個(gè)實(shí)例,用于編寫和運(yùn)行可重復(fù)的測試澎媒。它包括以下特性:

  • 用于測試期望結(jié)果的斷言(Assertion)
  • 用于共享共同測試數(shù)據(jù)的測試工具
  • 用于方便的組織和運(yùn)行測試的測試套件
  • 圖形和文本的測試運(yùn)行器

TestNG 是一個(gè)測試框架,其靈感來自 JUnitNUnit 储玫,但引入了一些新的功能撒穷,使其功能更強(qiáng)大禽笑,使用更方便。TestNG 消除了大部分的舊框架的限制蟀伸,使開發(fā)人員能夠編寫更加靈活和強(qiáng)大的測試。 因?yàn)樗诤艽蟪潭壬辖梃b了Java注解( JDK5.0 引入的)來定義測試迟蜜,它也可以顯示如何使用這個(gè)新功能在真實(shí)的Java語言生產(chǎn)環(huán)境中冕杠。

特點(diǎn)如下:

  • 注解
  • TestNG 使用 Java 和面向?qū)ο蟮墓δ?/li>
  • 支持綜合類測試(例如兢交,默認(rèn)情況下,不用創(chuàng)建一個(gè)新的測試每個(gè)測試方法的類的實(shí)例)
  • 獨(dú)立的編譯時(shí)測試代碼和運(yùn)行時(shí)配置/數(shù)據(jù)信息
  • 靈活的運(yùn)行時(shí)配置
  • 主要介紹“測試組”晴裹。當(dāng)編譯測試,只要要求 TestNG 運(yùn)行所有的“前端”的測試,或“快”阿迈,“慢”苗沧,“數(shù)據(jù)庫”等
  • 支持依賴測試方法鞠绰,并行測試屿笼,負(fù)載測試,局部故障
  • 靈活的插件 API
  • 支持多線程測試

Android 中的單元測試

因?yàn)?JUnit 測試框架是基于 Java 語言杈曲,當(dāng)然 Android 開發(fā)也是基于 Java 語言趣钱,所以在 Android 中我們可以用 Junit4 單元測試框架進(jìn)行回歸測試燕垃,但同時(shí),Google 也提供了一個(gè) AndroidJUnit4 測試框架井联,看名字就知道它是基于 JUnit 4 框架適合在 Android 環(huán)境中做單元測試卜壕。

那么,AndroidJUnit4 和 Junit4 有什么區(qū)別呢烙常?很大一個(gè)區(qū)別在于:

1轴捎,AndroidJUnit4 測試可以在真機(jī)的環(huán)境下進(jìn)行。比如你要測文件讀取SD卡军掂,或者操作 SqlLite 數(shù)據(jù)庫葱蝗,這些條件只有在真機(jī)上才有的璧瞬,此時(shí)你用 AndroidJUnit4 框架測試,可以直接跑起來用真實(shí)的環(huán)境做相應(yīng)的單元測試棒拂。

2,JUnit4 測試是運(yùn)行在工程項(xiàng)目中,也就是在編譯階段。此時(shí)如果想要模擬 Android 環(huán)境三幻,比如我想用 JUnit4 來測試 Activity 類,那么就需要引用第三方庫來支持,引用 Mockito 和 Robolectric 框架來模擬 Android 環(huán)境進(jìn)行相應(yīng)的單元測試节芥。

所以何時(shí)用 AndroidJUnit4 和 JUnit4 不同的框架進(jìn)行單元測試坛芽,就看你待測試的方法前置條件是什么尤误,然后做不同的選擇最冰。

小結(jié)

總的來說达布,單元測試不是集成測試,單元測試只是測試一個(gè)方法單元,不是測試一整個(gè)流程框弛。集成測試是一種End To End的系統(tǒng)測試,測試相關(guān)模塊集成在一起是否能夠按照預(yù)期工作屡律,一般都是接口或者功能層面的測試,可能會(huì)依賴很多系統(tǒng)因素常侣,測試的代碼邏輯一般比較復(fù)雜,運(yùn)行時(shí)間會(huì)比較長,出錯(cuò)之后的修復(fù)成本高。單元測試則是開發(fā)者在集成測試之前就已經(jīng)進(jìn)行自測過,同時(shí)呢,進(jìn)行單元測試之后姓赤,對(duì)于某個(gè)方法的執(zhí)行路徑組合進(jìn)行了一一驗(yàn)證不铆,它只關(guān)注三個(gè)目標(biāo):

  • 有明確的返回值。比如對(duì)某個(gè)函數(shù)進(jìn)行單元測試裹唆,驗(yàn)證其返回值是否符合預(yù)期結(jié)果誓斥。
  • 這個(gè)函數(shù)只改變其對(duì)象內(nèi)部的一些屬性或者狀態(tài),函數(shù)本身沒有返回值许帐,就驗(yàn)證它所改變的屬性和狀態(tài)劳坑。
  • 一些函數(shù)沒有返回值,也沒有直接改變哪個(gè)值的狀態(tài)成畦,這就需要驗(yàn)證其行為泡垃,比如點(diǎn)擊事件。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末羡鸥,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子忠寻,更是在濱河造成了極大的恐慌惧浴,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奕剃,死亡現(xiàn)場離奇詭異衷旅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)纵朋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門柿顶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人操软,你說我怎么就攤上這事嘁锯。” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵家乘,是天一觀的道長蝗羊。 經(jīng)常有香客問我,道長仁锯,這世上最難降的妖魔是什么耀找? 我笑而不...
    開封第一講書人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮业崖,結(jié)果婚禮上野芒,老公的妹妹穿的比我還像新娘。我一直安慰自己双炕,他們只是感情好狞悲,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雄家,像睡著了一般效诅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上趟济,一...
    開封第一講書人閱讀 52,158評(píng)論 1 308
  • 那天乱投,我揣著相機(jī)與錄音,去河邊找鬼顷编。 笑死戚炫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的媳纬。 我是一名探鬼主播双肤,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼钮惠!你這毒婦竟也來了茅糜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤素挽,失蹤者是張志新(化名)和其女友劉穎蔑赘,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體预明,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缩赛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撰糠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酥馍。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖阅酪,靈堂內(nèi)的尸體忽然破棺而出旨袒,到底是詐尸還是另有隱情汁针,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布峦失,位于F島的核電站扇丛,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏尉辑。R本人自食惡果不足惜帆精,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望隧魄。 院中可真熱鬧卓练,春花似錦、人聲如沸购啄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽狮含。三九已至顽悼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間几迄,已是汗流浹背蔚龙。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來泰國打工挨稿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留捶枢,地道東北人逐抑。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓杠园,卻偏偏與公主長得像,于是被迫代替她去往敵國和親节视。 傳聞我的和親對(duì)象是個(gè)殘疾皇子裆泳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 感謝原作者的奉獻(xiàn)虹蒋,原作者博客地址:http://blog.csdn.net/zhu_ai_xin_520/arti...
    狼孩閱讀 14,072評(píng)論 1 35
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,264評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理弛姜,服務(wù)發(fā)現(xiàn)脐瑰,斷路器,智...
    卡卡羅2017閱讀 134,693評(píng)論 18 139
  • Android單元測試介紹 處于高速迭代開發(fā)中的Android項(xiàng)目往往需要除黑盒測試外更加可靠的質(zhì)量保障廷臼,這正是單...
    東經(jīng)315度閱讀 3,113評(píng)論 6 37
  • 誰說每一天松松垮垮的日子不是在沉淀蚪黑?其實(shí)每天重要的不是你做些什么,有沒有玩手機(jī)中剩,而是你怎么做的,你在做的過程中收獲...
    安曉軼閱讀 223評(píng)論 0 0