精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

單測(cè)在商家前端業(yè)務(wù)中的實(shí)踐

開(kāi)發(fā) 前端
目前現(xiàn)狀是前端大部分情況下都沒(méi)有接觸到單測(cè),僅在組件庫(kù)或工具類的項(xiàng)目里有一些。這并不代表業(yè)務(wù)項(xiàng)目中前端就無(wú)法單測(cè), 而是因?yàn)橐恍┛陀^原因,導(dǎo)致前端在單測(cè)上的投入相對(duì)較少。

1、背景

圖片

商家系統(tǒng)是提供給得物商家在得物平臺(tái)上可以穩(wěn)定運(yùn)營(yíng)的服務(wù)抓手,前端代碼也伴隨著系統(tǒng)的發(fā)展而不斷壯大。這樣將導(dǎo)致文檔卻更新不及時(shí),最后想再通過(guò)這些文檔回溯業(yè)務(wù)邏輯也非常困難。

且若代碼結(jié)構(gòu)上沒(méi)有關(guān)注,動(dòng)輒就會(huì)產(chǎn)出一個(gè)大幾千行的文件??,人員交替維護(hù)的時(shí)候很難理清里面的邏輯,維護(hù)非常困難。

2、前端單測(cè)的難點(diǎn)

為解決上述痛點(diǎn),早在單測(cè)之前,團(tuán)隊(duì)上已經(jīng)做了一些其他事情來(lái)使文檔更清晰、代碼質(zhì)量更高,如寫需求系分文檔、通過(guò)??整潔架構(gòu)(The clean architecture)??對(duì)代碼進(jìn)行分層、code review等等。但這些其實(shí)都只是外在的約束,只有內(nèi)在的代碼能真正經(jīng)得住單測(cè)的推敲,才能更好的保障我們的代碼質(zhì)量。

但目前現(xiàn)狀是前端大部分情況下都沒(méi)有接觸到單測(cè),僅在組件庫(kù)或工具類的項(xiàng)目里有一些。這并不代表業(yè)務(wù)項(xiàng)目中前端就無(wú)法單測(cè), 而是因?yàn)橐恍┛陀^原因,導(dǎo)致前端在單測(cè)上的投入相對(duì)較少。

  1. 前端開(kāi)發(fā)的內(nèi)容比較雜,一個(gè)需求不僅僅是功能函數(shù)的編寫,還有UI的展示、dom交互的綁定等等,且若想單測(cè)完全覆蓋,將包含非常多的內(nèi)容,對(duì)業(yè)務(wù)前端來(lái)說(shuō)成本太高。
  2. 前端UI框架層出不窮,在業(yè)務(wù)開(kāi)發(fā)的時(shí)候,依賴框架也很容易將代碼邏輯和UI等完全耦合在一起,導(dǎo)致一個(gè)文件上千行,很難對(duì)這種代碼找到單測(cè)的切入點(diǎn)。
  3. 單測(cè)上手本身就有一定的門檻,要寫出可維護(hù)性高的單測(cè)更不簡(jiǎn)單,會(huì)讓不熟悉的人望而卻步。

3、單測(cè)即文檔

鑒于上面的第一個(gè)難點(diǎn),前端涉及的內(nèi)容太雜,我們肯定無(wú)法給所有的代碼覆蓋單測(cè),去測(cè)到代碼的各個(gè)角落。再結(jié)合上我們自己本身的痛點(diǎn)(文檔更新不及時(shí),人員輪轉(zhuǎn)成本高),因此以“單測(cè)即文檔”為目標(biāo),我們只用覆蓋業(yè)務(wù)邏輯上的單測(cè)即可,只關(guān)注業(yè)務(wù)流程的銜接,通過(guò)用例將業(yè)務(wù)流程講清楚,對(duì)于單測(cè)的分支覆蓋率也不做強(qiáng)硬的要求。

Use Cases

因此,要在團(tuán)隊(duì)落地單測(cè)的第一步即是識(shí)別出實(shí)現(xiàn)業(yè)務(wù)邏輯的代碼模塊。若在較早的時(shí)候,想找到這個(gè)切入點(diǎn)可能還真沒(méi)有什么好的方法,因?yàn)槿菐浊械拇笪募疫壿嫼蚒I都耦合在一起。

正如前面所說(shuō),在單測(cè)推行前,我們已經(jīng)做了一些代碼準(zhǔn)備工作。得益于“整潔架構(gòu)”的推行,在開(kāi)發(fā)需求的同時(shí),已逐漸在對(duì)代碼進(jìn)行解耦重構(gòu),其核心就是依據(jù)各部分代碼作用的不同將其拆分成不同的層次,在各層次間制定了明確的依賴原則,達(dá)到與框架無(wú)關(guān)與外部服務(wù)無(wú)關(guān)并可測(cè)試的目的。

