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

開源 | Canyon:提升JavaScript代碼質(zhì)量的全面覆蓋率分析工具

人工智能 開源
從這篇文章發(fā)表時起,我們將正式開源Canyon。JavaScript是時下最流行的編程語言,但是端到端測試覆蓋率收集領(lǐng)域一直空白,我們的代碼開發(fā)基于了istanbuljs,monaco editor等優(yōu)秀開源項目。

作者簡介

wr_zhang25,攜程資深前端開發(fā)工程師,關(guān)注前端代碼覆蓋率、JavaScript開源方向。

Liang, 攜程資深研發(fā)經(jīng)理,質(zhì)量專家,專注質(zhì)量工程領(lǐng)域。

一、背景

istanbuljs 是一款優(yōu)秀的JavaScript代碼覆蓋率工具,主要用于單元測試的代碼覆蓋率檢測和生成本地覆蓋率報告。然而,隨著現(xiàn)代前端技術(shù)和UI自動化測試的發(fā)展,對端到端測試的代碼覆蓋率檢測需求逐漸增加,istanbuljs提供的功能顯得捉襟見肘。

在攜程內(nèi)部JavaScript代碼覆蓋率使用的是gitlab內(nèi)置的coverage上報,也是只支持單元測試的覆蓋率收集和概覽數(shù)據(jù)展示。隨著攜程的前端技術(shù)日益精進,我們有了自己的前端流量錄制平臺,并且部署了相當大規(guī)模的模擬器集群進行UI自動化(flybirds)回放。這種場景下,需要對端到端測試的代碼覆蓋率進行收集和展示,以便開發(fā)同學更好的了解到自己的代碼質(zhì)量。

傳統(tǒng)的istanbuljs提供的功能已經(jīng)無法滿足我們的需求。我們需要處理UI自動化過程中來自前端高并發(fā)的覆蓋率上報,實時的覆蓋率聚合,以及覆蓋率數(shù)據(jù)的聚合展示。因此,我們在Istanbuljs的基礎(chǔ)上開發(fā)了Canyon,解決端到端測試覆蓋率難收集的問題。

目前,攜程的多個部門已經(jīng)開始使用Canyon,并在持續(xù)集成流水線構(gòu)建階段插入探針代碼,在UI自動化測試階段收集和上報覆蓋率數(shù)據(jù)。服務(wù)端實時生成詳盡的覆蓋率報告,為UI自動化測試用例提供全面的覆蓋率數(shù)據(jù)指標。

二、介紹

Canyon 通過簡單的 Babel 插件配置即可實現(xiàn)代碼插裝、覆蓋率上報和實時報告生成。其技術(shù)棧完全基于 JavaScript,只需 Node.js 環(huán)境即可運行,部署方便,適用于云原生環(huán)境的部署(如 Docker、Kubernetes)。

應(yīng)用的架構(gòu)設(shè)計適用于處理高頻、大規(guī)模的覆蓋率數(shù)據(jù)上報,能夠應(yīng)對 UI 自動化測試中的各種場景。同時,Canyon 與現(xiàn)有的 CI/CD 工具(如 GitLab CI、Jenkins)無縫集成,使用戶能夠輕松地在持續(xù)集成流水線中使用。

架構(gòu)圖如下:

圖片

下面會根據(jù)以下幾個部分來介紹 Canyon 的主要功能:

  • 代碼覆蓋率
  • 代碼插樁
  • 測試與上報
  • 覆蓋率聚合
  • 覆蓋率報告
  • 變更代碼覆蓋率
  • react native 覆蓋率收集方案
  • 覆蓋率提升優(yōu)先級列表

三、代碼覆蓋率

隨著編寫更多的end-to-end測試case,你會發(fā)現(xiàn)有一些疑問,我需要寫更多的測試用例嗎?究竟還有哪些代碼沒測到?用例會不會重復(fù)了?這個時候代碼覆蓋率就派上用場了,它的原理是在代碼執(zhí)行前將代碼探針插入到源代碼中(其實就是上下文加計數(shù)器),這樣每當case執(zhí)行的時候就可以觸發(fā)其中的計數(shù)器。

在代碼中插入代碼探針的步驟稱為代碼插樁(instrument)。插樁前的代碼:

// add.js
function add(a, b) {
  return a + b
}
module.exports = { add }

