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

使用 React Testing Library 的 15 個常見錯誤

開發 前端
作為測試庫工具系列的維護者,我們盡最大努力使 API 能夠引導人們盡可能有效地使用,一些不足之處,我們會嘗試正確地記錄下來,即使這會非常地困難(尤其是 API 改動/升級等)。

哈嘍,大家好。以前的我(Kent)并不是很喜歡那個時候的測試環境,為此寫了一個 React Testing Library。它是原來 DOM Testing Library 的一個擴展,隨著不斷更新迭代,現在 Testing Library 的實現也能支持當下所有流行的 JS 框架和工具來定位組件中的 DOM 了。

隨時代發展,我們也對這個庫的 API 做了很多修改,同時也發現社區中有很多不怎么優雅的使用方式。雖然我們已經很努力地在文檔里寫要怎么 “更好地” 使用我們提供的工具 API,但我還是在別的文章和博客中看到他們在用這些不優雅的使用方法。接下來,我就一一盤點這些方法,解釋為什么它們不是很好,以及如何改進測試以避免這些陷阱。

注:下面是重要程度的說明。

低:一般為我的主觀想法,如果你覺得使用上沒啥問題可以忽略它

中:如果你不遵循,可能會出現 Bugs、低效的測試用例、還可能會做額外的工作

高:一定要用我建議的方法。不然很有可能你會遇到大問題,而且測試用例并不怎么高效

沒有使用 Testing Library 的 ESLint 插件

重要程度:中

如果你想避免這些常見的錯誤,那么官方的 ESLint 插件可以給你帶來很多幫助:

  • eslint-plugin-testing-library
  • eslint-plugin-jest-dom

注:如果你已經在用 create-react-library,那 eslint-plugin-testing-library 已經包含包在依賴中了

建議:最好把這兩個 ESLint 插件都裝上。

還在用 Wrapper 作為 render 返回值的變量名

重要程度:低

// ?
const wrapper = render(<Example prop="1" />)
wrapper.rerender(<Example prop="2" />)

// ?
const {rerender} = render(<Example prop="1" />)
rerender(<Example prop="2" />)

Wrapper 是以前 Enzyme 的過時用法,現在已經不需要它了。而且 render 的返回值里也并沒有 Wraper 任何東西,它只是一些工具 API 的集合而已。所以,一般情況下可以不需要它了。

建議:直接使用從 render 返回值解構出來的東西,或者將返回值命名為 view。

手動使用 cleanup

重要性:中

// ?
import {render, screen, cleanup} from '@testing-library/react'

afterEach(cleanup)

// ?
import {render, screen} from '@testing-library/react'

現在cleanup 都是自動調用的,所以你已經不再需要再考慮它了。詳見這里。

建議:別手動調 cleanup

不用 screen

重要程度:中

// ?
const {getByRole} = render(<Example />)
const errorMessageNode = getByRole('alert')

// ?
render(<Example />)
const errorMessageNode = screen.getByRole('alert')

screen 是在 DOM Testing Library v6.11.0 引入的 (就就是說,你可以在 @testing-library/react@>=9 這些版本中使用它)。直接在 render 引入的時候一并引入就可以了:

import {render, screen} from '@testing-library/react'

使用 screen 的好處是:在添加/刪除 DOM Query 時,不需要實時地解構 render 的返回值來獲取內容。輸入 screen,你的編輯器就能自動補全它里面的 API 了。

除非一種情況:你在配置 container 或者 baseElement。不過,你應該避免使用它們(因為我實在想不出使用它們的現實場景,除非你是在處理一些歷史遺留問題)。

你也可以直接調 screen.debug 而不是 debug。

建議:用 screen 來做 Querying 和 Debugging

使用錯誤的斷言 API

重要程度:高

const button = screen.getByRole('button', {name: /disabled button/i})

// ?
expect(button.disabled).toBe(true)
// error message:
// expect(received).toBe(expected) // Object.is equality
//
// Expected: true
// Received: false

// ?
expect(button).toBeDisabled()
// error message:
// Received element is not disabled:
// <button />

建議:用 @testing-library/jest-dom 這個庫

將不必要的操作放在 act 里

重要程度:中

// ?
act(() => {
render(<Example />)
})

const input = screen.getByRole('textbox', {name: /choose a fruit/i})
act(() => {
fireEvent.keyDown(input, {key: 'ArrowDown'})
})