圖片

經(jīng)過(guò)分層后,我們將業(yè)務(wù)邏輯主要都落在了usecase這一層,在我們的代碼結(jié)構(gòu)上,它的作用是將業(yè)務(wù)流程串聯(lián)起來(lái),且它僅依賴entities(主要對(duì)服務(wù)端返回?cái)?shù)據(jù)做適配和檢查)層,邏輯獨(dú)立不會(huì)因?yàn)橐蕾嚳蚣芑騏I的變化而無(wú)法運(yùn)行。

相較于后端服務(wù),前端應(yīng)用通常并不會(huì)承載如計(jì)算、存儲(chǔ)等實(shí)實(shí)在在的業(yè)務(wù)邏輯,同時(shí)由于現(xiàn)在微服務(wù)架構(gòu)的流行,前端應(yīng)用往往會(huì)承擔(dān)很重的膠水邏輯,即將各個(gè)微服務(wù)的邏輯串聯(lián)在一起,從而跑通業(yè)務(wù)流程。

因此,前端在編寫usecase的時(shí)候,我們會(huì)更注重主子函數(shù)的拆分,讓主usecase更純粹的去描述業(yè)務(wù)流程,而將部分具體的實(shí)現(xiàn)拆分到子函數(shù)中去實(shí)現(xiàn)。


/*
usecase聚焦流程的描述,諸如url鏈接拼接、活動(dòng)期查詢等具體邏輯都拆分到了其他的模塊中
*/
async function exportActivityLog({count, formValues}: {count: number;formValues: LogData}) {
if (count > 5000) {
message.error('導(dǎo)出文件數(shù)量不得超過(guò)5000!')
return
}
const res = await checkIsDuringTheEventApi()
if (res.isDuring) {
message.error('活動(dòng)期間,功能暫不可用,如有疑問(wèn)聯(lián)系運(yùn)營(yíng)');
return
}
const url = generateDownloadUrl({ formValues })
downloadExcelFile(url)
}

function generateDownloadUrl() {
// 省略
}

因此,對(duì)usecase層寫單測(cè),正是我們要找的最好切入點(diǎn),其既能滿足我們將業(yè)務(wù)文檔進(jìn)行補(bǔ)充,同時(shí)又能有單測(cè)模塊的產(chǎn)出,保障我們的代碼質(zhì)量和程序的穩(wěn)定性。

4、單測(cè)實(shí)踐

在識(shí)別出要覆蓋單測(cè)的代碼模塊之后,下一步自然就是落地單測(cè)用例。

前面已說(shuō)過(guò),寫單測(cè)本身就有一定的門檻,但既然要寫就應(yīng)寫可維護(hù)性和穩(wěn)定性高的單測(cè)。否則代碼稍微一重構(gòu),單測(cè)崩了??;或代碼真崩了的時(shí)候,單測(cè)卻沒(méi)又通過(guò)了??。

根據(jù)前面的描述可以看出,我們對(duì)于用例的可讀性(文檔性)和穩(wěn)定性有極高的訴求,對(duì)于用例所測(cè)試的邏輯范圍要求不高,這個(gè)準(zhǔn)則對(duì)于后續(xù)的單測(cè)用例的設(shè)計(jì)取舍會(huì)有很大的影響。

4.1 用例設(shè)計(jì)

首先我們需要確定設(shè)計(jì)用例的切入點(diǎn),目前單測(cè)社區(qū)內(nèi)比較流行的模式無(wú)非TDD和BDD兩種:

TDD:測(cè)試驅(qū)動(dòng)開(kāi)發(fā),偏向于去測(cè)到函數(shù)的各個(gè)功能運(yùn)行的結(jié)果是否符合預(yù)期,由于是通過(guò)先寫用例去驅(qū)動(dòng)業(yè)務(wù)邏輯的實(shí)現(xiàn),因此用例的設(shè)計(jì)往往更偏技術(shù)實(shí)現(xiàn)。

BDD:行為驅(qū)動(dòng)開(kāi)發(fā),流程上是TDD模式的一種分支,區(qū)別在于在構(gòu)思用例的時(shí)候更多的是以用戶行為(user story)的角度去考慮。

圖片