插樁過程是對代碼解析以查找所有函數(shù)、語句和分支,然后將計數(shù)器插入代碼中。對于上面的代碼,插樁完成后:

// 這個對象用于計算每個函數(shù)和每個語句被執(zhí)行的次數(shù)
const c = (window.__coverage__ = {
  // "f" 記錄每個函數(shù)被調(diào)用的次數(shù)
  f: [0],
  // "s" 記錄每個語句被調(diào)用的次數(shù)
  // 我們有3個語句,它們都從0開始
  s: [0, 0, 0],
})


// 第一個語句定義了函數(shù)
c.s[0]++
function add(a, b) {
  // 函數(shù)被調(diào)用后是第二個語句
  c.f[0]++
  c.s[1]++


  return a + b
}
// 第三個語句即將被調(diào)用
c.s[2]++
module.exports = { add }

我們希望確保文件中的每個語句和函數(shù)add.js都已被我們的測試至少執(zhí)行一次。因此我們編寫一個測試:

// add.cy.js
const { add } = require('./add')


it('adds numbers', () => {
  expect(add(2, 3)).to.equal(5)
})

當測試調(diào)用時add(2, 3),執(zhí)行“add”函數(shù)內(nèi)的計數(shù)器遞增,覆蓋范圍對象變?yōu)椋?/span>

{
  f: [1],
  s: [1, 1, 1]
}

這個測試用例覆蓋率達到了100%,每個函數(shù)和每個語句都至少執(zhí)行了一次。但是在實際應(yīng)用中,要達到100%的代碼覆蓋率需要多次測試。

這是覆蓋率的基本介紹,有了這個前置知識,方便大家理解下面的內(nèi)容。

四、代碼插樁(instrumenting-code)

代碼覆蓋率最重要的一環(huán)就是代碼插樁

istanbuljs 是久經(jīng)沙場的js代碼插樁黃金標準。Canyon主要為端到端測試提供解決方案,經(jīng)過大量的實驗驗證,現(xiàn)代化前端工程的覆蓋率插樁必須要編譯時插樁。具體原因是istanbuljs提供的nyc插樁工具只能對原生js進行插樁,然而前端模版語法層出不窮,例如ts、tsx、vue,雖然nyc也可以插樁,但是結(jié)構(gòu)實踐證明直接插樁的覆蓋率效果不盡人意,無法精確到該插樁到的函數(shù)、語句、分支。

幸運的是經(jīng)過調(diào)研,我們發(fā)現(xiàn)了babel-plugin-istanbul、vite-plugin-istanbul(experimental)、swc-plugin-coverage-instrument(experimental)。等類型工程的插樁解決方案。這些方案無一例外都是在前端工程編譯階段在將代碼分析成ast抽象語法樹的時候在適當時機進行插樁方法調(diào)用,更精確的插樁到的函數(shù)、語句、分支。

適用的工程類型:

工程類型

方案

vanilla javascript

nyc

babel

babel-plugin-istanbul

vite

vite-plugin-istanbul (experimental)

swc

swc-plugin-coverage-instrument (experimental)

用戶可以根據(jù)自己的工程類型選擇合適的插樁方案,只需要在工程中安裝對應(yīng)的插件,然后就會在編譯時自動插樁。

以babel.config.js為例:

module.exports = {
  plugins: [
    [
      'babel-plugin-istanbul',
      {
        exclude: ['**/*.spec.js', '**/*.spec.ts', '**/*.spec.tsx', '**/*.spec.jsx'],
      },
    ],
  ],
};

插樁完成后,代碼中會插入一些代碼探針,這些代碼探針會在運行時收集覆蓋率數(shù)據(jù),然后上報到Canyon服務(wù)端。

檢查是否插樁成功,可以在編譯后的產(chǎn)物中搜索__coverage__,如果有則說明插樁成功。

圖片

為了緊密關(guān)聯(lián)插樁代碼的源代碼,我們適配了各種provider,將環(huán)境變量發(fā)送到Canyon服務(wù)端,兌換到reportID,方便覆蓋率數(shù)據(jù)聚合計算完成后的覆蓋率源文件的關(guān)聯(lián)展示。

我們還提供了babel-plugin-canyon的babel插件,可以在各種流水線內(nèi)(aws,gitlab ci)讀取環(huán)境變量(branch、sha),以供后續(xù)覆蓋率數(shù)據(jù)與對應(yīng)的gitlab源代碼關(guān)聯(lián)。