// ?
render(<Example />)
const input = screen.getByRole('textbox', {name: /choose a fruit/i})
fireEvent.keyDown(input, {key: 'ArrowDown'})

我經常看到不少人像上面那樣把一些操作放在 act 里,因為他們一看到 "act" 的 Warning,就把操作放在 act 里面,以此去掉 Warning。但他們不知道的是 render 和 fireEvent 已經包裹在 act 里了!所以這樣么其實沒啥卵用。

大多數時間,如果你看到這些 act 的 Warning,不是要讓你無腦地干掉它們,是在告訴你:你的測試有問題了。可以看這里的視頻來了解更多:Fix the "not wrapped in act(...)" warning。

建議:去了解什么時候應該用 act,別把啥東西都往 act 里放

使用錯誤的 Query

重要程度:高

// ?
// 假設你有這樣的 DOM:
// <label>Username</label><input data-testid="username" />
screen.getByTestId('username')

// ?
// 改成通過關聯 label 以及設置 type 來訪問 DOM
// <label for="username">Username</label><input id="username" type="text" />
screen.getByRole('textbox', {name: /username/i})

我們文檔里一直有維護一個頁面:“Which query should I use?”。你應該按這個頁面中的順序來使用 Query API。如果你的目標和我們的一樣,都想通過測試來確保用戶在使用時應用能夠正常工作的話,那你就要盡量用更接近用戶的使用方式來查詢 DOM。我們提供的 Query 都能幫你做到這一點,但并非所有 Query API 都是一樣的。

使用 container 來查詢元素

作為 “使用錯誤的 Query” 的子集,我想聊一下直接用 container 來查詢元素的問題:

// ?
const {container} = render(<Example />)
const button = container.querySelector('.btn-primary')
expect(button).toHaveTextContent(/click me/i)

// ?
render(<Example />)
screen.getByRole('button', {name: /click me/i})

實際上我們更希望用戶能直接和 UI 進行交互,然而,如果你用 querySelector 這些來做查詢的話,不僅我們不能模仿用戶的 UI 交互行為,測試代碼也會變得很難讀,而且容易崩。這和下面這一節也有關系:

沒有用文本來做查詢

作為 “使用錯誤的 Query” 的子集,我想聊一下為什么我們更建議你用真實的文本來做查詢(關于地區語言,應該用默認的地區語言文本),而不是用 Test ID 以及別的一些機制。

// ?
screen.getByTestId('submit-button')

// ?
screen.getByRole('button', {name: /submit/i})

如果不用真實的文本來查詢,那你要做很多額外的工作,因為你要確保你的地區語言的翻譯轉換是正確的。這里肯定有多人會吐槽說:要是別人改了文本的內容,你的測試不就崩了么?我對此的反駁是,首先,如果有人將 “UserName” 更改為 “Email”,這是我絕對想知道的變更(因為我需要更改我的實現了)。而且,就算有人因為改了個名搞崩了測試,修復測試也用不了多長時間,馬上就能修好了。

總的來說,修復的成本是很低的,而好處則是可以增加你對翻譯正確性信心,而且寫出來的測試也是容易閱讀和修改的。

還是要聲明一下,并不是所有人都同意我這個觀點的,具體可以看下 Twitter 上的這個 Thread。

多數情況下沒有使用 *ByRole

作為 “使用錯誤的 Query” 的子集,我想來聊聊 *ByRole。在最近 RTL 的幾個版本里,對 *ByRole 相關的 Query API 都做了很多的升級,這了是對組件渲染輸出做查詢操作最推薦的方法。下面是我比較喜歡它的一些功能。

name 選項可以讓你通過元素的 "Accessible Name" 查詢元素,這也是 Screen Reader 會對每個元素讀取的內容。好處是:即使元素的文本內容被其它不同元素分割了,它還是能夠以此做查詢。比如:

// 假如現在我們有這樣的 DOM://

// 假如現在我們有這樣的 DOM:
// <button><span>Hello</span> <span>World</span></button>

screen.getByText(/hello world/i)
// ? 報錯:
// Unable to find an element with the text: /hello world/i. This could be
// because the text is broken up by multiple elements. In this case, you can
// provide a function for your text matcher to make your matcher more flexible.

screen.getByRole('button', {name: /hello world/i})
// ? 成功!

人們不使用 *ByRole 做查詢的原因之一是他們不熟悉在元素上的隱式 Role。,沒關系,大家可以參考 MDN,MDN 上有寫這些元素上的 Role List。