關(guān)于兩者更多的區(qū)別,大家可以網(wǎng)上查閱到更多的資料,這里就不再贅述。為了我們單測(cè)的穩(wěn)定可維護(hù)性,且以文檔為導(dǎo)向的我們,自然是選用了BDD的模式,只測(cè)業(yè)務(wù)行為邏輯,不關(guān)注功能函數(shù)的輸出正確與否(這塊目前可在自測(cè)和測(cè)試兄弟團(tuán)隊(duì)那邊幫忙保障)。這樣除非業(yè)務(wù)流程發(fā)生變更,否則代碼一般的重構(gòu)或調(diào)整都不會(huì)影響到單測(cè)的運(yùn)行,不會(huì)造成單測(cè)的雪崩。

4.2 用例結(jié)構(gòu)

在用例結(jié)構(gòu)上,為了配合“單測(cè)即文檔”的初衷并更好的配合BDD,我們?cè)谏鐓^(qū)常見(jiàn)的AAA(Arrange-Act-Assert)和GWT(Given-When-Then)兩種結(jié)構(gòu)之間選擇了后者。

無(wú)論AAA還是GWT最終都會(huì)形成一個(gè)三段式的用例結(jié)構(gòu),其區(qū)別仍然在于AAA的構(gòu)思更傾向于技術(shù)實(shí)現(xiàn),GWT更傾向于業(yè)務(wù)流程。雖然結(jié)構(gòu)一樣,但設(shè)計(jì)出來(lái)的用例內(nèi)容會(huì)有很大區(qū)別。

Given-When-Then

Given:一個(gè)上下文,指定和準(zhǔn)備測(cè)試的預(yù)設(shè)

When:進(jìn)行一系列操作,即所要執(zhí)行的操作

Then:得到可觀察的結(jié)果,即需要檢測(cè)的斷言

我們根據(jù)GWT的提供了單測(cè)的基本模板,供組內(nèi)同學(xué)寫單測(cè)時(shí)直接使用。


function init() {
const checkIsDuringTheEventApi = jest.fn();
const downloadExcelFile = jest.fn();
const exportActivityLog = buildMakeExportActivityLog({checkIsDuringTheEventApi, downloadExcelFile})

return {
checkIsDuringTheEventApi,
downloadExcelFile,
exportActivityLog
}
}

describe('spec', () => {
it('test', () => {
// Given 準(zhǔn)備用例所需的上下文
const { checkIsDuringTheEventApi, downloadExcelFile, exportActivityLog } = init();

// When 調(diào)用待測(cè)的函數(shù)
exportActivityLog()

// Then 斷言
expect('expect')
})
})

對(duì)于一些校驗(yàn)簡(jiǎn)單模型的用例,通過(guò)init函數(shù)做一層封裝就夠用了。但對(duì)于業(yè)務(wù)邏輯比較復(fù)雜,字段比較多的模型,直接利用原生數(shù)據(jù)進(jìn)行初始化對(duì)用例的可讀性并不友好。


describe('spec', () => {
it('個(gè)人賣家未發(fā)貨的訂單,允許進(jìn)行取消操作', () => {
// Bad case: 依賴字段較多,這樣手動(dòng)去創(chuàng)造字段數(shù)據(jù)可讀性并不友好
// 若case較多,這些字段要手動(dòng)構(gòu)建多次
action({
status: Status.待發(fā)貨,
merchantType: MerchantType.個(gè)人賣家,
// ...還有一些其他必傳字段
})
})
}

對(duì)于這種復(fù)雜場(chǎng)景,我們傾向于使用builder模式來(lái)構(gòu)造數(shù)據(jù),在較小的開(kāi)發(fā)成本下保障用例的可讀性和可維護(hù)性。

describe('spec', () => {
it('個(gè)人賣家未發(fā)貨的訂單,允許進(jìn)行取消操作', () => {
// Good case:通過(guò)builder實(shí)現(xiàn)邏輯的復(fù)用和信息的聚焦
const order = new OrderBuilder()
.status("待發(fā)貨")
.merchantType("個(gè)人賣家")
.build()

action(order)

})
})

4.3 用例描述

既然是要作為文檔使用,那用例描述上也顯得至關(guān)重要了。相比TDD對(duì)功能函數(shù)的單測(cè),我們描述完全于GWT的用例結(jié)構(gòu)對(duì)應(yīng)(When時(shí)常會(huì)被省略掉),我們并不關(guān)心具體的技術(shù)實(shí)現(xiàn)細(xì)節(jié),更多的是描述的這個(gè)業(yè)務(wù)的行為流程,思考函數(shù)最終想做什么,達(dá)到什么目的。基于意圖,把被測(cè)函數(shù)當(dāng)做黑盒,不用關(guān)注其中間的實(shí)現(xiàn)細(xì)節(jié),究竟生成了什么臨時(shí)變量、循環(huán)了幾次、有什么判斷等,而是通過(guò)用例描述將業(yè)務(wù)流程講清楚。


describe('導(dǎo)出活動(dòng)日志', () => {
it('導(dǎo)出時(shí),先查詢當(dāng)前活動(dòng)狀態(tài),若狀態(tài)是未在進(jìn)行中,則執(zhí)行導(dǎo)出操作', () => {
// 省略...
})
it('導(dǎo)出時(shí),若導(dǎo)出數(shù)量大于5000條,將不允許導(dǎo)出', () => {
// 省略...
})
})

上面??是導(dǎo)出活動(dòng)日志的一個(gè)操作,可以看出,用例的描述不會(huì)像測(cè)功能函數(shù)那樣精簡(jiǎn)(入?yún)⑹莂,調(diào)用了啥函數(shù)必須返回b之類),但是將導(dǎo)出活動(dòng)時(shí),相應(yīng)的調(diào)用流程和條件描述了出來(lái),這樣其他人在接手這塊業(yè)務(wù)時(shí),通過(guò)這個(gè)用例就能清楚知道在導(dǎo)出活動(dòng)日志時(shí)需求上有些什么限制以及要做的操作。