babel.config.js

module.exports = {
  plugins: [
    [
        'babel-plugin-canyon',
        {
          provider: 'gitlab',
          branch: process.env.CI_COMMIT_REF_NAME,
          sha: process.env.CI_COMMIT_SHA,
        },
    ],
  ],
};

支持的提供商:

  • Azure Pipelines
  • CircleCI
  • Drone
  • Github Actions
  • GitLab CI
  • Jenkins
  • Travis CI

需要特別注意的是,代碼探針的插樁會在構(gòu)建產(chǎn)物上下文加上代碼探針,會是代碼整體產(chǎn)物增大30%,建議不要上生產(chǎn)環(huán)境。

五、測試與上報

當插樁完成發(fā)布到測試環(huán)境后,我們就可以進行測試了。拿playwright舉例,對于插樁成功的前端應(yīng)用站點,window對象上面都會掛載__coverage__和__canyon__對象,我們需要在playwright測試過程中收集并上報這些數(shù)據(jù)到canyon的服務(wù)端。

playwright示例:

const {chromium} = require('playwright');
const main = async () => {
  const browser = await chromium.launch()
  const page = await browser.newPage();
  // 進入被測頁面
  await page.goto('http://test.com')
  // 執(zhí)行測試用例
  // 用例1
  await page.click('button')
  // 用例2
  await page.fill('input', 'test')
  // 用例3
  await page.click('text=submit')
  const coverage = await page.evaluate(`window.__coverage__`)
  // 收集上報覆蓋率
  upload(coverage)
  browser.close()
}


main()

攜程內(nèi)部有自己的UI自動化平臺 flybirds,我們在flybirds內(nèi)部集成了Canyon覆蓋率數(shù)據(jù)的收集和上報。真實的瀏覽器UI自動化測試的覆蓋率收集場景較為復(fù)雜,主要體現(xiàn)在多頁面(MPA)的覆蓋率收集時機不確定性。

單頁面(SPA)與多頁面(MPA)

當測試用例執(zhí)行完成后,對于單頁面應(yīng)用(SPA)或者多頁面應(yīng)用而言,上報步驟是將頁面window對象上的__coverage__對象上報到Canyon服務(wù)端,對于單頁面應(yīng)用來說,相對來說比較簡單,在所有測試內(nèi)容都在單頁面應(yīng)用內(nèi),覆蓋率數(shù)據(jù)會常駐在window對象中,對于多頁面應(yīng)用而言,路由的跳轉(zhuǎn)會導(dǎo)致window對象的重制,丟失coverage對象。所以這個時機是至關(guān)重要的,經(jīng)過大量實踐驗證,我們找到了瀏覽器的onvisiblechange方法。

  • visibilitychange

在瀏覽器可見性改變的時候上報覆蓋率數(shù)據(jù),值得一提的是,對于visibilitychange這種可能會導(dǎo)致重復(fù)數(shù)據(jù)上報,但是對于覆蓋率統(tǒng)計來說,未執(zhí)行到的代碼多次合并來說不會影響覆蓋率的具體指標數(shù)據(jù)統(tǒng)計。

  • fetchLater

Chrome 瀏覽器正在積極引入一個革命性的 JavaScript API——fetchLater()。這個全新的 API 旨在徹底簡化關(guān)閉頁面時的數(shù)據(jù)發(fā)送過程,確保即使在頁面關(guān)閉后或用戶離開的情況下,請求也能在未來某個時刻被安全、可靠地發(fā)出。

這個API的推出時令人振奮的,可以很好的解決多頁面(MPA)收集難的問題,只需要在瀏覽器關(guān)閉時收集。

注:fetchLater() 已在 Chrome 中提供,用于在版本 121(2024 年 1 月發(fā)布)開始的原始試驗中供真實用戶測試,該試驗將持續(xù)到 Chrome 126(2024 年 7 月)。

六、聚合

覆蓋率數(shù)據(jù)的來源是同一版本的代碼,覆蓋率數(shù)據(jù)是可以聚合的,Canyon內(nèi)部使用reportID來關(guān)聯(lián)測試用例和細分聚合維度。這樣做可以讓海量的覆蓋率數(shù)據(jù)聚合成有限個,即Case的數(shù)量。