另一個我喜歡這個 API 的功能是:如果不能通過指定好的 Role 找到元素,它不僅會像 get* 以及 find* API 一樣把整個 DOM 樹都打印出來,而且還會把當前能訪問的 Role 都打印出來!

// 假設我們有這樣的 DOM
// <button><span>Hello</span> <span>World</span></button>
screen.getByRole('blah')

上面會報這樣的錯誤:

TestingLibraryElementError: Unable to find an accessible element with the role "blah"

Here are the accessible roles:

button:

Name "Hello World":
<button />

--------------------------------------------------

<body>
<div>
<button>
<span>
Hello
</span>

<span>
World
</span>
</button>
</div>
</body>

這里要注意的是,我們并沒有為設置 Role 而加上 role=button。因為這是隱式的 Role,下一節會詳細說明。

建議:閱讀并根據 “Which Query Should I Use" Guide” 里的推薦順序來使用 Query

錯誤地添加可訪問屬性:aria-,role

重要程度:高

// ?
render(<button role="button">Click me</button>)

// ?
render(<button>Click me</button>)

像上面那樣隨意添加/修改可訪問屬性(Accessibility Attributes)不僅沒有必要,而且還會把 Screen Reader 和用戶搞懵。只有當無法滿足當前的 HTML 語義時(比如你寫了一個非原生的 UI 組件,同時也要讓它 像 AutoComplete 一樣可訪問),你才應該使用可訪問屬性。假如這就是你現在要開發的東西,那可以用現有的第三庫根據 WAI-ARIA 實踐來實現可訪問性。它們一般會有一些 很好的樣例來參考。

注意:如果要讓 input 可以通過 role 來訪問,你需要指定對應的 type 屬性值!

建議:避免錯誤地添加不必要的或不正確的可訪問屬性

沒有使用 @testing-library/user-event

重要程度:高

// ?
fireEvent.change(input, {target: {value: 'hello world'}})

// ?
userEvent.type(input, 'hello world')

@testing-library/user-event 是在 fireEvent 基礎上實現的,但它提供了一些更接近用戶交互的方法。上面這個例子中,fireEvent.change 其實只觸發了 Input 的一個 Change 事件。但是 type 則可以對每個字符都會觸發 keyDown、keyPress 和 keyUp 一系列事件。這能更接近用戶的真實交互場景。好處是可以很好地和你當前那些沒有監聽 Change 事件的庫一起使用。

我們現在還在進行 @testing-library/user-event 這個庫的開發,來保證它能像它承諾的那樣:能夠觸發用戶在執行特定操作時會觸發的所有相同事件。不過,現在它還沒完全做到這一點,這也是為什么它還沒有合入 @testing-library/dom (可能在未來的某個時候會合入)。但是,我對它有足夠的信心,建議你多關注和使用它,而不是 fireEvent。

建議:盡可能地使用 @testing-library/user-event,而不是 fireEvent

沒有用 query* 來斷言元素不存在

重要程度:高

// ?
expect(screen.queryByRole('alert')).toBeInTheDocument()

// ?
expect(screen.getByRole('alert')).toBeInTheDocument()
expect(screen.queryByRole('alert')).not.toBeInTheDocument()

把暴露 query* 相關的 API 出來的唯一原因是:可以在找不到元素的情況下不會拋出異常(返回 null)。唯一的好處是可以用來判斷這個元素是否沒有被渲染到頁面上。這是很重要的,因為類似 get* 和 find* 相關的 API 在找不到元素時都會自動拋出異常 —— 這樣你就可以看到渲染的內容以及為什么找不到元素的原因。然而,query* 只會返回 null,所以 toBeInTheDocument 在這里最好的用法就是:判斷 null 不在 Document 上。

建議:query* API 只用于斷言當前元素不能被找到

用 waitFor 等待 find* 的查詢結果

重要程度:高

// ?
const submitButton = await waitFor(() =>
screen.getByRole('button', {name: /submit/i}),
)

// ?
const submitButton = await screen.findByRole('button', {name: /submit/i})

上面兩段代碼幾乎是等價的(find* 其實也是在內部用了 waitFor),但是第二種使用方法更清晰,而且拋出的錯誤信息會更友好。

建議:當查詢那些不能立馬能訪問到的元素時,使用 find*

給 waitFor 傳空 callback