4.4 用例斷言

在確定好用例的設(shè)計(jì)思路和結(jié)構(gòu)之后,我們?cè)谟美男r?yàn)內(nèi)容上也做了一些取舍。針對(duì)社區(qū)上主導(dǎo)的經(jīng)典測(cè)試(Classical)和模擬測(cè)試(Mockist)兩大陣營(yíng),結(jié)合“單測(cè)即文檔“的理念,我們對(duì)于業(yè)務(wù)流程的驗(yàn)證訴求非常強(qiáng)烈,因此選擇了后者。

Classical風(fēng)格是盡可能的使用真實(shí)對(duì)象和函數(shù),讓函數(shù)以及依賴都真實(shí)的執(zhí)行;相對(duì)的,Mockist是想盡辦法去mock,主張將所調(diào)用的被測(cè)函數(shù)全部mock。存在即合理,兩個(gè)派各有利弊,并不存在一定誰(shuí)好誰(shuí)差。

要對(duì)用到的函數(shù)進(jìn)行mock,在保證用例可維護(hù)性的前提下(比如不mock文件路徑),我們需要對(duì)函數(shù)的依賴關(guān)系進(jìn)行整理。得益于團(tuán)隊(duì)整潔架構(gòu)的落地,目前應(yīng)用的usecase層都已經(jīng)通過(guò)依賴倒置對(duì)依賴關(guān)系做了很好的管理(usecase只依賴entity)。


export default function buildMakeExportActivityLog({checkIsDuringTheEventApi,downloadExcelFile}) {
async function exportActivityLog({count,formValues}) {
if (count > 5000) {
message.error('導(dǎo)出文件數(shù)量不得超過(guò)5000!')
return
}
const res = await checkIsDuringTheEventApi()
if (res.isDuring) {
message.error('活動(dòng)期間,功能暫不可用,如有疑問(wèn)聯(lián)系運(yùn)營(yíng)');
return
}
const url = generateDownloadUrl({ formValues })
downloadExcelFile(url)
}
}

// index.ts
import {checkIsDuringTheEventApi} from '@/services/activity'
import {downloadExcelFile} from '@/utils'
import buildMakeExportActivityLog from './makeExportActivityLog'

export const exportActivityLog = buildMakeExportActivityLog({cancel,printSaleTicket})

可以看到checkIsDuringTheEventApi以及downloadExcelFile這兩個(gè)函數(shù)最終作為參數(shù)傳入到實(shí)際的函數(shù)中,他們一個(gè)將會(huì)去發(fā)起請(qǐng)求,一個(gè)是會(huì)調(diào)用window的方法進(jìn)行下載,通過(guò)依賴倒置就能方便我們對(duì)其進(jìn)行模擬,在單測(cè)時(shí)就不會(huì)去真實(shí)執(zhí)行這兩個(gè)函數(shù)。


function init() {
const checkIsDuringTheEventApi = jest.fn();
const downloadExcelFile = jest.fn();
const exportActivityLog = buildMakeExportActivityLog({checkIsDuringTheEventApi, downloadExcelFile})
return {
checkIsDuringTheEventApi,
downloadExcelFile,
exportActivityLog
}
}