/**
 * 合并兩個相同文件的文件覆蓋對象實例,確保執(zhí)行計數(shù)正確。
 *
 * @method mergeFileCoverage
 * @static
 * @param {Object} first 給定文件的第一個文件覆蓋對象
 * @param {Object} second 相同文件的第二個文件覆蓋對象
 * @return {Object} 合并后的結(jié)果對象。請注意,輸入對象不會被修改。
 */
function mergeFileCoverage(first, second) {
  const ret = JSON.parse(JSON.stringify(first));


  delete ret.l; // 移除派生信息


  Object.keys(second.s).forEach(function (k) {
    ret.s[k] += second.s[k];
  });


  Object.keys(second.f).forEach(function (k) {
    ret.f[k] += second.f[k];
  });


  Object.keys(second.b).forEach(function (k) {
    const retArray = ret.b[k];
    const secondArray = second.b[k];
    for (let i = 0; i < retArray.length; i += 1) {
      retArray[i] += secondArray[i];
    }
  });


  return ret;
}

端到端測試的覆蓋率數(shù)據(jù)特點之一是單體數(shù)據(jù)體積大,在項目整體插樁的情況下相當于整體源代碼體積的30%。攜程Trip.com flight站點的預(yù)定頁UI自動化case上報次數(shù)每次可達2000次,每次10M數(shù)據(jù),這樣的數(shù)據(jù)量對于Canyon服務(wù)端來說是一個巨大的挑戰(zhàn)。

對于單條數(shù)據(jù)大且高頻次的數(shù)據(jù)上報場景,很難做到實時數(shù)據(jù)聚合計算。Canyon采用消息隊列的形式來消費數(shù)據(jù),并且設(shè)計成無狀態(tài)服務(wù),適用于云原生時代的容器化部署,可通過HPA彈性伸縮容來應(yīng)用不同場景下的測試覆蓋率上報。

七、報告

對于覆蓋率報告展示,我們沿用了istanbul-report的界面風格,但是由于istanbul-report只提供了靜態(tài)html文件的生成,不適合現(xiàn)代化前端水合數(shù)據(jù)生成html的模式,為此我們參考了它的源碼,使用了monaco-editor標記源代碼覆蓋率。

const decorations = useMemo(() => {
    if (data) {
        const annotateFunctionsList = annotateFunctions(data.coverage, data.sourcecode);
        const annotateStatementsList = annotateStatements(data.coverage);
        return [...annotateStatementsList, ...annotateFunctionsList].map((i) => {
            return {
                inlineClassName: 'content-class-found',
                startLine: i.startLine,
                startCol: i.startCol,
                endLine: i.endLine,
                endCol: i.endCol,
            };
        });
    } else {
        return [];
    }
}, [data]);

經(jīng)過著色后的效果:

圖片

八、變更代碼覆蓋率

對于變更代碼覆蓋率,我們統(tǒng)計的公式是覆蓋到的新增代碼行/所有新增代碼行。

通過配置compareTarget來指定對比目標,再聯(lián)合gitlab的git diff接口獲取變更代碼行結(jié)合覆蓋率數(shù)據(jù)計算。

/**
 * returns computed line coverage from statement coverage.
 * This is a map of hits keyed by line number in the source.
 */
function getLineCoverage(statementMap:{ [key: string]: Range },s:{ [key: string]: number }) {
  const statements = s;
  const lineMap = Object.create(null);


  Object.entries(statements).forEach(([st, count]) => {
    if (!statementMap[st]) {
      return;
    }
    const { line } = statementMap[st].start;
    const prevVal = lineMap[line];
    if (prevVal === undefined || prevVal < count) {
      lineMap[line] = count;
    }
  });
  return lineMap;
}

九、react native 覆蓋率收集方案

攜程的移動端技術(shù)棧主要是react native,好消息是對于我們的插樁方案一樣適用,因為都是基于babel編譯。并且得力于得力于公司內(nèi)部的react native項目結(jié)構(gòu)統(tǒng)一,我們將編譯時插樁做到了流水線中,在流水線中分別打包“正常包”和”插樁包“,這樣搭配UI自動化可以形成一套完整的錄制回放覆蓋率指標收集的測試體系。

利用websocket暴露模擬器內(nèi)覆蓋率數(shù)據(jù):

// 創(chuàng)建WebSocket連接
const socket = new WebSocket('ws://localhost:8080');