重要程度:高

// ?
await waitFor(() => {})
expect(window.fetch).toHaveBeenCalledWith('foo')
expect(window.fetch).toHaveBeenCalledTimes(1)

// ?
await waitFor(() => expect(window.fetch).toHaveBeenCalledWith('foo'))
expect(window.fetch).toHaveBeenCalledTimes(1)

waitFor 的目的是可以讓你等一些指定的事情發生。如果傳了空的 callback,可能它在今天還能 Work,因為你只是想在 Event Loop 等一個 Tick 就好了。但這樣你也會留下一個脆弱的測試用例,一旦改了某些異步邏輯它很可能就崩了。

建議:在 waitFor 里等待指定的斷言,不要傳空 callback

一個 waitFor callback 里有多個斷言

重要程度:低

// ?
await waitFor(() => {
expect(window.fetch).toHaveBeenCalledWith('foo')
expect(window.fetch).toHaveBeenCalledTimes(1)
})

// ?
await waitFor(() => expect(window.fetch).toHaveBeenCalledWith('foo'))
expect(window.fetch).toHaveBeenCalledTimes(1)

在上面的例子中,如果 window.fetch 調用了兩次,那么 waitFor 就會失敗,但是我們就得等到超時了才能看到具體報錯。而如果 waitFor 里只有一個斷言,我們則可以等待 UI 渲染到斷言的同時,也可以在其中一個斷言失敗時更快地獲得報錯信息。

建議:waitFor 的 callback 里只放一個斷言

在 waitFor 中使用副作用

重要程度:高

// ?
await waitFor(() => {
fireEvent.keyDown(input, {key: 'ArrowDown'})
expect(screen.getAllByRole('listitem')).toHaveLength(3)
})

// ?
fireEvent.keyDown(input, {key: 'ArrowDown'})
await waitFor(() => {
expect(screen.getAllByRole('listitem')).toHaveLength(3)
})

waitFor 適用的情況是:在執行的操作和斷言之間存在不確定的時間量。因此,callback 可在不確定的時間和頻率(在間隔以及 DOM 變化時調用)被調用(或者檢查錯誤)。所以這也意味著你的副作用可能會被多次調用!

同時,這也意味著你不能在 waitFor 里面使用快照斷言(SnapShot Assertion)。如果你想要用快照斷言,首先要等待某些斷言走完了,然后再拍快照。

建議:把副作用放在 waitFor 回調的外面,回調里只能有斷言

用 get* 來做斷言

重要程度:低

// ?
screen.getByRole('alert', {name: /error/i})

// ?
expect(screen.getByRole('alert', {name: /error/i})).toBeInTheDocument()

雖然這不是什么大問題,但我還是想說下我的觀點。如果 get* API 找不到元素,它就會拋出異常,打印整個 DOM 樹結構(語法高亮),在 Debug 的時候很有用。也因為這點,斷言是永遠不可能失敗的(因為如果找不到元素,查詢在斷言之前拋出異常)。

因為這個原因,很多人直接不做斷言了。這其實也還好,但是我個人通常來說,會把斷言留著,這樣可以讓后面做重構、修改的人知道:這里不是個查詢操作,而是個斷言操作。

建議:如果你想斷言某個東西是否存在,那么就做顯式的斷言操作

總結

作為測試庫工具系列的維護者,我們盡最大努力使 API 能夠引導人們盡可能有效地使用,一些不足之處,我們會嘗試正確地記錄下來,即使這會非常地困難(尤其是 API 改動/升級等)。希望這篇文章會幫到你,我們只是想你更有信心地交付你的代碼。

Good Luck!

好了,這篇外文就給大家帶到這里了。翻譯這篇文章還是花不少時間的,同時也學到了很多 RTL 這個庫的一些思想,希望大家也能吸收里面一些測試思路。

責任編輯:武曉燕 來源: 寫代碼的海怪
相關推薦

2025-04-28 04:22:00

2020-03-19 14:50:31

Reac單元測試前端

2022-10-10 09:00:35

ReactJSX組件

2020-05-29 14:30:35

Kubernetes開發錯誤

2022-05-31 15:43:15

自動化測試

2021-03-09 09:52:55

技術React Hooks'數據

2024-09-18 11:27:57

2024-03-21 15:01:44

2021-11-26 05:50:50

Promise JS項目

2021-06-16 15:04:06

JavaScript內存開發

2020-03-20 15:10:09

