<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      測開新手學(xué)自動(dòng)化:分享幾點(diǎn)搭建自動(dòng)化測試框架經(jīng)驗(yàn)

      一、開頭說兩點(diǎn)

      傳統(tǒng)軟件測試行業(yè)是以手工測試為主,也就是所謂的點(diǎn)點(diǎn)點(diǎn),加上國內(nèi)軟件公司不注重測試,受制于大環(huán)境影響等也就給了大眾一種測試人員雖然身處互聯(lián)網(wǎng)行業(yè),卻是毫無技術(shù)可言的工種。

      話鋒一轉(zhuǎn),到了如今,不得不說一聲:大人,時(shí)代變了,最直觀的表現(xiàn)莫過于招聘要求的提高,越來越要求測試人員擁有七十二變的能力。而在這其中,自動(dòng)化測試能力是現(xiàn)在手工測試邁向更高技術(shù)崗位的必經(jīng)之路。

      大家好,我是黎潘,我又來了,作為一名行業(yè)新手,我也是興致滿滿,選擇了當(dāng)下較為火熱,且入門簡單的Python語言作為我邁向自動(dòng)化測試工程師的重要幫手。所以以下討論的皆是與python相關(guān)的如何實(shí)現(xiàn)自動(dòng)化的總結(jié),當(dāng)然肯定不止這一門語言可以實(shí)現(xiàn),最好與實(shí)際項(xiàng)目需求和個(gè)人能力相結(jié)合,選擇最適合自己的自動(dòng)化測試之路。

      二、初識(shí)自動(dòng)化測試

      廣義上來講,自動(dòng)化包括一切通過工具(程序)的方式來代替或輔助手工測試的行為都可以看作是自動(dòng)化。狹義上來講,通過工具記錄或編寫腳本的方式模擬手工測試的過程,通過回放或運(yùn)行腳本來執(zhí)行測試用例,從而代替人工對(duì)系統(tǒng)的功能進(jìn)行驗(yàn)證。通俗易懂點(diǎn)就是一切能代替手工來執(zhí)行測試用例,提高效率,不斷回歸的測試方法,在我眼里都能算是自動(dòng)化測試。

      2. 為什么要做自動(dòng)化測試

      2.1 減少手工測試占比

      自動(dòng)化測試可以替代大量的手工機(jī)械重復(fù)性操作,測試工程師可以把更多的時(shí)間花在更全面的用例設(shè)計(jì)新性功能的測試上。

      2.2 提升回歸效率

      自動(dòng)化測試可以大幅提升回歸測試的效率,測試人員不用花費(fèi)大量時(shí)間去校驗(yàn)原有功能的正確性,最大的優(yōu)點(diǎn)是非常適合敏捷開發(fā)過程中,也就是加入到CI/CD中。

      2.3 持續(xù)測試系統(tǒng)的穩(wěn)定

      自動(dòng)化測試可以高效實(shí)現(xiàn)某些手工測試無法完成或者代價(jià)巨大的測試類型。比如關(guān)鍵核心業(yè)務(wù)需要24小時(shí)持續(xù)運(yùn)行的穩(wěn)定性測試。

      2.4 增加競爭力

      隨著測試行業(yè)的發(fā)展,測試人們的發(fā)展方向越來越廣,技術(shù)方向越來越多樣化,更多的測試人傾向于往高技術(shù)攀爬。而擁有自動(dòng)化測試的能力在以后很有可能是我們選擇工作的敲門磚了。雖然不少人都對(duì)這種變化感到惶恐不安,但是更多的人選擇站在狂風(fēng)處,迎接挑戰(zhàn),增加自身的競爭力,擁抱明天。

      3. 什么項(xiàng)目適合自動(dòng)化測試

      3.1 需求穩(wěn)定,不頻繁變更

      測試腳本的穩(wěn)定性決定了自動(dòng)化測試的維護(hù)成本。如果軟件需求變動(dòng)過于頻繁,測試人員需要根據(jù)變動(dòng)的需求來更新測試用例以及相關(guān)的測試腳本,而腳本的維護(hù)本身就是一個(gè)代碼開發(fā)的過程,需要修改,調(diào)試,必要的時(shí)候還要修改自動(dòng)化框架,如果花費(fèi)的成本高于其節(jié)省的成本,那么自動(dòng)化測試是失敗的。

      我們可以優(yōu)先對(duì)項(xiàng)目中核心模塊,相對(duì)穩(wěn)定的模塊進(jìn)行自動(dòng)化,而變動(dòng)較大的仍是用手工測試。

      3.2 研發(fā)和維護(hù)周期長

      由于自動(dòng)化測試需求的確定,自動(dòng)化測試框架的設(shè)計(jì),測試腳本的編寫與調(diào)試均需要相當(dāng)長的時(shí)間來完成。這樣的過程本身就是一個(gè)測試軟件地開發(fā)過程,需要較長的時(shí)間來完成。如果項(xiàng)目周期比較短,沒有足夠的時(shí)間去支持這樣一個(gè)過程,那么自動(dòng)化測試便毫無意義。

      3.3 項(xiàng)目資源足夠

      自動(dòng)化測試從需求范圍的確定,到自動(dòng)化測試框架的設(shè)計(jì),以及腳本的編寫與調(diào)試,均需要相當(dāng)長的時(shí)間來完成。這樣的過程本身就是一個(gè)測試軟件的開發(fā)過程。因此有足夠的人力,物力非常重要。

      三、搭建自己的接口測試框架

      3.1 構(gòu)建接口測試思維

      當(dāng)前互聯(lián)網(wǎng)產(chǎn)品最大的特點(diǎn)就是,上線周期通常是以"天"甚至是以"小時(shí)"為單位,而傳統(tǒng)軟件產(chǎn)品的周期多以"月",甚至以"年"為單位。因此,如何在保證產(chǎn)品質(zhì)量下,有效縮短測試回歸時(shí)間成了重中之重。

      兩個(gè)突破口:

      • 引入測試的并發(fā)執(zhí)行,即從以往的串行執(zhí)行測試用例,采用分布式的方法并行執(zhí)行。
      • 從測試策略上找到突破口,從傳統(tǒng)軟件產(chǎn)品的金字塔測試策略往菱形測試策略轉(zhuǎn)變。以接口測試為主,GUI測試為輔,單元測試則根據(jù)公司實(shí)際情況進(jìn)行。

      四點(diǎn)建議:

      • 以中間層的API測試為重點(diǎn)做全面的測試
      • 輕量級(jí)的GUI測試,只覆蓋最核心直接影響主營業(yè)務(wù)流程的E2E場景
      • 最上層的GUI測試通常利用探索式測試思維,以人工測試的方式發(fā)現(xiàn)盡可能多的潛在問題
      • 單元測試只對(duì)那些相對(duì)穩(wěn)定并且核心的服務(wù)和模塊開展全面的單元測試,而應(yīng)用層或者上層業(yè)務(wù)只會(huì)做少量的

      3.2 搭建自己的接口測試框架

      3.2.1 為何要搭建自己的測試框架

      • 開發(fā)自己的框架更能結(jié)合自身工作中的痛點(diǎn),難點(diǎn)來做一個(gè)針對(duì)性的解決,使其擴(kuò)展性更高,后期也能接入CI/CD。
      • 利用現(xiàn)有工具來進(jìn)行接口測試,隨著項(xiàng)目的規(guī)模變大,維護(hù)成本將會(huì)增大,不利于管控。
      • 工具本身具有一定的局限性,如支持的協(xié)議比較單一。
      • 不用糾結(jié)技術(shù)選型,根據(jù)自身的技術(shù)實(shí)力和技術(shù)功底來選擇,而不要以開發(fā)工程師的技術(shù)棧來選擇。

      3.2.2 定義專屬框架目錄結(jié)構(gòu)

      • test_case:存放測試用例
      • test_data:存放測試數(shù)據(jù)
      • report:存放測試報(bào)告
      • common:存放公共方法
      • lib:存放第三方庫
      • config:存放環(huán)境配置信息
      • main:框架主入口
      • fixture:類似unittest中的setUp/tearDown的存在,但功能遠(yuǎn)比他們強(qiáng)大

      3.2.3 構(gòu)建框架流程

      在框架構(gòu)建過程中,由于篇符有限,本文只涉及其中部分環(huán)節(jié)。

      1、在common公共模塊、封裝定義框架專屬的http請(qǐng)求能力

      # !/usr/bin/python3
      # -*- coding: utf-8 -*-
      # @Author: pan-li
      import requests
      
      
      class HttpRequests(object):
      
          def __init__(self, url):
              self.url = url
              self.req = requests.session()
              # 自定義請(qǐng)求頭,根據(jù)自身所在公司項(xiàng)目需求
              self.headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}
      	
          # 封裝get請(qǐng)求
          def get(self, url='', params='', data='', headers=None, cookies=None):
              response = self.req.get(url=url, params=params, data=data, headers=headers, cookies=cookies)
              return response
      	
          # post請(qǐng)求
          def post(self, url='', params='', data='', headers=None, cookies=None):
              response = self.req.post(url=url, params=params, data=data, headers=headers, cookies=cookies)
              return response
      	
          # put請(qǐng)求
          def put(self, url='', params='', data='', headers=None, cookies=None):
              response = self.req.put(url=url, params=params, data=data, headers=headers, cookies=cookies)
              return response
      
          # delete請(qǐng)求
          def delete(self, url='', params='', data='', headers=None, cookies=None):
              response = self.req.delete(url=url, params=params, data=data, headers=headers, cookies=cookies)
              return response
      
      

      2、抽離URL生成url_conf.py在config文件中

      import enum
      
      
      class URLConf(enum.Enum):
          TEST_URL = 'http://10.12.7.20:8443/v2x-omp/api/'
      

      3、編寫接口測試用例在test_case文件中,第一版測試用例,安裝pytest,pip install -U pytest

      import os
      import sys
      import pytest
      import json
      from common.http_requests import *
      from config.url_conf import URLConf
      project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
      sys.path.append(project_root)
      
      class TestV2x:
      
          @classmethod
          def setup_class(cls) -> None:
              cls.url = URLConf.TEST_URL.value
              cls.http = HttpRequests(cls.url)
      
          def setup(self) -> None:
              self.headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}
              self.http = HttpRequests(self.url)
      
          def tearDown(self):
              pass
      
          @staticmethod
          def get_token():
              headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}
              response = TestV2x.http.post(url=URLConf.TEST_URL.value, data='{"cmd":"signin","params":{"userName":"smarttest","password":"72be4b7f62832c516b85fb26de59df53"}}', headers=headers)
              token = response.json()['detail']['token']
              return token
      
          def test_001_queryArea(self):
              """查詢區(qū)域"""
              playload = {"cmd": "queryArea", "csrfToken": TestV2x.get_token(), "params": {"cityId": "320200"}}
              response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)
              resultNote = response.json().get('resultNote')
              assert resultNote, 'Success'
      
          def test_002_queryYearlyCheckCount(self):
              """查詢年檢總數(shù)"""
              playload = {"cmd": "queryYearlyCheckCount", "Token": TestV2x.get_token(), "params": {}}
              response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)
              resultNote = response.json().get('resultNote')
              assert resultNote, 'SUCCESS'
      
          def test_003_queryTrafficEvent(self):
              """查詢交通事件"""
              playload = {"cmd": "queryTrafficEvent", "Token": TestV2x.get_token(), "params": {}}
              response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)
              resultNote = response.json().get('resultNote')
              assert resultNote, 'Success'
      
          def test_004_queryRsuCount(self):
              """查詢r(jià)su總數(shù)"""
              playload = {"cmd": "queryRsuCount", "Token": TestV2x.get_token(), "params": {}}
              response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)
              resultNote = response.json().get('resultNote')
              assert resultNote, '查詢路測設(shè)備數(shù)量成功!'
      
          def test_005_queryDeviceDetail(self):
              """查詢?cè)O(shè)備詳情"""
              playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": '0086860703231572'}, "Token": TestV2x.get_token()}
              response = TestV2x.http.post(self.url, data=json.dumps(playload), headers=self.headers)
              resultNote = response.json().get('resultNote')
              assert resultNote, '查詢終端信息成功!'
      
      
      if __name__ == '__main__':
          pytest.main()
      
      

      4、顯然前面的測試用例也是流水賬似的,還有很大的優(yōu)化空間,現(xiàn)在就來一步一步進(jìn)行。

      5、優(yōu)化一:利用feature特性優(yōu)化前置和后置條件,fixture目錄下的v2x_fixture.py文件

      import pytest
      from common.http_requests import HttpRequests
      from config.url_conf import URLConf
      
      
      @pytest.fixture(scope='function', autouse=True)
      def http():
          url = URLConf.TEST_URL.value
          http = HttpRequests(url)
          return http
      
      
      @pytest.fixture(scope='function', autouse=True)
      def get_token(http):
          headers = {'Content-Type': 'application/json', 'User-Agent': 'Node midway-v2x Version/1.28.1'}
          response = http.post(url=URLConf.TEST_URL.value,
                               data='{"cmd":"signin","params":{"userName":"smarttest","password":"72be4b7f62832c516b85fb26de59df53"}}',
                               headers=headers)
          token = response.json()['detail']['token']
          return token
      
      

      上述在引入feature之后,簡化了http請(qǐng)求的調(diào)用,重新定義http()來進(jìn)行調(diào)用。之前每次接口的調(diào)用都要附帶token參數(shù),現(xiàn)在把獲取token的方法提取出來,單獨(dú)封裝,加上feature的裝飾,他會(huì)作用與每一個(gè)方法,用起來更加方便。此處的token是依賴登陸接口之后返回的值,可根據(jù)自身項(xiàng)目的需求封裝。

      6、優(yōu)化二: 為測試用例添加數(shù)據(jù)驅(qū)動(dòng)模式

      # 以第五個(gè)測試用例單獨(dú)為例
      @pytest.mark.parametrize('deviceid', ['0086860703231572', '0086337601270714', '0086822412608154'])
          def test_005_queryDeviceDetail(self, http, get_token, deviceid):
              """查詢?cè)O(shè)備詳情"""
              playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": deviceid}, "Token": get_token}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), '查詢終端信息成功!'
              logger.info('查詢終端信息成功!')
      """直接利用pytest.mark.parametrize()裝飾器,第一個(gè)參數(shù)為參數(shù)名,后邊數(shù)組為測試數(shù)據(jù),用例當(dāng)中同樣添加形參deviceid"""
      

      在 pytest 中,數(shù)據(jù)驅(qū)動(dòng)是經(jīng)由 pytest 自帶的 pytest.mark.parametrize() 來實(shí)現(xiàn)的。 pytest.mark.parametrize 是 pytest 的內(nèi)置裝飾器,它允許你在 function 或者 class 上定義多組參 數(shù)和 fixture 來實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)。

      **@pytest.mark.parametrize() ** 裝飾器接收兩個(gè)參數(shù):

      • 第一個(gè)參數(shù)以字符串的形式存在,它代表能被被測試函數(shù)所能接受的參數(shù),如果被測試函數(shù)有多個(gè)參數(shù), 則以逗號(hào)分
      • 第二個(gè)參數(shù)用于保存測試數(shù)據(jù)。如果只有一組數(shù)據(jù),以列表的形式存在,如果有多組數(shù)據(jù),以列表嵌套元 組的形式存在

      7、優(yōu)化三: 為測試用例添加標(biāo)簽,此時(shí)用到pytest.ini配置文件,放在項(xiàng)目任意位置都能生效,有以下作用

      • 為你的測試框架定制用例查找規(guī)則
      • 為你的測試框架注冊(cè)標(biāo)簽名稱
      • 指定查找用例起始目錄
      [pytest]
      python_files = test_*  *_test test*
      python_classes = Test* test*
      python_functions = test_* test*
      
      markers =
          smoke: marks tests as smoke
          test : marks tests as test
          log : marks tests as log
      # 使用時(shí)只需要在測試用例上使用@pytest.mark.smoke即可
      # 執(zhí)行時(shí)pytest -m [標(biāo)記名]
      

      8、優(yōu)化四: 配置pytest.ini文件集成日志收集和實(shí)時(shí)控制臺(tái)打印功能

      [pytest]
      log_cli = 1
      log_cli_level = DEBUG
      log_cli_date_format = %Y-%m-%d-%H-%M-%S
      log_cli_format = %(asctime)s - %(filename)s - %(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
      log_file = ..\\report\\run.log
      log_file_level = DEBUG
      log_file_date_format = %Y-%m-%d-%H-%M-%S
      log_file_format = %(asctime)s - %(filename)s -%(name)s - %(module)s - %(funcName)s - %(lineno)d - %(levelname)s - %(message)s
      

      關(guān)于字段的詳解可以在終端輸入pytest --help 查看

      9、優(yōu)化五: 定制測試框架測試報(bào)告,屬于第三方應(yīng)用放在lib目錄中

      這里我們使用目前市面上使用人數(shù)較多的一款開源測試報(bào)告框架Allure,它支持絕大多數(shù)測試框架

      安裝方法:

      使用方法:

      • 執(zhí)行pytest命令,并指定allure報(bào)告目錄: pytest -v -s test_v2x_api_02.py --alluredir=./allure_reports
      • 在線生成allure報(bào)告:allure serve allure_reports
      • 生成本地allure報(bào)告:allure generate allure_reports

      當(dāng)然這只是在控制臺(tái)直接命令執(zhí)行,還不夠方便,如果我們想在其他環(huán)境運(yùn)行就又得配置環(huán)境變量,那么我們?nèi)绾伟阉傻轿覀兊目蚣苤心?/p>

      在共同方法中生成allure工具類,以便分辨運(yùn)行環(huán)境是windows還是mac

      import os
      import sys
      import platform
      
      
      path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'lib')
      allure_path = os.path.join(path, 'allure', 'bin')
      sys.path.append(allure_path)
      
      
      class Report():
          @property
          def allure(self):
              if platform.system() == 'Windows':
                  cmd = os.path.join(allure_path, 'allure.bat')
              else:
                  cmd = os.path.join(allure_path, 'allure')
              return cmd
      

      10、在main模塊中,添加執(zhí)行調(diào)度策略

      import os
      import threading
      import pytest
      
      from common.report import Report
      
      project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
      report_dir = os.path.join(project_root, 'report')
      result_dir = os.path.join(report_dir, 'allure_result')
      allure_report = os.path.join(report_dir, 'allure_report')
      report = Report()
      
      
      def run_pytest():
          pytest.main(['-v', '-s', f'--alluredir={result_dir}'])
      
      
      def general_report():
          cmd = "{} generate {} -o {} --clean".format(report.allure, result_dir, allure_report)
          print(os.popen(cmd).read())
      
      
      if __name__ == '__main__':
          run = threading.Thread(target=run_pytest)
          gen = threading.Thread(target=general_report)
          run.start()  # 多線程先執(zhí)行pytest命令生成測試報(bào)告
          run.join()
          gen.start()	# 報(bào)告生成后調(diào)用allure工具類生成本地報(bào)告
      

      11、最后一版測試用例,整合前面的優(yōu)化

      import os
      import sys
      import json
      from fixture.v2x_fixture import *
      from config.url_conf import URLConf
      project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
      sys.path.append(project_root)
      
      
      
      
      class TestV2x:
          @pytest.mark.smoke  # 標(biāo)簽的使用
          def test_001_queryArea(self, http, get_token):
              """查詢區(qū)域"""
              playload = {"cmd": "queryArea", "csrfToken": get_token, "params": {"cityId": "320200"}}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), 'success'
              logger.info('查詢區(qū)域成功')
      
          def test_002_queryYearlyCheckCount(self, http, get_token):
              """查詢年檢總數(shù)"""
              playload = {"cmd": "queryYearlyCheckCount", "Token": get_token, "params": {}}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), 'SUCCESS'
              logger.info('查詢年檢成功')
      
          def test_003_queryTrafficEvent(self, http,get_token):
              """查詢交通事件"""
              playload = {"cmd": "queryTrafficEvent", "Token": get_token, "params": {}}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), 'Success'
              logger.info('查詢交通事件成功')
      
          def test_004_queryRsuCount(self, http, get_token):
              """查詢r(jià)su總數(shù)"""
              playload = {"cmd": "queryRsuCount", "Token": get_token, "params": {}}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), '查詢路測設(shè)備數(shù)量成功!'
              # text = response.text
              # print(text)
              logger.info('查詢路側(cè)設(shè)備成功')
      	
          # 簡單的數(shù)據(jù)驅(qū)動(dòng)
          @pytest.mark.parametrize('deviceid', ['0086860703231572', '0086337601270714', '0086822412608154'])
          def test_005_queryDeviceDetail(self, http, get_token, deviceid):
              """查詢?cè)O(shè)備詳情"""
              playload = {"cmd": "queryDeviceDetail", "params": {"deviceId": deviceid}, "Token": get_token}
              response = http.post(url=URLConf.TEST_URL.value, data=json.dumps(playload), headers=URLConf.HEADERS.value)
              resultNote = response.json()
              assert resultNote.get('resultNote'), '查詢終端信息成功!'
              logger.info('查詢終端信息成功!')
      
      
      if __name__ == '__main__':
          # 打印更詳細(xì)的信息
          pytest.main(['-s', '-v', ])
      
      

      四、總結(jié)

      關(guān)于這次自動(dòng)化測試學(xué)習(xí)分享,涉及到的知識(shí),只是冰山一角,參加狂師老師的全棧測開訓(xùn)練營收獲非常大,還有很多的知識(shí)點(diǎn)沒有使用到,也就是我們的測試框架依然還有很多優(yōu)化的空間,后續(xù)我會(huì)繼續(xù),將細(xì)節(jié)補(bǔ)充到位,同時(shí)分享一些高階的用法。

      原文出自發(fā)表于:公眾號(hào):測試開發(fā)技術(shù)

      posted @ 2021-03-31 09:44  狂師  閱讀(865)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 午夜成人无码免费看网站| 精品人妻免费看一区二区三区| 亚洲天堂久久一区av| 人人妻人人澡人人爽曰本| 久久精品国产精品亚洲综合| 亚洲av无码乱码在线观看野外| 四虎成人精品国产永久免费| 精品国产成人国产在线观看 | 亚洲国产精品一区二区第一页| 亚洲成a人片在线观看中 | 久久无码人妻精品一区二区三区| 一区二区三区四区自拍视频| 看免费的无码区特aa毛片| 久久国内精品一国内精品| 中文字幕在线精品人妻| 亚洲熟女乱色一区二区三区| 日韩精品欧美高清区| 国产在线精品福利91香蕉| 国精产品一区一区三区有限公司杨 | 无码国内精品久久人妻蜜桃| 欧美精品久久天天躁| 国产一区国产二区在线视频| 亚洲国产成人综合精品| 狠狠色丁香婷婷综合尤物| 久久亚洲国产欧洲精品一| 国产精品十八禁一区二区| 国产日韩av二区三区| 日韩中文免费一区二区| 国产精品多p对白交换绿帽| 无套内谢少妇高清毛片| 色老头亚洲成人免费影院| 影音先锋人妻啪啪av资源网站| 草裙社区精品视频播放| 又粗又硬又黄a级毛片| 亚洲精品乱码久久久久久中文字幕| 色综合久久综合中文综合网| 天堂av成人网在线观看| 日本人成精品视频在线| 久久久久国精品产熟女久色| 亚洲天堂精品一区二区| 久久精品国产最新地址|