// 當WebSocket連接打開時觸發(fā)
socket.onopen = () => {
    console.log('Connected to coverage WebSocket server');
};


// 當收到WebSocket消息時觸發(fā)
socket.onmessage = event => {
    try {
      if (JSON.parse(event.data).type === 'getcoverage') {
        // 發(fā)送覆蓋率數(shù)據(jù)
        socket.send(JSON.stringify(payload));
      }
    } catch (e) {
      console.log(e);
    }
};


// 當WebSocket連接關(guān)閉時觸發(fā)
socket.onclose = () => {
    console.log('Disconnected from coverage WebSocket server');
};

目前攜程機票部門的APP模塊均已接入Canyon,經(jīng)過實踐istanbuljs可以很好的對其進行插樁及覆蓋率數(shù)據(jù)收集,測試團隊在每次生產(chǎn)發(fā)布前會以Canyon的覆蓋率數(shù)據(jù)指標來衡量此次發(fā)布的質(zhì)量情況。

十、覆蓋率提升優(yōu)先級列表

在用戶最初接入Canyon系統(tǒng)時,會面臨一個挑戰(zhàn):如果沒有大量的UI自動化測試用例,大型應(yīng)用的代碼覆蓋率會顯得尤為低下。一開始,僅僅提供一個Istanbul代碼覆蓋率報告,并不能有效指導(dǎo)團隊如何提高覆蓋率,這讓大家感到困惑和無所適從。

為了解決這個問題,我們進行了深入的調(diào)研,并發(fā)現(xiàn)公司已經(jīng)有了一個成熟的生產(chǎn)環(huán)境代碼覆蓋率收集系統(tǒng)。基于這一發(fā)現(xiàn),我們決定將這個系統(tǒng)的數(shù)據(jù)與我們自己的覆蓋率數(shù)據(jù)相結(jié)合,創(chuàng)建了一個“覆蓋率提升優(yōu)先級列表”。這個列表的目的是為開發(fā)團隊提供明確的指引,幫助他們了解在哪些方面可以優(yōu)先提升代碼覆蓋率。

為了使這個指引更加科學和實用,我們制定了一個覆蓋率權(quán)重公式:

生產(chǎn)環(huán)境覆蓋率×100×0.3 + (1 - 測試覆蓋率)×100×0.3 + 函數(shù)數(shù)量×0.2

通過這個公式,我們能夠優(yōu)先識別出那些生產(chǎn)環(huán)境使用率高、行數(shù)多,測試覆蓋率低的代碼文件,從而為開發(fā)團隊提供針對性的提升建議。這樣的方法不僅提高了代碼質(zhì)量,也增強了我們對整體覆蓋率的掌控。

十一、社區(qū)推廣

從這篇文章發(fā)表時起,我們將正式開源Canyon。JavaScript是時下最流行的編程語言,但是端到端測試覆蓋率收集領(lǐng)域一直空白,我們的代碼開發(fā)基于了istanbuljs,monaco editor等優(yōu)秀開源項目,我們有信心推出Canyon開源可以贏得社區(qū)的反響,并且可以有大量JavaScript開發(fā)者參與進來。

Canyon在未來還有很大發(fā)展空間,例如生產(chǎn)環(huán)境插樁收集還未有待驗證嘗試,與playwright、puppeteer、cypress等自動化測試的工具還沒有深度鏈接,這些都已經(jīng)規(guī)劃到了未來的開發(fā)計劃中。希望在未來Canyon可以在攜程及社區(qū)里有更多人參與建設(shè)。

責任編輯:張燕妮 來源: 攜程技術(shù)
相關(guān)推薦

2011-11-01 10:10:48

ScriptCover

2012-04-11 11:21:57

ibmdw

2022-05-31 09:01:18

SwiftApp 項目

2023-10-27 08:49:00

JCovOpenJDK

2021-12-25 22:30:27

Chrome DevTJavaScript調(diào)試工具

2019-09-25 09:20:41

谷歌代碼開發(fā)者

2017-01-20 09:45:20

JavaScript代碼質(zhì)量

2021-10-15 13:47:19

覆蓋率檢測 istanbul 總代碼的比例

2011-04-25 09:49:20

代碼測試

2012-09-21 10:30:56

Linux項目代碼覆蓋率

2016-01-13 10:14:15

WebPHP函數(shù)覆蓋

2015-11-09 17:56:57