Python錯誤分析代碼

2021-12-30 21:51:10

JavaScript開發內存

2019-10-14 16:39:50

云計算配置錯誤企業

2015-07-29 10:46:20

Java錯誤

2018-01-12 14:57:06

React Nativ開發錯誤

2018-01-11 16:29:19

錯誤HibernateJPQL

2009-08-27 11:12:04

C# foreach

2015-11-16 15:15:51

SaaS初創公司定價錯誤

2025-02-10 00:00:00

技巧JavaStreams

2019-08-13 11:32:55

物聯網技術大數據
點贊
收藏

51CTO技術棧公眾號

天天干天天操天天干天天操| 国产精品白嫩美女在线观看 | 亚洲一区二区三区免费在线观看| 亚洲精品91美女久久久久久久| av网站手机在线观看| 男男激情在线| 久久精品72免费观看| 国内精品久久久久| youjizz亚洲女人| 99ri日韩精品视频| 欧亚洲嫩模精品一区三区| 日本xxx免费| 欧美亚洲日本| 国产精品白丝jk黑袜喷水| 欧美中文字幕第一页| 天海翼在线视频| 日韩欧美四区| 日韩欧美一级二级| 黄色三级视频在线| av资源中文在线| 国产精品欧美久久久久一区二区| 国产伦精品一区二区三区高清 | 蜜乳av另类精品一区二区| 久久久国产一区| 日本免费福利视频| 欧美日本三级| 欧美日韩日日骚| 欧美女人性生活视频| 蜜臀av国内免费精品久久久夜夜| 中文字幕免费一区| 欧美精品一区三区在线观看| 国产黄频在线观看| 久久国产婷婷国产香蕉| 国产成人精品一区二区在线| 日韩激情在线播放| 欧美激情日韩| 久久久久北条麻妃免费看| 中文字幕av久久爽一区| 欧美中文一区| 欧美精品一区二区三区一线天视频| 国产色视频在线播放| 亚洲成人看片| 欧美三级免费观看| 免费国产a级片| japanese色国产在线看视频| 1024成人网色www| 亚洲精品美女久久7777777| 日本五码在线| 26uuu另类欧美亚洲曰本| 岛国视频一区| 国模私拍视频在线| 懂色av中文一区二区三区| 91沈先生播放一区二区| av中文字幕观看| 青青草华人在线视频| 欧美日韩国产系列| 成人黄色激情网| 最新黄色网址在线观看| 国产日韩1区| 欧美一区二区三区……| 国产精品xxxx喷水欧美| 99精品国产99久久久久久福利| 欧美黑人极品猛少妇色xxxxx| 精品99久久久久成人网站免费| 欧美.www| 欧美激情啊啊啊| 国产亚洲精品码| 极品av少妇一区二区| 97免费中文视频在线观看| 国产午夜视频在线播放| 一本久道久久久| 欧美在线视频免费| 天堂免费在线视频| 蜜臀av性久久久久av蜜臀妖精| 国产日韩欧美在线视频观看| 国产精品国产三级国产aⅴ| 国产精品自产自拍| 国产原创精品| 国产在线一二三区| 中文字幕中文字幕一区| a级片一区二区| 麻豆免费在线| 欧美性大战久久| 性鲍视频在线观看| 另类春色校园亚洲| 一区二区三区精品99久久| 小泽玛利亚一区| 一本一道久久综合狠狠老精东影业| 欧美在线视频在线播放完整版免费观看 | 欧美三级韩国三级日本三斤在线观看 | 豆国产96在线|亚洲| 麻豆av一区二区| 东热在线免费视频| 亚洲精品国产成人久久av盗摄 | 日韩av中文字幕一区二区三区| 成人av资源在线播放| 免费激情视频网站| 国产婷婷色一区二区三区| 人妻无码一区二区三区四区| 自拍偷拍欧美视频| 欧美夫妻性生活| 无码人妻aⅴ一区二区三区| 欧美成人直播| 97超级碰碰人国产在线观看| 一本到在线视频| 97久久精品人人做人人爽50路| 亚洲欧洲国产精品久久| 2020国产在线| 欧美日韩mp4| 日本高清www| 欧美成人一区二免费视频软件| 欧美一区二区三区艳史| 国产丝袜视频在线观看| 久久久九九九九| 黄色一级大片免费| 日本成人福利| 日韩国产高清污视频在线观看| 中文字幕第69页| 久久狠狠婷婷| 国产精成人品localhost| 亚洲精品承认| 色婷婷综合久久| 中文乱码人妻一区二区三区视频| 91综合网人人| 国产精品成人aaaaa网站| 全部免费毛片在线播放一个| 亚洲日本韩国一区| 538任你躁在线精品免费| 天天躁日日躁狠狠躁欧美巨大小说| 久久这里有精品| 一级特黄aaa| 亚洲国产高清aⅴ视频| 日本在线xxx| 一区二区三区视频免费视频观看网站| 最近中文字幕mv在线一区二区三区四区 | 亚洲自拍都市欧美小说| 欧美激情精品久久久久久大尺度| 91精品中文字幕| 亚洲国产激情av| 免费激情视频在线观看| 亚洲丝袜啪啪| 欧美亚洲国产另类| 视频一区二区三区在线看免费看| 亚洲成人动漫在线观看| 亚洲乱妇老熟女爽到高潮的片 | 一区二区视频免费| 国产日韩欧美高清| 欧美韩国日本在线| 蜜桃一区二区| 人体精品一二三区| 神马久久久久| 岛国视频午夜一区免费在线观看| 精品人妻伦一二三区久| 激情久久久久| 久久99国产精品| 中文字幕在线高清| 亚洲欧美制服丝袜| 亚洲中文一区二区| 国产精品三级电影| 999久久久精品视频| 一区二区三区国产精华| 亚洲综合中文字幕在线| 女子免费在线观看视频www| 日韩一级完整毛片| 日韩美女一级片| 26uuu精品一区二区在线观看| 日日摸天天爽天天爽视频| 精品美女视频| 成人av色在线观看| 另类视频在线| 亚洲精品日韩丝袜精品| 国产在线观看第一页| 国产精品国产自产拍高清av王其| 欧美一区二区三区影院| 伊人成年综合电影网| 麻豆亚洲一区| 日韩午夜视频在线| 欧美黄色www| 日本免费不卡| 欧美人妇做爰xxxⅹ性高电影| 动漫性做爰视频| 99久久久无码国产精品| 国产欧美高清在线| 911精品美国片911久久久 | a级片在线免费看| 亚洲成人免费看| 一级片久久久久| 国产精品一区二区久激情瑜伽| 成人免费视频91| 国产亚洲第一伦理第一区| 国产精品永久免费| 第一中文字幕在线| 亚洲偷熟乱区亚洲香蕉av| 国产精品久久久久久久久久久久久久久久久久 | 超碰超碰人人人人精品| www.美女亚洲精品| 免费观看黄色av| 欧美日韩综合一区| 日干夜干天天干| 亚洲欧洲精品天堂一级| 在线黄色免费网站| 精品一区二区三区免费视频| 国产 日韩 欧美在线| 国产精品一国产精品| 91九色在线免费视频| 免费观看成人性生生活片| 久久99久久99精品中文字幕| 大片免费播放在线视频| 精品免费日韩av| 中文字幕一区二区三区波野结| 亚洲国产色一区| 成人午夜免费影院| 久久理论电影网| 亚洲色图欧美另类| 久久国产精品第一页| 日本黄网站免费| 亚洲国产激情| 中文字幕乱码免费| 欧美综合一区| 欧美日韩在线播放一区二区| julia中文字幕一区二区99在线| 国产精品欧美亚洲777777| 麻豆网站免费在线观看| 欧美激情在线视频二区| 乱人伦中文视频在线| 亚洲最大在线视频| 亚洲 欧美 激情 另类| 欧美成人性战久久| 国产三级视频在线播放| 欧美日韩黄色影视| 中文字幕日韩三级| 欧美优质美女网站| 波多野结衣视频在线观看| 午夜在线成人av| 久久久久久久久97| 夜夜嗨av一区二区三区四季av| 91制片厂在线| 国产精品久久久久久户外露出| 亚洲人成人无码网www国产| 99精品黄色片免费大全| 欧产日产国产精品98| 国产99久久久国产精品潘金 | 成人av网站在线观看免费| 亚洲精品国产久| 国产精品一区一区| 免费人成视频在线播放| 国产一区二三区| 欧美性受xxxx黒人xyx性爽| 国内成人精品2018免费看| 亚洲免费成人在线视频| 激情偷乱视频一区二区三区| 夜夜夜夜夜夜操| 国产尤物一区二区在线| 日本在线观看视频一区| 极品美女销魂一区二区三区| 国产一区二区在线观看免费视频| 久久99热这里只有精品| 欧美视频国产视频| 国产精品一二一区| 色悠悠在线视频| 91麻豆国产福利精品| www.黄色在线| 国产精品精品国产色婷婷| 中文字幕人妻一区二| 亚洲一区二区三区在线看| 日韩av在线电影| 91福利在线看| 国产又粗又猛视频免费| 欧美一级在线免费| 蜜桃91麻豆精品一二三区| 日韩av在线网| 黄色大片在线看| 久久久久999| av日韩中文| 国产成人久久久精品一区| 久久精品97| 国产精品高清一区二区三区| 欧美日韩导航| 亚洲国产精品一区二区第四页av| 亚洲精品2区| 欧美网站免费观看| 麻豆精品在线播放| 日本中文字幕有码| 久久综合色综合88| 中日韩一级黄色片| 亚洲国产成人av好男人在线观看| 中文字幕精品无码一区二区| 7777精品伊人久久久大香线蕉经典版下载 | 亚洲人人精品| av五月天在线| 成人午夜私人影院| 欧美亚洲色综久久精品国产| 一区二区三区中文字幕在线观看| 国产精品男女视频| 91精品国产91久久久久久一区二区 | 婷婷久久综合网| 精品福利一区二区| 97超视频在线观看| 国产视频久久网| 成人在线网址| 日本成熟性欧美| 亚洲精品不卡在线观看| 日韩在线第一区| 99成人免费视频| 欧美性猛交xxxx乱大交91| 91免费看视频| 九九视频免费在线观看| 欧美探花视频资源| 色噜噜在线播放| 不卡av电影在线观看| 国产韩日精品| 精品欧美一区二区精品久久| 久久久久久美女精品| 午夜视频在线瓜伦| 99这里只有精品| 男女免费视频网站| 欧美电影一区二区三区| 成人午夜影视| 日本高清视频一区| youjizz亚洲| 51xx午夜影福利| 久久精品二区亚洲w码| 波多野结衣av在线观看| 懂色av中文一区二区三区天美| www.久久综合| 久久精品最新地址| 黄色成人小视频| 日韩亚洲视频| 久久午夜激情| 欧美xxxxx少妇| 一区二区三区不卡在线观看| 91肉色超薄丝袜脚交一区二区| 亚洲人成电影网站色www| 鲁鲁在线中文| 久久99精品久久久久久三级| 亚洲国产91| aaa黄色大片| 亚洲一二三区视频在线观看| 一级黄色片在线观看| 在线精品91av| av成人在线播放| 欧美在线播放一区二区| 久久国产精品99国产| 成人网站免费观看| 欧美日韩视频在线| 欧美视频综合| 日本精品免费一区二区三区| 一呦二呦三呦国产精品| 国产成人精品无码播放| 亚洲国产精品传媒在线观看| 国产成人自拍偷拍| 在线免费看av不卡| 成人福利片在线| 伊人av成人| 国产一区二三区好的| 国产a免费视频| 精品国产一二三区| 手机在线观看av| 欧美在线3区| 九九精品视频在线看| 日韩成人毛片视频| 精品国产免费久久| 中文在线а√天堂| 日本欧洲国产一区二区| 美国三级日本三级久久99| 成人在线观看高清| 日韩美女视频在线| 高清在线视频不卡| 日本视频精品一区| 极品少妇一区二区三区精品视频| 全程偷拍露脸中年夫妇| 精品福利二区三区| 天堂中文av在线资源库| 亚洲成人在线视频网站| 国产一区二区调教| 国产无遮挡裸体免费视频| 亚洲欧美日韩国产中文| 色综合.com| 国产自产在线视频| 久久精品一区八戒影视| 国产精品亚洲lv粉色| 国内精品小视频| 欧美综合视频| av av在线| 欧美性受极品xxxx喷水| 2024最新电影免费在线观看| 九九九九精品| 久久丁香综合五月国产三级网站| 久操视频免费在线观看| 国产亚洲免费的视频看| 日韩中文字幕无砖| 99热成人精品热久久66| 亚洲男人天堂一区| 蜜桃免费在线| 99免费在线视频观看| 日韩国产欧美视频| 久久亚洲成人av| 在线性视频日韩欧美| 欧美变态挠脚心| 亚洲第一区第二区第三区|