<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 41  文章 - 29  trackbacks - 0
    <2010年7月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    常用鏈接

    留言簿(5)

    隨筆分類(28)

    隨筆檔案(23)

    收藏夾(6)

    Inside JVM

    Java

    java performance

    Solr

    搜索

    •  

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    最近公司要求重新回顧單元測(cè)試的實(shí)際效果,作為一個(gè)開(kāi)發(fā)經(jīng)理,我個(gè)人對(duì)單元測(cè)試也有很多疑惑。就個(gè)人而言,我自己也寫(xiě)過(guò)很多單元測(cè)試,也鼓勵(lì)程序員寫(xiě)單元測(cè)試,但實(shí)際效果似乎不盡如人意。因此,寫(xiě)了這篇短文,想和大家一起探討。

    1. 背景介紹
    我所在的公司是一家外資軟件公司,主要工作是開(kāi)發(fā)一個(gè)復(fù)雜的在線系統(tǒng)(java based web applicaiton). 該系統(tǒng)的主要特點(diǎn)是:定制化程度比較高,業(yè)務(wù)邏輯相當(dāng)復(fù)雜。 系統(tǒng)的技術(shù)棧是Struts, EJB (JBoss) and Hibernate。我管理的小組一共有10個(gè)左右開(kāi)發(fā)人員,6個(gè)左右測(cè)試人員,平均工作經(jīng)驗(yàn)在3年以上。

    公司在兩年前開(kāi)始推行單元測(cè)試。在開(kāi)始推行單元測(cè)試之前,系統(tǒng)已經(jīng)正式上線,也就是意味著有海量的沒(méi)有單元測(cè)試的代碼。推行之后,應(yīng)該說(shuō)投入了相當(dāng)多的時(shí)間,總共覆蓋的行數(shù)有20k, 其中行覆蓋率(line coverage)有55%左右,分支覆蓋率(branch coverage)有40%左右。我相信經(jīng)過(guò)這么多嘗試,應(yīng)該說(shuō),我?guī)У倪@個(gè)組不是一個(gè)單元測(cè)試的新手,有資格討論單元測(cè)試的得失。


    2. 實(shí)踐中的問(wèn)題和疑惑(開(kāi)發(fā)人員怎么說(shuō)?)
          我一向主張:一項(xiàng)技術(shù)值不值得或者好不好用歸根結(jié)底是要問(wèn)實(shí)際的使用者和開(kāi)發(fā)者的。作為一個(gè)經(jīng)理,我不傾向于推行一項(xiàng)程序員極力反對(duì)的技術(shù),不管這項(xiàng)技術(shù)是不是業(yè)界的標(biāo)準(zhǔn)或者是評(píng)論者的寵兒。一項(xiàng)技術(shù)必須要解決實(shí)際問(wèn)題,也就是mark your life easier。所以下面是開(kāi)發(fā)人員的回答。
      2.1 為什么需要單元測(cè)試和TDD (Test Driven Development)?
         2.2.1 單元測(cè)試可以發(fā)現(xiàn)代碼缺陷(Defect)么?投入/產(chǎn)出比(Defect count/Effort)是多少?
                    只能發(fā)現(xiàn)待測(cè)單元的缺陷,不能發(fā)現(xiàn)單元交互(集成)之間的缺陷。在實(shí)踐過(guò)程中,很少有defect通過(guò)單元測(cè)試發(fā)現(xiàn)。
                    基本不能用于發(fā)現(xiàn)表現(xiàn)層(JSP, Java scripts, css, UI etc)的代碼缺陷
                    投入/產(chǎn)出比太高。換句話說(shuō),相比于單元測(cè)試,人工測(cè)試(munual testing)可以很大程度得更快更好的發(fā)現(xiàn)系統(tǒng)缺陷。
         2.2.2 單元測(cè)試可以用來(lái)防止Regression Defect么?
                    如果我們特地為某個(gè)regression defect加了相應(yīng)的單元測(cè)試,那么單元測(cè)試在某種程度上可以防止regression defect的再一次出現(xiàn)。但是同樣的,單元測(cè)試只能防止待測(cè)單元中的Regression Defect,而且需要通過(guò)猜測(cè)來(lái)加入相應(yīng)的測(cè)試案例。
         2.2.3 單元測(cè)試對(duì)設(shè)計(jì)有幫助么?
                    單元測(cè)試本身不一定能幫助設(shè)計(jì)。據(jù)說(shuō)TTD可以幫助設(shè)計(jì),實(shí)踐過(guò)程中沒(méi)有很深的體會(huì)。
         2.2.4 你投入了多少時(shí)間寫(xiě)單元測(cè)試?需要多少時(shí)間維護(hù)單元測(cè)試?
                   單元測(cè)試:代碼 = 2:1,也就是說(shuō)一行代碼需要兩行單元測(cè)試。也有些人說(shuō)1:1。
                   維護(hù)成本基本上決定于單元接口的變化頻率:對(duì)于一些比較穩(wěn)定的代碼單元,維護(hù)成本還可以接受。但對(duì)于一些需求變化劇烈的單元,基本上需要重寫(xiě)。在實(shí)際實(shí)踐中,可能的比例為穩(wěn)定的單元測(cè)試:重寫(xiě)的單元測(cè)試 = 80%:20%。但是這里有一個(gè)悖論:其實(shí)我們更希望單元測(cè)試可以用于驗(yàn)證(verify)核心單元的正確性,然而這些單元的測(cè)試單元確基本上需要重寫(xiě)。這是為什么呢?其中一個(gè)可能的原因是:對(duì)于一個(gè)在線系統(tǒng)(web based application)來(lái)說(shuō),系統(tǒng)的主要邏輯和用戶接口(user interface)綁定過(guò)于緊密,所以,用戶接口的變化導(dǎo)致從表現(xiàn)層到數(shù)據(jù)庫(kù)層的垂直變化。即使業(yè)務(wù)需求只是加了一個(gè)新的屬性,但是這個(gè)數(shù)據(jù)將被加入核心的對(duì)象當(dāng)中,所有涉及這個(gè)對(duì)象的單元測(cè)試需要改變。

         2.2.5 單元測(cè)試的主要挑戰(zhàn)是什么?
              挑戰(zhàn)之一:如何在多個(gè)測(cè)試用例之間共享測(cè)試數(shù)據(jù)。
             公司產(chǎn)品支持一個(gè)很復(fù)雜的在線向?qū)?,由七步組成,每一步可以單獨(dú)保存然后退出,下次繼續(xù)編輯。如果你想測(cè)試最后一步的API, 你需要準(zhǔn)備很多其他頁(yè)面的數(shù)據(jù)。因此,需要花很多時(shí)間準(zhǔn)備測(cè)試數(shù)據(jù)。另外,公司產(chǎn)品還支持相似功能的其他向?qū)?。作為一個(gè)程序員,我們一直想在多個(gè)類似功能的向?qū)PI之間共享測(cè)試數(shù)據(jù)。然而,如果待測(cè)對(duì)象本身有些微變化,所有共享該數(shù)據(jù)的測(cè)試代碼全部需要重寫(xiě)。這是一個(gè)巨大的維護(hù)費(fèi)用。
             挑戰(zhàn)之二:劇烈的需求變化導(dǎo)致維護(hù)成本劇增,收益減少。
             正如2.2.4中描述的,一個(gè)典型的在線系統(tǒng)(web based application),通常可以分為三層:表現(xiàn)層,主要是用戶界面,包括HTML/JSP/CSS/Java Scripts/Ajex等等;業(yè)務(wù)層,主要是業(yè)務(wù)邏輯;數(shù)據(jù)層,存取數(shù)據(jù)。根據(jù)面向?qū)ο笤O(shè)計(jì)(OOD)的原則,業(yè)務(wù)層主要由一組領(lǐng)域?qū)ο?Business Object/Domain Object)構(gòu)成。這些領(lǐng)域?qū)ο笾惶峁┮唤M數(shù)目相對(duì)有限的,接口比較清晰的,時(shí)間比較穩(wěn)定的API。對(duì)這組API進(jìn)行單元測(cè)試是有必要的,也是有意義的。
             然而,系統(tǒng)還有相當(dāng)一部分的代碼用于調(diào)用不同領(lǐng)域?qū)ο笾g的API, 轉(zhuǎn)變成表現(xiàn)層需要的對(duì)象。表現(xiàn)層其他的邏輯還包含大量的代碼用于連接不同的頁(yè)面,以及構(gòu)建不同的向?qū)А?nbsp;
            正如和絕大多數(shù)的系統(tǒng)一樣,產(chǎn)品需求的變化是極其劇烈的,可以預(yù)測(cè)的,不可避免的。在這種情況下,需求變化將導(dǎo)致領(lǐng)域?qū)ο驛PI以上的代碼(包括絕大多數(shù)表現(xiàn)層代碼和一部分業(yè)務(wù)層代碼)將發(fā)生劇烈變化,與之相應(yīng)的單元測(cè)試代碼都需要相應(yīng)的改變。也就是說(shuō),這些代碼的單元測(cè)試代碼的維護(hù)成本很好。
             挑戰(zhàn)之三:海量的遺留代碼(Legacy Codes)
            正如前面描述的,我們是在產(chǎn)品已經(jīng)上線之后才開(kāi)始推行單元測(cè)試的。因此,大量的遺留代碼并不適用于單元測(cè)試。換句話說(shuō),單元測(cè)試必須要在API實(shí)現(xiàn)之前予以仔細(xì)得考慮。如果API本身沒(méi)有得到很好的設(shè)計(jì),單元測(cè)試基本上是不可能的。 

         2.2.6 拿什么來(lái)衡量單元測(cè)試?
              一般來(lái)說(shuō),業(yè)界使用行覆蓋率(line coverage)和分支覆蓋率(branch coverage)來(lái)衡量單元測(cè)試的測(cè)量。但在實(shí)際過(guò)程中,我們發(fā)現(xiàn)這些衡量標(biāo)準(zhǔn)和我們對(duì)單元測(cè)試的期望有很大差距:比如說(shuō),高覆蓋率不見(jiàn)得較少的代碼缺陷。高覆蓋率也不能防止regression缺陷。高覆蓋率也似乎和設(shè)計(jì)沒(méi)有直接關(guān)聯(lián)。從另外一個(gè)角度說(shuō),達(dá)到高覆蓋率所花費(fèi)的時(shí)間也是相當(dāng)驚人的。 
          從另外一個(gè)角度來(lái)說(shuō),我們希望找到一個(gè)方法可以簡(jiǎn)單直接地衡量單元測(cè)試的測(cè)量:比如說(shuō)代碼缺陷或regression defect數(shù)量。
          
    3. 聆聽(tīng)和討論(業(yè)界怎么說(shuō))
            帶著這些問(wèn)題和困惑,我在網(wǎng)上查詢了大量相關(guān)資料,牛人的文章和業(yè)界的討論。很容易看出,業(yè)界對(duì)于單元測(cè)試的目標(biāo),作用,方法和手段都有很多爭(zhēng)議。
        3.1 什么是(不是)單元測(cè)試?
             3.1.1 單元測(cè)試和發(fā)現(xiàn)缺陷無(wú)關(guān)(http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/)
                【摘要】單元測(cè)試不是一個(gè)發(fā)現(xiàn)缺陷或者檢測(cè)regression defect的有效方法。其一,單元測(cè)試,根據(jù)定義,是用來(lái)測(cè)試特定代碼單元。然而,一個(gè)系統(tǒng)往往是一個(gè)大量單元的復(fù)雜集成,單元測(cè)試很難發(fā)現(xiàn)集成的缺陷。其二,相比單元測(cè)試,手工測(cè)試或者自動(dòng)化集成測(cè)試更容易用于檢測(cè)缺陷。
             3.1.2 一個(gè)測(cè)試不是單元測(cè)試 如果 -  
             和數(shù)據(jù)庫(kù)交互
             需要跨越網(wǎng)絡(luò)
             需要訪問(wèn)文件系統(tǒng)
             不能和其他的單元測(cè)試同時(shí)運(yùn)行
             需要配置文件才能運(yùn)行

        3.1.3 測(cè)試驅(qū)動(dòng)開(kāi)發(fā)和驗(yàn)證(verification)無(wú)關(guān),和規(guī)范(specification)相關(guān)
          測(cè)試驅(qū)動(dòng)開(kāi)發(fā)并不意味著單元測(cè)試驅(qū)動(dòng)的開(kāi)發(fā)。實(shí)際上,測(cè)試驅(qū)動(dòng)開(kāi)發(fā)這個(gè)詞非常容易引起誤解。在TDD的大佬們眼中,單元測(cè)試只是測(cè)試驅(qū)動(dòng)開(kāi)發(fā)的工具,而不是目的。測(cè)試驅(qū)動(dòng)開(kāi)發(fā)更關(guān)注這個(gè)代碼單元應(yīng)該如何運(yùn)行(behave)而不是這個(gè)代碼單元實(shí)現(xiàn)是否正確(verification)。之所以叫測(cè)試驅(qū)動(dòng)開(kāi)發(fā),意義及在于此。最近你可以看到一個(gè)新名字的興起-行為驅(qū)動(dòng)開(kāi)發(fā)(Behaviour Driven Developemnt)。BDD更強(qiáng)調(diào)一個(gè)組件應(yīng)該如何工作,以及尋找一個(gè)簡(jiǎn)易的方法來(lái)規(guī)范行為。
         3.1.4 為什么需要單元測(cè)試?
           可以單獨(dú)地測(cè)試每個(gè)單元
           可以用于驗(yàn)證重構(gòu)后的代碼 
           可以用來(lái)確保不會(huì)破壞其他人的代碼
           可以用來(lái)提高系統(tǒng)設(shè)計(jì),比如說(shuō),不能單元測(cè)試的代碼將不會(huì)出現(xiàn) 
                  

        3.2 對(duì)怎么樣的代碼做(不做)單元測(cè)試?
        參考http://blog.stevensanderson.com/2009/11/04/selective-unit-testing-costs-and-benefits/ 
         【摘要】 該文作者在總結(jié)3年的TDD實(shí)踐經(jīng)驗(yàn)的時(shí)候,反復(fù)認(rèn)識(shí)一個(gè)情況:對(duì)于某些類型的代碼,單元測(cè)試工作得很好,也極大的提高了待測(cè)代碼的質(zhì)量;但對(duì)另外一些類型的代碼,單元測(cè)試耗費(fèi)了大量的時(shí)間,并沒(méi)有起到輔助設(shè)計(jì)和減少缺陷的作用,同時(shí)還導(dǎo)致代碼更加難以維護(hù)。
        基于這個(gè)想法,作者畫(huà)了一張圖來(lái)表示:

          作者認(rèn)為,
                (1)代碼本身很復(fù)雜但是對(duì)外部的依賴很少(左上),最適合單元測(cè)試,因?yàn)楹馁M(fèi)較少和收益較多。一般來(lái)說(shuō),某種算法(排序),核心業(yè)務(wù)規(guī)則,數(shù)據(jù)解析類似的模塊屬于這樣的代碼
                (2)帶有很多依賴的瑣碎代碼(Trivial Code with many dependencies,右下):稱為協(xié)調(diào)者(Coordinators),因?yàn)檫@些代碼主要用于集成多個(gè)代碼單元和安排代碼單元之間的交互。這些代碼不適用于單元測(cè)試,因?yàn)楹馁M(fèi)很高,收益卻不大。
                 (3)代碼很復(fù)雜而且外部依賴很多(右上):過(guò)于復(fù)雜的代碼,需要重構(gòu)。
                 (4)外部依賴較少的瑣碎代碼(左下):這些代碼可測(cè)可不測(cè),因?yàn)橹匾圆桓?,?fù)雜度也不高,加單元測(cè)試的意義不是很大。

             對(duì)于作者的這個(gè)想法,我比較同意。正如我在2.2.4和2.2.5中提到的,對(duì)于一個(gè)在線系統(tǒng)(web-based application)來(lái)說(shuō),可以分為內(nèi)外兩個(gè)圈:內(nèi)圈由核心領(lǐng)域?qū)ο螅–ore Domain Object)構(gòu)成,外圈由大量鏈接匯編代碼構(gòu)成。所謂核心領(lǐng)域?qū)ο螅@些對(duì)象包含核心業(yè)務(wù)邏輯,數(shù)目相對(duì)較少,邏輯相對(duì)比較復(fù)雜,接口(API)相對(duì)比較穩(wěn)定,輸入輸出相對(duì)比較清晰,屬于算法類代碼,最合適單元測(cè)試,也需要單元測(cè)試來(lái)提高相應(yīng)的質(zhì)量。同時(shí)我想強(qiáng)調(diào)一下:這些對(duì)象一定要精心設(shè)計(jì),精挑細(xì)選,一定要滿足數(shù)量少,接口穩(wěn)定,輸入輸出清晰這三個(gè)要求。數(shù)量少意味著需要測(cè)的代碼少,相應(yīng)的單元測(cè)試數(shù)量也少。接口穩(wěn)定意味著用戶界面的變化(或需求變化)對(duì)單元測(cè)試的影響較小。輸入輸出清晰意味著容易驗(yàn)證邏輯的正確性。相對(duì)的,外圈的代碼主要用來(lái)鏈接多個(gè)領(lǐng)域?qū)ο螅才潘麄冎g的交互,轉(zhuǎn)換成用戶界面需要的數(shù)據(jù)結(jié)構(gòu)。也就意味著外圈代碼和需求緊密相連,微小的用戶界面變化將會(huì)導(dǎo)致相應(yīng)的代碼代碼,寫(xiě)單元測(cè)試得不償失。

        3.3 單元測(cè)試最佳實(shí)踐和測(cè)試驅(qū)動(dòng)開(kāi)發(fā)反模式
        參考http://blog.stevensanderson.com/2009/08/24/writing-great-unit-tests-best-and-worst-practises/
        (1)單元測(cè)試之間應(yīng)該完全獨(dú)立的
              不要寫(xiě)不必要的斷言,每次只測(cè)一個(gè)代碼單元,模擬(Mock)外部依賴,避免不必要的前提條件。
        (2)單元測(cè)試應(yīng)該運(yùn)行得很快(比如說(shuō)少于5 min)
             單元測(cè)試需要運(yùn)行得很快,這樣程序員才愿意經(jīng)常運(yùn)行單元測(cè)試。這就意味著(1)單元測(cè)試不要訪問(wèn)數(shù)據(jù)庫(kù)(2)單元測(cè)試不要訪問(wèn)網(wǎng)絡(luò)(3)外部依賴需要被模擬(mock)
        (3)給單元測(cè)試一個(gè)清晰和一致的命名
              一個(gè)單元測(cè)試的名字應(yīng)該包含3項(xiàng)內(nèi)容:待測(cè)對(duì)象_待測(cè)案例_期望結(jié)果,比如說(shuō)ProductPurchaseAction_IfStockIsZero_RendersOutOfStockView()。 
        (4)常見(jiàn)的TDD反模式
               撒謊者:所有測(cè)試案例都通過(guò)了,看上去是有效的。但如果靠近看,你會(huì)發(fā)現(xiàn)這些案例完全沒(méi)有測(cè)試預(yù)期的內(nèi)容
               過(guò)度配置:一個(gè)單元測(cè)試需要一堆配置然后才能開(kāi)始測(cè)試。有的時(shí)候需要幾百行代碼配置環(huán)境,設(shè)計(jì)數(shù)十個(gè)對(duì)象。
               巨人:一個(gè)單元測(cè)試需要測(cè)試數(shù)千行代碼,并且包含大量的測(cè)試用例。
              無(wú)用者 :有的時(shí)候模擬是有效的方便的。但是其他一些時(shí)候,過(guò)多的模擬對(duì)象,Stub對(duì)象,假對(duì)象,導(dǎo)致單元測(cè)試主要在測(cè)模擬對(duì)象而不是實(shí)際的系統(tǒng)。
              檢察官:?jiǎn)卧獪y(cè)試對(duì)待測(cè)代碼非常了解,任何對(duì)待測(cè)代碼的變化將影響單元測(cè)試代碼。
              慷慨的富有者:多個(gè)單元測(cè)試共享測(cè)試數(shù)據(jù),任何一個(gè)單元測(cè)試改動(dòng)了一些數(shù)據(jù),其他的測(cè)試全部失敗了。
              本地英雄:?jiǎn)卧獪y(cè)試依賴于開(kāi)發(fā)環(huán)境某些特定的配置。這意味著:在其他環(huán)境上運(yùn)行單元測(cè)試將會(huì)失敗。
              采集者:?jiǎn)卧獪y(cè)試驗(yàn)證所有的輸出盡管它只對(duì)某些數(shù)據(jù)感興趣。
              狗仔隊(duì):?jiǎn)卧獪y(cè)試依賴于特定的實(shí)現(xiàn)細(xì)節(jié),比如說(shuō),單元測(cè)試捕獲待測(cè)代碼中拋出的每一個(gè)異常。
              欺瞞者:?jiǎn)卧獪y(cè)試驗(yàn)證了一大堆無(wú)關(guān)的細(xì)節(jié),但從不測(cè)試核心行為。比如說(shuō),待測(cè)代碼訪問(wèn)數(shù)據(jù)庫(kù)并返回?cái)?shù)據(jù),單元測(cè)試驗(yàn)證每個(gè)返回的數(shù)據(jù)。
              大聲說(shuō)話的人:?jiǎn)卧獪y(cè)試輸出一大堆診斷信息,日志信息,然而沒(méi)有清晰的成功/失敗標(biāo)志。
             please refer to http://tdd-antipatterns.net/index.php?title=Main_Page     


    4. 結(jié)論(前途在哪里)
            現(xiàn)在,我想答案應(yīng)該比較清楚了。
           第一,重新強(qiáng)調(diào)單元測(cè)試和測(cè)試驅(qū)動(dòng)開(kāi)發(fā)的目地:通過(guò)寫(xiě)單元測(cè)試來(lái)澄清接口(幫助系統(tǒng)設(shè)計(jì)),確保核心代碼(i.e.Domain Object)的正確性。它不是一個(gè)檢測(cè)缺陷的有效工具,也不應(yīng)該只用覆蓋率來(lái)衡量單元測(cè)試的質(zhì)量
           第二,只對(duì)核心代碼(比如說(shuō)主要業(yè)務(wù)對(duì)象)進(jìn)行單元測(cè)試。待測(cè)對(duì)象需要有相對(duì)有限的API數(shù)量,比較穩(wěn)定的接口定義和清晰的輸入輸出。不要把寶貴的時(shí)間花在測(cè)試大量的非核心代碼,比如說(shuō),鏈接(多個(gè)核心對(duì)象),協(xié)調(diào)(多個(gè)核心對(duì)象),和需求/用戶接口緊密相關(guān)的代碼。
           第三,不要濫用單元測(cè)試,請(qǐng)時(shí)刻關(guān)注最佳實(shí)踐和TDD反模式。
           第四,好的單元測(cè)試來(lái)源于好的設(shè)計(jì)。設(shè)計(jì)不好,代碼不會(huì)好,單元測(cè)試也不會(huì)好。
           最后,我還想繼續(xù)研究行為驅(qū)動(dòng)開(kāi)發(fā)(BDD),看看BDD是否更實(shí)用,請(qǐng)繼續(xù)關(guān)注。


    posted on 2010-07-13 17:34 Justin Chen 閱讀(2896) 評(píng)論(2)  編輯  收藏 所屬分類: Unit Test & Mock Test

    FeedBack:
    # re: 【原創(chuàng)】單元測(cè)試和測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)雜談 2010-07-27 11:12 海洋之心
    受教了!~  回復(fù)  更多評(píng)論
      
    # re: 【原創(chuàng)】單元測(cè)試和測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(TDD)雜談 2010-08-16 12:14 打醬油的
    這個(gè)。。。
    我想樓主得先把書(shū)好好翻一下,理解什么叫TDD才發(fā)表雜談吧。。。  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 亚洲福利电影一区二区?| 成人无码a级毛片免费| 99爱视频99爱在线观看免费| 亚洲av无码潮喷在线观看 | 一级毛片直播亚洲| 99久久这里只精品国产免费| 毛片在线全部免费观看| 一级人做人爰a全过程免费视频| 亚洲欧洲日产国码久在线| 亚洲女人被黑人巨大进入| 好男人看视频免费2019中文| 黄网站色视频免费观看45分钟| 亚洲娇小性xxxx| 亚洲国产成人久久精品app | 亚洲国产AV无码一区二区三区 | 亚洲精品免费在线视频| 老司机亚洲精品影院在线观看| 亚洲免费在线视频观看| 久久久无码精品亚洲日韩按摩| 日韩精品免费一区二区三区| 真人做A免费观看| 222www免费视频| 最近2019免费中文字幕6| 久久精品成人免费观看| 国产真人无码作爱视频免费| 成人无码a级毛片免费| 成人性生交大片免费看中文| 在线观看免费播放av片| 国内精品99亚洲免费高清| 亚洲欧美国产欧美色欲| 国产亚洲精品bv在线观看| 亚洲日韩国产欧美一区二区三区| 亚洲永久在线观看| 亚洲av无码无线在线观看| 亚洲天堂视频在线观看| 四虎影视永久免费视频观看| 日本人的色道www免费一区| 日本一道一区二区免费看| 国产18禁黄网站免费观看| mm1313亚洲精品无码又大又粗| 亚洲不卡无码av中文字幕|