WebPHP函數(shù)覆蓋

2025-03-04 00:00:33

2022-05-13 09:40:51

代碼可行應(yīng)用性能

2022-10-21 15:29:32

5G網(wǎng)絡(luò)

2022-03-25 09:22:42

代碼開發(fā)

2022-08-25 06:27:39

vivoJaCoCo代碼覆蓋率

2024-09-03 14:10:00

模型測試

2019-09-30 10:27:52

變異測試評估

2025-05-08 01:44:00

RussGo調(diào)試
點贊
收藏

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

久久成人羞羞网站| 精品影院一区| 久久美女视频| 欧美裸体bbwbbwbbw| 亚洲国产午夜伦理片大全在线观看网站 | 免费看日韩精品| 久久精品最新地址| 一本色道久久hezyo无码| 在线中文字幕播放| 国产精品免费免费| 国产精品裸体一区二区三区| 中文字幕激情小说| 五月天久久777| 精品国产一区二区亚洲人成毛片| 国产精品沙发午睡系列| 日韩黄色影院| 91视频一区二区三区| 国产精品日韩欧美| 国产精品第108页| 日韩精品欧美| 日韩电影中文字幕在线观看| 色综合色综合色综合色综合| 日本大片在线播放| 国产精品毛片大码女人| 91免费精品国自产拍在线不卡| 精品欧美久久久| 国产精品69页| 久草在线资源站资源站| 国产精品美女一区二区| 久久久综合亚洲91久久98| 国产麻豆免费视频| 老司机精品视频网站| 欧美极品少妇与黑人| 黑人狂躁日本娇小| 美女亚洲一区| 亚洲第一福利网| 成人在线短视频| 国产69精品久久久久9999人| 日韩欧美一区二区三区四区| 麻豆影视在线播放| 大胆日韩av| 日韩成人av在线| 欧美黄网在线观看| 久久久久亚洲av无码专区桃色| 男人亚洲天堂| 在线亚洲一区二区| 免费看又黄又无码的网站| 色a资源在线| yellow在线观看网址| 久久色在线视频| 国产精品青青草| 久热精品视频在线观看一区| 日韩欧美不卡在线| 超碰在线观看免费| 亚洲欧洲国产日韩| 亚洲春色在线| av黄色在线观看| 亚洲国产精品成人久久综合一区| 蜜桃网站成人| 人成在线免费视频| 久久香蕉国产线看观看99| 国产精品果冻传媒潘| 性生交大片免费看女人按摩| 国产一区不卡视频| 国产欧美一区二区三区久久 | 亚洲色图欧美视频| 成人免费av在线| 国产欧美一区二区视频| 天堂中文在线官网| 91丝袜美腿高跟国产极品老师| 国产在线欧美日韩| 欧美一区二区少妇| 亚洲国产电影在线观看| 亚洲精品欧洲精品| 成人在线免费看黄| 亚洲国产精品久久久男人的天堂| 色香蕉在线观看| 神马午夜伦理不卡| 亚洲不卡av一区二区三区| 男女视频网站在线观看| 最近高清中文在线字幕在线观看1| 日韩欧中文字幕| 在线免费视频a| 高清久久精品| 亚洲激情第一页| 日本人亚洲人jjzzjjz| 99久久精品网| 国语自产精品视频在线看| av大片在线免费观看| 日韩成人免费在线| 国产日韩欧美另类| 国产成人免费看一级大黄| 成人激情免费网站| 日韩av一区二区三区在线| 秋霞午夜理伦电影在线观看| 亚洲综合色丁香婷婷六月图片| 欧美性猛交内射兽交老熟妇| 亚洲美女炮图| 欧美剧情电影在线观看完整版免费励志电影| xxx中文字幕| 蜜臀av免费一区二区三区| 最新日韩中文字幕| 国产精品999久久久| 日韩av在线播放中文字幕| 91久久精品www人人做人人爽| 日本私人网站在线观看| 成人欧美一区二区三区| 国产精品无码一区二区在线| 欧美网站免费| 亚洲国产成人在线播放| 久久久久99精品成人| 伊人久久大香线蕉av超碰演员| 国产精品2018| 日本黄色一区二区三区| 国产精品久久久久久久久免费樱桃 | 国产91精品不卡视频| ,亚洲人成毛片在线播放| 成人免费高清在线观看| 三年中文高清在线观看第6集| 日韩欧美一中文字暮专区| 欧美久久一区二区| 中国女人特级毛片| 亚洲精品少妇| 91丝袜脚交足在线播放| 91美女视频在线| 福利一区视频在线观看| 91香蕉在线观看| 大陆成人av片| 亚洲精品在线免费看| cao在线视频| 7777精品伊人久久久大香线蕉完整版| 好吊一区二区三区视频| 91精品电影| 日韩理论片中文av| 91国产精品电影| 99er热精品视频| 中文字幕免费不卡| 欧美精品一区二区三区免费播放| 开心久久婷婷综合中文字幕 | 免费av一级片| 亚洲少妇屁股交4| 亚洲娇小娇小娇小| 欧美伦理在线视频| 日韩免费观看网站| 牛牛热在线视频| 精品国产鲁一鲁一区二区张丽| 伊人精品视频在线观看| 99精品综合| 91精品国产自产在线老师啪| 美国成人xxx| 欧美精品一级二级三级| 永久免费成人代码| 国产午夜久久| 久草精品电影| 欧美男人天堂| 日韩国产精品一区| 日本va欧美va国产激情| jlzzjlzz亚洲日本少妇| 成品人视频ww入口| 久本草在线中文字幕亚洲| 欧美精品福利在线| 欧美熟妇乱码在线一区| 亚洲va韩国va欧美va精品| 亚洲啪av永久无码精品放毛片 | 欧美黄色片免费观看| 亚洲在线精品视频| 国产精品嫩草影院com| jizz大全欧美jizzcom| 国产91精品一区| 国产精品资源在线看| 一区在线电影| 成人自拍视频| 成人美女免费网站视频| av亚洲在线| 欧美在线999| 一级免费黄色录像| 久久久www成人免费精品| 国产一区二区三区四区五区六区| 亚洲综合丁香| 免费试看一区| 懂色aⅴ精品一区二区三区| 日韩小视频在线观看| 99久久精品国产色欲| 亚洲综合色区另类av| 网站免费在线观看| 波多野结衣不卡| 国内精品久久久久久久久电影网 | 欧美一级特黄aaa| 99久久99久久精品国产片桃花 | 免费黄色av片| 国产精品18久久久| 2018日日夜夜| 久久综合色占| 91免费看片网站| 国产91足控脚交在线观看| 亚洲国产一区二区三区四区| 日日夜夜操视频| 亚洲人成伊人成综合网小说| 国产性猛交96| 玖玖玖国产精品| 中文字幕免费高| 青青草这里只有精品| 国产日韩在线免费| 2021天堂中文幕一二区在线观| 国产亚洲成av人片在线观看桃| 国产乱人乱偷精品视频a人人澡| 亚洲一区中文在线| 国产123在线| 国产高清视频一区| 国产熟人av一二三区| 欧美成人午夜| 亚洲综合一区二区三区| 能看毛片的网站| 久久久久国产精品一区二区 | 免费成人黄色大片| 激情综合亚洲| 桥本有菜av在线| 免费看成人吃奶视频在线| 欧美色爱综合网| 欧美一级二级三级九九九| 欧美激情不卡| 91av成人在线| 欧洲在线视频| 色一情一乱一区二区| 性xxxfllreexxx少妇| 在线成人小视频| 国产成人无码专区| 精品久久中文字幕| 久草视频免费在线| 成人欧美一区二区三区在线播放| 亚洲天堂久久新| 国产成人精品免费| 九九热在线免费| 羞羞视频在线观看欧美| 亚洲精品国产suv一区88| 91视频一区| 日韩高清三级| 少妇精品久久久一区二区三区| 成人免费视频国产在线观看| 国产又粗又长又大的视频| 国产精品久久国产愉拍| 99久久免费观看| 91精品电影| 伊人情人网综合| 日韩理论在线| 亚洲国内在线| 青青草这里只有精品| 国产视色精品亚洲一区二区| 久久久久亚洲精品中文字幕| 成人有码在线视频| 午夜精品久久久久久毛片| 国产精品丝袜视频| 欧美另类激情| 91精品在线国产| 亚洲日本免费电影| 成人中心免费视频| 国产中文欧美日韩在线| 91久久夜色精品国产网站| 99久久999| 91中文字幕一区| 日韩三级久久| 国产精品免费一区二区三区四区| 97品白浆高清久久久久久| 日本欧美一区二区在线观看| 日本日本19xxxⅹhd乱影响| 日韩视频不卡| 成熟老妇女视频| 日韩有码一区二区三区| 美女网站视频黄色| 精品一区二区精品| 久久精品一二三四| k8久久久一区二区三区| 久操视频免费看| 亚洲国产激情av| 免费在线观看h片| 亚洲风情在线资源站| 精品成人av一区二区在线播放| 欧美性69xxxx肥| 中文字幕欧美色图| 日韩一区二区三区免费观看| 丰满岳乱妇国产精品一区| 亚洲激情视频在线| 成人免费在线电影| 欧美精品生活片| 三妻四妾的电影电视剧在线观看| 国产成人综合亚洲| 国产乱码精品一区二区三区亚洲人| 91久久精品国产91久久性色tv | 亚洲一区二区三区久久 | 欧美日韩国产高清一区二区三区 | 毛片av一区二区| 天天色天天干天天色| a美女胸又www黄视频久久| 亚洲国产欧洲综合997久久| 99在线观看精品视频| 欧美不卡激情三级在线观看| 久热av在线| 日韩有码片在线观看| caoporn-草棚在线视频最| 国产ts一区二区| 亚洲在线资源| 国内精品国语自产拍在线观看| 精品成av人一区二区三区| 亚洲av综合色区| 久久婷婷久久| 2018国产精品| 中文字幕不卡的av| 国产亚洲自拍av| 欧美婷婷六月丁香综合色| 欧美视频一二区| 日韩在线观看免费| 一本大道色婷婷在线| 亚洲va欧美va在线观看| 久久av综合| 国产精品网站在线看| 91精品国产91久久久久久不卡 | 亚洲色图一区二区| 精品欧美一区二区三区免费观看 | 欧美激情综合色| 成人不卡视频| 精品一区二区日本| 自拍偷拍欧美| 美女一区二区三区视频| 成人av资源在线| 国产老头老太做爰视频| 精品人人人人| 久久资源av| 欧美日韩精品免费观看视频完整| 亚洲五月天综合| 国产一区二区| 精品99999| 日本三级在线视频| 欧美一区二区大胆人体摄影专业网站| 永久免费观看精品视频| 人偷久久久久久久偷女厕| 99精品福利视频| 亚洲av综合色区无码另类小说| 国产精品国产精品国产专区不片| www毛片com| 亚洲九九九在线观看| 鲁鲁在线中文| 国产免费一区| 影院欧美亚洲| 一区二区三区四区影院| 亚洲精品视频在线看| 国产又色又爽又黄又免费| 一本久久综合亚洲鲁鲁| 美女100%一区| 韩漫成人漫画| 国产精品黄色av| 亚洲精品456| 浮妇高潮喷白浆视频| 成人h精品动漫一区二区三区| 黄色a级片在线观看| 在线播放/欧美激情| 韩国中文字幕在线| 成人性生交xxxxx网站| 中文字幕日韩一区二区不卡 | 久久99精品国产99久久| 亚洲激情午夜| 日韩精品人妻中文字幕有码| 亚洲国产视频在线| 丰满肥臀噗嗤啊x99av| 91国内免费在线视频| 欧美影院天天5g天天爽| 国产最新免费视频| 久久久综合激的五月天| 极品国产91在线网站| 欧美三级在线| 国产清纯白嫩初高中在线观看性色| 一区二区三区中文字幕精品精品| 亚洲精华国产精华精华液网站| 久久人人爽人人爽人人片av高请 | 欧美日韩亚洲精品内裤| 伊人情人网综合| 精品久久久中文字幕| 99re精彩视频| 亚洲三级电影网站| 亚洲国产精品suv| 国内成人精品视频| 精品一级毛片| 手机在线国产视频| 亚洲午夜影视影院在线观看| 日韩精品123| 国产欧美日韩高清| 国内精品久久久久久久97牛牛 | 成人精品一区二区三区四区 | 51国偷自产一区二区三区的来源| 黄色成人在线网址| 欧洲美一区二区三区亚洲| 欧美军同video69gay| heyzo中文字幕在线| 日韩福利影院| 大美女一区二区三区| 涩涩视频在线观看| 九色成人免费视频| 国产欧美日韩视频在线| 男人女人拔萝卜视频| 一本大道久久a久久精二百| 黄色免费在线看|