usecase中時(shí)常會(huì)有依賴的函數(shù)要去發(fā)起請(qǐng)求,在單測(cè)時(shí)我們不會(huì)去真實(shí)去發(fā)起這個(gè)請(qǐng)求,因此對(duì)于這類函數(shù),我們都應(yīng)mock掉,這樣可保障我們用例的速度和穩(wěn)定性。當(dāng)然實(shí)際在寫單測(cè)中,我們也不應(yīng)該成為一個(gè)完全的mockist,無(wú)休止的進(jìn)行mock,更好的方式是兩者結(jié)合,否則濫用mock反而會(huì)導(dǎo)致單測(cè)寫起來(lái)會(huì)更繁瑣(因?yàn)橐ock所有調(diào)用的函數(shù)實(shí)現(xiàn)或場(chǎng)景),而且真實(shí)代碼寫起來(lái)也會(huì)很別扭(所有外部函數(shù)都依賴倒置)。

一個(gè)用例正確與否,最終依賴的是最后的斷言,那對(duì)我們來(lái)說(shuō)該怎樣進(jìn)行斷言呢,如前面一直強(qiáng)調(diào)的一樣,我們測(cè)的是邏輯行為,因此需斷言的是某個(gè)行為的是否執(zhí)行或者是否達(dá)到了什么目的。結(jié)合前面的mock,我們可對(duì)函數(shù)的調(diào)用情況進(jìn)行捕獲,針對(duì)上面發(fā)起取消退款的函數(shù),斷言的例子如下:


describe('導(dǎo)出活動(dòng)日志', () => {
it('導(dǎo)出時(shí),先查詢當(dāng)前活動(dòng)狀態(tài),若狀態(tài)是未在進(jìn)行中,則執(zhí)行導(dǎo)出操作', () => {
// 省略...
expect(downloadExcelFile).toBeCalled()
})

it('導(dǎo)出時(shí),若導(dǎo)出數(shù)量大于5000條,將不允許導(dǎo)出', () => {
// 省略...
expect(downloadExcelFile).not.toBeCalled();
})
})

如上,斷言的內(nèi)容不是函數(shù)的實(shí)現(xiàn)細(xì)節(jié),如參數(shù)是否正確,而是只斷言行為是否執(zhí)行,它能盡量保證做到若代碼重構(gòu)后,單測(cè)用例在不修改的情況下依然能健壯的運(yùn)行,其只依賴需求的變更而做更改。同時(shí)為了維護(hù)用例的穩(wěn)定性,單個(gè)用例我們通常僅執(zhí)行一次斷言(單一職責(zé)),斷言的內(nèi)容嚴(yán)格和描述的“Then”部分對(duì)應(yīng)。

5、結(jié)語(yǔ)

商家以“單測(cè)即文檔”的理念為落地方向,在代碼設(shè)計(jì)以及用例的構(gòu)思、結(jié)構(gòu)、斷言、描述等環(huán)節(jié)都做了一定取舍,最終在用例的書寫成本、穩(wěn)定性、可讀性等各個(gè)方面取得了相對(duì)較好的平衡。

目前組內(nèi)各個(gè)項(xiàng)目已逐漸沉淀了幾百個(gè)用例,團(tuán)隊(duì)內(nèi)相互支援或自己回顧時(shí),通過(guò)這些用例就能知道這塊邏輯在做什么事,在修改這些需求時(shí)通過(guò)測(cè)試用例也能盡快知道基本的業(yè)務(wù)邏輯,有了單測(cè)的保障,改起代碼來(lái)更有底氣,代碼結(jié)構(gòu)上,也更加的合理。在大家逐漸熟悉單測(cè)后,后續(xù)更會(huì)慢慢做到功能函數(shù)、UI等的單測(cè)覆蓋,大家一起來(lái)保障商家前端業(yè)務(wù)的穩(wěn)定發(fā)展。

參考文章:

“整潔架構(gòu)”和商家前端的重構(gòu)之路:

??https://mp.weixin.qq.com/s/Sgr6El88eqjCDaRFxIVFQA??

The Difference Between TDD and BDD:

??https://joshldavis.com/2013/05/27/difference-between-tdd-and-bdd/??

??https://lassala.net/2017/07/20/test-style-aaa-or-gwt/??

jest文檔:

??https://jestjs.io/zh-Hans/docs/getting-started???

責(zé)任編輯:龐桂玉 來(lái)源: 得物技術(shù)
相關(guān)推薦

2022-07-06 08:34:17

前端單測(cè)項(xiàng)目

2022-04-10 11:52:43

前端單測(cè)程序

2022-03-29 09:03:22

測(cè)試組件Propsrender

2023-03-14 22:32:24

業(yè)務(wù)單測(cè)數(shù)量

2022-03-22 15:16:50

路由前端路由動(dòng)畫

2022-05-26 21:33:09

業(yè)務(wù)前端測(cè)試

2022-05-26 10:12:21

前端優(yōu)化測(cè)試

2016-10-28 15:01:35

Cookie前端實(shí)踐

2016-01-12 11:38:19

智能化運(yùn)維運(yùn)維業(yè)務(wù)

2022-06-03 09:30:31

店鋪W3C體系渲染

2022-08-08 13:24:28

整潔架構(gòu)架構(gòu)前端

2024-07-11 07:02:01

2025-03-20 10:50:08

RedisCaffeine緩存監(jiān)控

2020-07-08 10:01:07

SDP網(wǎng)絡(luò)安全安全框架

2017-06-19 16:45:41

數(shù)據(jù)庫(kù)水平切分用戶中心

2023-11-27 18:38:57

得物商家測(cè)試

2022-01-06 09:55:19

鴻蒙HarmonyOS應(yīng)用

2023-04-21 18:36:16

商家開(kāi)發(fā)平臺(tái)

2022-09-09 10:01:11

服務(wù)網(wǎng)格云原生交付請(qǐng)求

2023-04-07 18:35:23

StarRocks貨品運(yùn)營(yíng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

欧美人与拘性视交免费看| 亚洲大胆人体大胆做受1| 香蕉成人久久| 色视频www在线播放国产成人| 手机免费看av网站| 影音先锋男人资源在线| 99精品国产视频| 国产精品免费久久久久久| 丁香花五月激情| 日本妇女一区| 日韩一级二级三级精品视频| 国产亚洲精品网站| 久操视频在线| 亚洲精品黑牛一区二区三区| 亚洲午夜电影在线观看| 午夜精品区一区二区三| 亚洲av无码国产综合专区| 久热综合在线亚洲精品| 久久99国产综合精品女同| 国产一区二区三区四区五区六区| 视频二区欧美毛片免费观看| 欧美综合色免费| 日韩欧美国产综合在线| 国产在线观看91| 久久久www免费人成精品| 97在线中文字幕| 在线观看不卡的av| 男女精品视频| 久久久久久69| 丰满少妇被猛烈进入一区二区| 久久综合色占| 亚洲精品久久在线| www.黄色网| 日本成人在线网站| 欧美中文字幕不卡| 免费成人在线视频网站| 国产丝袜视频在线播放| 亚洲欧洲韩国日本视频| 日韩精品一区二区三区丰满| 亚洲日本香蕉视频| 成人av资源站| 99在线观看视频| 国产乱码精品一区二区| 男人的天堂久久精品| 欧美亚洲一级片| 日本高清www免费视频| 欧美1区3d| 欧美老女人xx| 欧美黑人猛猛猛| 亚洲成人一区| 久久综合五月天| 亚洲综合视频网站| 天天揉久久久久亚洲精品| 国产一区二区三区直播精品电影 | 无码人妻丰满熟妇区五十路| 一区二区激情| 热99在线视频| 五月婷婷六月婷婷| 麻豆精品一二三| 国产日韩欧美电影在线观看| 一二三区在线播放| 国内欧美视频一区二区| 亚洲tv在线观看| www.国产免费| 成人sese在线| 欧美日韩国产三区| av大片在线看| 亚洲青青青在线视频| 欧美视频在线第一页| 日韩三级免费| 色综合中文字幕国产| 无码日韩人妻精品久久蜜桃| 国精产品一区一区三区四川| 欧美性猛交xxxx乱大交退制版| 最新天堂中文在线| 日韩影片在线观看| 亚洲男人的天堂在线| 夫妇交换中文字幕| 真实国产乱子伦精品一区二区三区| 欧美激情视频给我| 久久亚洲精品国产| 久久成人免费日本黄色| 99热国产免费| 国产精品久久一区二区三区不卡| 亚洲欧洲一区二区三区| 成人一级生活片| 日韩在线短视频| 日韩亚洲欧美成人一区| 黄瓜视频污在线观看| 欧美丰满老妇| 91av在线免费观看视频| 亚洲熟女乱色一区二区三区久久久| 国产乱一区二区| 久久精品国产一区二区三区日韩| 99reav在线| 香蕉加勒比综合久久| 又色又爽又高潮免费视频国产| 国产一区二区三区亚洲综合 | 成人在线激情视频| 午夜视频在线播放| 国产精品成人免费| 亚洲中文字幕无码中文字| www一区二区三区| 亚洲免费一在线| 中文字幕影音先锋| 日本中文在线一区| 国产一区二区免费电影| 欧美jizzhd69巨大| 色综合天天性综合| 亚洲欧洲国产视频| 天天av综合| 日韩av男人的天堂| 午夜福利一区二区三区| 亚洲男人的天堂一区二区 | 亚洲天堂av在线| 91精品国产综合久久福利| 成年人网站免费看| 黄色欧美日韩| 91午夜在线播放| 东热在线免费视频| 岛国av午夜精品| 精品无码av一区二区三区| 国产精品国产三级国产在线观看| 欧亚精品在线观看| 欧美性受xxxx狂喷水| 一色桃子久久精品亚洲| 亚洲欧美在线精品| 欧洲专线二区三区| 97在线视频国产| 色婷婷激情五月| 一区二区三区免费网站| 999热精品视频| 日韩欧美1区| 国产精品美女网站| bbbbbbbbbbb在线视频| 欧美性xxxxhd| 精品无码在线视频| 国产欧美三级| 久久日韩精品| 亚洲一二三四| 亚洲欧美日韩精品久久| 国产又黄又猛又粗又爽| 99re视频精品| 国产精品秘入口18禁麻豆免会员| 久久中文字幕导航| 91国自产精品中文字幕亚洲| 天堂网在线播放| 午夜精品久久久久久久蜜桃app| 岛国大片在线免费观看| 欧美激情精品久久久六区热门| 91成人免费在线观看| www久久日com| 欧美大片一区二区| 日韩精品成人在线| 91在线观看免费视频| 欧美三级午夜理伦三级| 久久成人av| 国产免费一区二区三区在线能观看| av网站在线免费播放| 欧美日韩在线免费视频| 日本在线视频www| 香蕉久久精品日日躁夜夜躁| 日本免费一区二区三区视频观看| 你懂得在线网址| 91九色最新地址| 国产又粗又长又黄的视频| 精品一区二区日韩| 日韩欧美视频免费在线观看| 国产精品45p| 欧美在线视频观看| yw在线观看| 欧美一区二区精美| 91久久国产视频| 国产欧美一区二区在线观看| 中文字幕免费高清在线| 欧美日本在线| 欧美中日韩一区二区三区| 黄色成人在线观看网站| 久久99国产精品自在自在app| 色网站免费观看| 91黄视频在线| 中文字幕影音先锋| 国产亚洲一区二区三区在线观看 | www.日本精品| 日本一区二区在线不卡| 日韩欧美理论片| 99精品国产一区二区青青牛奶| 欧美日韩国产一二| 日韩中文字幕在线一区| 日本高清+成人网在线观看| 亚洲免费视频一区二区三区| 精品久久一区二区三区| www.国产毛片| 亚洲自拍偷拍av| av手机在线播放| 国产成人av电影| 国产aaaaa毛片| 亚洲人成毛片在线播放女女| 亚洲精品国产精品国自产| 国内精品国产成人国产三级粉色| 国产精品日韩欧美| 水蜜桃在线视频| 欧美成人一区二区三区电影| 欧美高清电影在线| 日韩精品中午字幕| 一级黄色大片免费观看| 精品国产福利视频| 亚洲av鲁丝一区二区三区 | 日韩av在线精品| 国产精品-色哟哟| 一本大道av伊人久久综合| 欧美成人精品激情在线视频| 中文字幕精品一区| 亚洲精品女人久久久| 国产一区二区在线观看视频| 老司机午夜av| 亚洲一区二区网站| 美女黄色免费看| 一本精品一区二区三区| 日韩久久精品一区二区三区| 美女一区2区| 国产精品18毛片一区二区| 精品国产一级| 成人黄色av免费在线观看| 精品成人免费一区二区在线播放| 韩剧1988免费观看全集| 欧美野外wwwxxx| 欧美wwwxxxx| 乱人伦中文视频在线| 揄拍成人国产精品视频| 亚洲欧美日韩免费| 亚洲激情成人网| 色婷婷中文字幕| 亚洲国产成人一区| 日本久久一级片| 欧美精品一区二区三区视频| 亚洲av无码乱码国产麻豆 | 五月婷婷六月丁香综合| 欧美精品一区二区三区蜜桃视频| 成人av免费播放| 日韩欧美国产小视频| 99国产在线播放| 欧美一区二区精美| 精品人妻一区二区三区蜜桃| 69堂精品视频| 精品黑人一区二区三区国语馆| 91精品国产91久久综合桃花| 国产日韩欧美一区二区东京热 | 日本道色综合久久影院| 日韩电影网站| 国产精品白嫩初高中害羞小美女 | 不卡视频一区二区三区| 色播一区二区| 国产亚洲一区二区三区在线播放 | 国精产品一区一区三区mba桃花| 亚洲欧美视频二区| 黄色小说综合网站| 亚洲一区和二区| 99re热视频这里只精品| 美女脱光内衣内裤| 中文文精品字幕一区二区| 国产精品夜夜夜爽阿娇| 亚洲一线二线三线视频| 日韩av黄色片| 欧美专区亚洲专区| 一级黄色a毛片| 亚洲精品在线电影| 日本亚洲一区| 中文字幕欧美日韩在线| av毛片在线播放| 午夜精品久久久久久99热软件| 一个人看的www视频在线免费观看| 国产成人激情小视频| 色诱色偷偷久久综合| 成人羞羞视频免费| 蜜桃一区二区| 日韩video| 国产日韩亚洲| 亚洲一级片av| 99久久久无码国产精品| 五月婷婷欧美激情| 一卡二卡欧美日韩| av一级在线观看| 91麻豆精品国产91久久久资源速度 | 55av亚洲| 国产精品久久久久久久久| 精品视频一区二区三区| 久久久久无码国产精品一区| 久久精品国产99久久| 日韩精品在线中文字幕| 日韩不卡手机在线v区| 日本泡妞xxxx免费视频软件| 久久婷婷久久一区二区三区| 日本黄色免费片| 欧美性极品xxxx做受| 国产精品羞羞答答在线| 日韩h在线观看| 成人在线观看亚洲| 国产999精品久久久| 日韩精品成人在线观看| 任我爽在线视频精品一| 国产一区美女| 中文字幕免费高清在线| 久久久久综合网| 免费日韩在线视频| 欧美日韩三级一区二区| 深夜福利在线看| 欧美大片免费观看在线观看网站推荐 | 亚洲天堂成人在线观看| 精品人妻一区二区三区免费看| 欧美一二三四区在线| av免费在线一区二区三区| 性欧美xxxx视频在线观看| 麻豆国产一区| 一区二区三区视频| 日本在线不卡一区| 国产精品第七页| 午夜久久久影院| 亚洲国产剧情在线观看| 日韩视频免费观看| 国语自产精品视频在线看抢先版结局 | 久久久久久久久久久91| 亚洲一区二区三区久久久| 日本不卡高清视频一区| 99热精品在线观看| 免费不卡的av| 亚洲午夜影视影院在线观看| 国产熟女一区二区丰满| 久久精品国产久精国产一老狼| 蜜桃精品在线| 日本中文不卡| 视频一区在线播放| 人妻视频一区二区| 色呦呦日韩精品| 国产中文字幕在线视频| 日韩av快播网址| 少妇精品久久久一区二区| 日本久久久精品视频| 99久久精品国产一区| 日韩人妻无码一区二区三区99 | 欧美性生交xxxxx| 亚洲综合男人的天堂| 亚洲AV无码一区二区三区性| 米奇精品一区二区三区在线观看| 免费观看在线一区二区三区| 国产又黄又爽免费视频| 久久99精品国产麻豆不卡| 日韩精品一区二区亚洲av性色| 欧美精品高清视频| 中文在线免费| 国产精品综合久久久久久| 亚洲人成高清| 亚洲精品国产熟女久久久| 欧美亚洲自拍偷拍| 国产一区久久精品| 成人女人免费毛片| 亚洲少妇诱惑| 97人妻人人揉人人躁人人| 欧美在线一区二区三区| 老司机在线永久免费观看| 亚洲一区二区三区在线视频| 国内精品久久久久久久影视蜜臀| 水蜜桃av无码| 91福利区一区二区三区| 麻豆影院在线观看| 成人午夜电影在线播放| 国产精品呻吟| 免费一级suv好看的国产网站| 欧美一区二区视频网站| www成人免费观看| 无码免费一区二区三区免费播放 | 久久国产精品久久| 日韩精品乱码免费| 欧美日韩精品亚洲精品| 日韩高清a**址| 全球最大av网站久久| 一二三四中文字幕| 久久久影视传媒| 国产欧美第一页| 欧美又大又粗又长| 999久久久精品国产| 国产精品成人无码专区| 欧洲亚洲精品在线| 美女网站视频在线| 日本成人三级| 国产91精品免费| av首页在线观看| 久久久久久久999| 成人黄色av| 在线观看成人动漫| 欧美亚洲综合另类| 精品众筹模特私拍视频| 欧美日韩一区二区视频在线| 国产精品自拍在线| 真实新婚偷拍xxxxx| 久久久久久久久国产精品| 精品美女在线视频| 日本xxxx裸体xxxx| 欧美一区永久视频免费观看| 久久r热视频|