亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

對(duì)Ruby on Rails進(jìn)行高效的單元測(cè)試的教程

2020-02-24 15:37:26
字體:
供稿:網(wǎng)友

我們?cè)陂_發(fā)系統(tǒng)的時(shí)候需要對(duì)大量的數(shù)據(jù)進(jìn)行分析,這不僅需要準(zhǔn)確的數(shù)據(jù)分析,而且需要一定的速度,下文是武林技術(shù)頻道小編和大家分享的對(duì)Ruby on Rails進(jìn)行高效的單元測(cè)試的教程。

  • ??? 改變思路:能做到從需求到代碼的過程轉(zhuǎn)換,逐步細(xì)化;
  • ??? 簡(jiǎn)化代碼:力圖讓每個(gè)方法都很小,只專注一件事;
  • ??? 優(yōu)化代碼:當(dāng)測(cè)試代碼寫不出來,或者需要寫很長(zhǎng)的時(shí)候,說明代碼是有問題的,是可以被分解的,需要進(jìn)一步優(yōu)化;
  • ??? 便于擴(kuò)展:當(dāng)擴(kuò)展新業(yè)務(wù)或修改舊業(yè)務(wù)時(shí),如果測(cè)試代碼沒有成功,則說明擴(kuò)展和修改不成功;
  • ??? 時(shí)半功倍:貌似寫測(cè)試代碼很費(fèi)時(shí),實(shí)際在測(cè)試、部署和后續(xù)擴(kuò)展中,測(cè)試代碼將節(jié)省更多的時(shí)間。

環(huán)境搭建

筆者采用的測(cè)試環(huán)境是比較流行通用的框架:RSpec + Factory Girl,并用autotest自動(dòng)工具。RSpec是一種描述性語言,通過可行的例子描述系統(tǒng)行為,非常容易上手,測(cè)試用例非常容易理解。Factory Girl可以很好的幫助構(gòu)造測(cè)試數(shù)據(jù),免去了自己寫fixture的煩惱。Autotest能自動(dòng)運(yùn)行測(cè)試代碼,隨時(shí)檢測(cè)測(cè)試代碼的結(jié)果,并且有很多的插件支持,可以讓測(cè)試結(jié)果顯示的很炫。
第一步 安裝rspec和rspec-rails

在命令行中執(zhí)行如下命令:

$ sudo gem install rspec v = 1.3.0$ sudo gem install rspec-rails v = 1.3.2

安裝完成后,進(jìn)入rails應(yīng)用所在的目錄,運(yùn)行如下腳本,生成spec測(cè)試框架:

$ script/generate rspec       exists lib/tasks identical lib/tasks/rspec.rake identical script/autospec identical script/spec  exists spec identical spec/rcov.opts identical spec/spec.opts identical spec/spec_helper.rb

第二步 安裝factory-girl


在命令行中執(zhí)行如下命令:

$ sudo gem install rspec v = 1.3.0$ sudo gem install rspec-rails v = 1.3.2

安裝完成后,進(jìn)入rails應(yīng)用所在的目錄,運(yùn)行如下腳本,生成spec測(cè)試框架:

$ script/generate rspec       exists lib/tasks identical lib/tasks/rspec.rake identical script/autospec identical script/spec  exists spec identical spec/rcov.opts identical spec/spec.opts identical spec/spec_helper.rb

第二步 安裝factory-girl

在命令行中執(zhí)行如下命令:

$ sudo gem install factory-girl

在config/environment/test.rb中,加入factory-girl這個(gè)gem:

ruby.html="" tags="">ruby;">config.gem "factory_girl"

在spec/目錄下,增加一個(gè)factories.rb的文件,用于所有預(yù)先定義的model工廠。
第三步 安裝autotest

在命令行中執(zhí)行如下命令:

$ sudo gem install ZenTest$ sudo gem install autotest-rails

然后設(shè)置與RSpec的集成,在rails應(yīng)用的目錄下,運(yùn)行如下的命令,就可以顯示測(cè)試用例的運(yùn)行結(jié)果。

RSPEC=true autotest or autospec

在自己的home目錄下,增加一個(gè).autotest設(shè)置所有的Rails應(yīng)用的autotest插件。當(dāng)然,也可以把這個(gè)文件加到每個(gè)應(yīng)用的根目錄下,這個(gè)文件將覆蓋home目錄下的文件設(shè)置。autotest的插件很多,筆者用到如下的plugin:

$ sudo gem install autotest-growl$ sudo gem install autotest-fsevent$ sudo gem install redgreen

設(shè)置.autotest文件,在.autotest中,加入如下代碼。

require 'autotest/growl' require 'autotest/fsevent' require 'redgreen/autotest' Autotest.add_hook :initialize do |autotest| %w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|  autotest.add_exception(exception) endend

測(cè)試經(jīng)驗(yàn)

安裝了必要的程序庫以后,就可以寫測(cè)試代碼了。本例中,所有應(yīng)用都是在Rails 2.3.4上開發(fā)的,RSpec采用的是1.3.0的版本。為了很好的說明問題,我們假定這樣的需求:判斷一個(gè)用戶在一個(gè)時(shí)間段內(nèi)是否遲到。寫測(cè)試代碼時(shí)都是遵循一個(gè)原則,只關(guān)心輸入和輸出,具體的實(shí)現(xiàn)并不在測(cè)試代碼的考慮范圍之內(nèi),是行為驅(qū)動(dòng)開發(fā)。根據(jù)這個(gè)需求,我們將會(huì)設(shè)計(jì)方法absence_at(start_time,end_time),有兩個(gè)輸入值start_time和end_time以及一個(gè)輸出值,類型是boolean。對(duì)應(yīng)的測(cè)試代碼如下:

describe "User absence or not during [start_time,end_time]" do before :each do   @user = Factory(:user) end it "should return false when user not absence " do  start_time = Time.utc(2010,11,9,12,0,0,0)  end_time = Time.utc(2010,11,9,12,30,0)   @user.absence_at(start_time,end_time).should be_false end it "should return true when user absence " do  start_time = Time.utc(2010,11,9,13,0,0,0)  end_time = Time.utc(2010,11,9,13,30,0)   @user.absence_at(start_time,end_time).should be_ture endend

測(cè)試代碼已經(jīng)完成。至于absence_at方法我們并不關(guān)心它的實(shí)現(xiàn),只要這個(gè)方法的結(jié)果能讓測(cè)試代碼運(yùn)行結(jié)果正確就可以。在此測(cè)試代碼的基礎(chǔ)上,就可以大膽地去完成代碼,并根據(jù)測(cè)試代碼的結(jié)果不斷修改代碼直到所有測(cè)試用例通過。
Stub的使用

寫測(cè)試代碼,最好首先從model開始。因?yàn)閙odel的方法能很好與輸入輸出的原則吻合,容易上手。最初的時(shí)候,你會(huì)發(fā)現(xiàn)mock和stub很好用,任何的對(duì)象都可以mock,并且在它的基礎(chǔ)上可以stub一些方法,省去構(gòu)造數(shù)據(jù)的麻煩,一度讓筆者覺得測(cè)試代碼是如此美麗,一步步的深入,才發(fā)現(xiàn)自己陷入了stub的誤區(qū)。還是引用上面的例子,我們的代碼實(shí)現(xiàn)如下:

class User < ActiveRecord::Base def absence_at(start_time,end_time)    return false if have_connection_or_review?(start_time,end_time)  return (login_absence_at?(start_time,end_time) ? true : false)   endend

按照最初寫測(cè)試代碼的思路,本方法中存在三種情況,即需要三個(gè)用例,而且還調(diào)用了其他兩個(gè)方法,需要對(duì)他們進(jìn)行stub,于是就有了下面的測(cè)試代碼。記得當(dāng)時(shí)完成后還很興奮,心中還想:這么寫測(cè)試代碼真有趣。

before(:each) do @user = User.newenddescribe "method <absence_at(start_time,end_time)>" do  s = Time.now e = s + 30.minutes # example one it "should be false when user have interaction or review" do  @user.stub!(:have_connection_or_review?).with(s,e).and_return(true)  @user.absence_at(s,e).should be_false end   # example two it "should be true when user has no interaction and he no waiting at platform" do  @user.stub!(:have_connection_or_review?).with(s,e).and_return(false)  @user.stub!(:login_absence_at?).with(s,e).and_return(true)  @user.absence_at(s,e).should be_true end # example three it "should be false when user has no interaction and he waiting at platform" do  @user.stub!(:have_connection_or_review?).with(s,e).and_return(false)  @user.stub!(:login_absence_at?).with(s,e).and_return(false)  @user.absence_at(s,e).should be_false end  end

上面的測(cè)試代碼,是典型把代碼的實(shí)現(xiàn)細(xì)節(jié)帶到了測(cè)試代碼中,完全是本末倒置的。當(dāng)然這個(gè)測(cè)試代碼運(yùn)行的時(shí)候,結(jié)果都是正確的。那是因?yàn)橛胹tub來假定所有的子方法都是對(duì)的,但是如果這個(gè)子方法have_connection_or_review?發(fā)生變化,它不返回boolean值,那么將會(huì)發(fā)生什么呢?這個(gè)測(cè)試代碼依然正確,可怕吧!這都沒有起到測(cè)試代碼的作用。

另外,如果是這樣,我們不僅要修改have_connection_or_review?的測(cè)試代碼,而且還要修改absence_at的測(cè)試代碼。這不是在增大代碼維護(hù)量嗎?

相比而言,不用stub的測(cè)試代碼,不用修改,如果Factory的數(shù)據(jù)沒有發(fā)生變化,那么測(cè)試代碼的結(jié)果將是錯(cuò)誤的,因?yàn)閔ave_connection_or_review?沒有通過測(cè)試,導(dǎo)致absence_at方法無法正常運(yùn)行。

其實(shí)stub主要是mock一些本方法或者本應(yīng)用中無法得到的對(duì)象,比如在tech_finish?方法中,調(diào)用了一個(gè)file_service來獲得Record對(duì)象的所有文件,在本方法測(cè)試代碼運(yùn)行過程中,無法得到這個(gè)service,這時(shí)stub就起作用了:

class A < ActiveRecord::Base has_many :records def tech_finish?  self.records.each do |v_a|   return true if v_a.files.size == 5  end  return false endendclass Record < ActiveRecord::Base belongs_to :a has_files # here is a service in gemend

所對(duì)應(yīng)的測(cè)試代碼如下:

describe "tech_finish?" do it "should return true when A's records have five files" do  record = Factory(:record)  app = Factory(:a,:records=>[record])  record.stub!(:files).and_return([1,2,3,4,5])     app.tech_finish?.should == true end it "should return false when A's records have less five files" do  record = Factory(:record)  app = Factory(:a,:records=>[record])  record.stub!(:files).and_return([1,2,3,5])     app.tech_finish?.should == false endend

Factory的使用

有了這個(gè)工廠,可以很方便的構(gòu)造不同的模擬數(shù)據(jù)來運(yùn)行測(cè)試代碼。還是上面的例子,如果要測(cè)試absence_at方法,涉及到多個(gè)model:

  • ??? HistoryRecord:User的上課記錄
  • ??? Calendar:User的課程表
  • ??? Logging:User的日志信息

如果不用factory-girl構(gòu)造測(cè)試數(shù)據(jù),我們將不得不在fixture構(gòu)造這些測(cè)試數(shù)據(jù)。在fixture構(gòu)造的數(shù)據(jù)無法指定是那個(gè)測(cè)試用例使用,但是如果用Factory的話,可以為這個(gè)方法專門指定一組測(cè)試數(shù)據(jù)。

Factory.define :user_absence_example,:class => User do |user| user.login "test" class << user  def default_history_records   [Factory.build(:history_record,:started_at=>Time.now),    Factory.build(:history_record,:started_at=>Time.now)]  end  def default_calendars   [Factory.build(:calendar),    Factory.build(:calendar)]         end   def default_loggings   [Factory.build(:logging,:started_at=>1.days.ago),    Factory.build(:logging,:started_at=>1.days.ago)]   end  end  user.history_records {default_history_records}  user.calendars {default_calendars}  user.loggings {default_loggings}end

這個(gè)測(cè)試數(shù)據(jù)的構(gòu)造工廠,可以放在factories.rb文件中,方便其他測(cè)試用例使用,也可以直接放到測(cè)試文件的before中,僅供本測(cè)試文件使用。通過factory的構(gòu)造,不僅可以為多個(gè)測(cè)試用例共享同一組測(cè)試數(shù)據(jù),而且測(cè)試代碼也簡(jiǎn)潔明了。

before :each do @user = Factory.create(:user_absence_example)end

Readonly的測(cè)試

在筆者的系統(tǒng)中,大量使用了acts_as_readonly,從另外一個(gè)數(shù)據(jù)庫來讀取數(shù)據(jù)。由于這些model并不在本系統(tǒng)中,所以當(dāng)用Factory構(gòu)造測(cè)試數(shù)據(jù)的時(shí)候,總會(huì)有問題。雖然也可以使用mock來達(dá)到這個(gè)目的,但是由于mock的局限性,還是無法靈活的滿足構(gòu)造測(cè)試數(shù)據(jù)的需要。為此,擴(kuò)展了一些代碼,使得這些model依然可以測(cè)試。核心思想則是,根據(jù)配置文件的設(shè)置,將對(duì)應(yīng)的readonly的表創(chuàng)建在測(cè)試數(shù)據(jù)庫,這個(gè)操作在運(yùn)行測(cè)試之前執(zhí)行,這樣就達(dá)到與其他model一樣的效果。site_config配置文件中,關(guān)于readonly的配置格式如下:

readonly_for_test: logings:  datetime: created_at  string: status  integer: trainer_id

Gem的測(cè)試

Gem在Rails中被廣泛使用,而且是最基礎(chǔ)的東西,因此它的準(zhǔn)確無誤就顯得更加重要。在不斷實(shí)踐的基礎(chǔ)上,筆者所在的團(tuán)隊(duì)總結(jié)出一種用spec測(cè)試gem的方法。假設(shè)我們要測(cè)試的gem是platform_base,步驟如下:

1. 在gem的根目錄下創(chuàng)建一個(gè)目錄spec(路徑為platform_base/spec)。

2. 在gem的根目錄下創(chuàng)建文件Rakefile(路徑為platform_base/Rakefile),內(nèi)容如下:

require 'rubygems'require 'rake'require 'spec/rake/spectask'Spec::Rake::SpecTask.new('spec') do |t| t.spec_opts = ['--options', "spec/spec.opts"] t.spec_files = FileList['spec/**/*_spec.rb']end

3. 文件在spec目錄下創(chuàng)建spec.opts(路徑為platform_base/spec/spec.opts),內(nèi)容如下:

?

復(fù)制代碼 代碼如下:
--colour
--format progress
--loadby mtime
--reverse

?

4. 在spec目錄下,創(chuàng)建一個(gè)Rails app,名為test_app。這個(gè)新應(yīng)用需要有spec目錄和spec_helper.rb文件。

5. 為了保持簡(jiǎn)化,把這個(gè)新app(test_app)整理一下,刪除vendor和public目錄,最終的結(jié)構(gòu)如下:

?

復(fù)制代碼 代碼如下:
test_app
?? |- app
?? |- config
?? |?? |- environments
?? |?? |- initializers
?? |?? |- app_config.yml
?? |?? |- boot.rb
?? |?? |- database.yml
?? |?? |- environment.rb
?? |?? /- routes.rb
?? |- db
?? |?? /- test.sqlite3
?? |- log
?? /- spec
?????? /- spec_helper.rb

?

6. 在config/environment.rb配置文件中,增加如下代碼:

Rails::Initializer.run do |config| config.gem 'rails_platform_base'end

7. 在platform_base/spec/目錄下增加helpers_spec.rb文件,內(nèi)容如下:

require File.join(File.dirname(__FILE__), 'test_app/spec/spec_helper')

describe "helpers" do describe "url_of" do  before do   Rails.stub!(:env).and_return("development")   @controller = ActionController::Base.new  end  it "should get url from app's configration" do   @controller.url_of(:article, :comments, :article_id => 1).should == "http://www.idapted.com/article/articles/1/comments"   @controller.url_of(:article, :comments, :article_id => 1, :params=>{:category=>"good"}).should == "http://www.idapted.com/article/articles/1/comments?category=good"  end endend

至此,準(zhǔn)備工作已經(jīng)就緒,可以在platform_base目錄下,運(yùn)行rake spec來進(jìn)行測(cè)試,當(dāng)然現(xiàn)在什么都不會(huì)發(fā)生,因?yàn)檫€沒有測(cè)試代碼呢。本方法中,最關(guān)鍵的就是下面的require語句,不僅加載了Rails environment,而且把gem在test_app中使用并測(cè)試。

require File.join(File.dirname(__FILE__), 'test_app/spec/spec_helper')

Controller的測(cè)試

對(duì)于controller的測(cè)試,一般來說比較簡(jiǎn)單,基本是三段式:初始化參數(shù)、請(qǐng)求方法、返回render或者redirect_to。如下例中,對(duì)某個(gè)controller的index方法的測(cè)試:

describe "index action" do it "should render report page with the current month report" do  controller.stub!(:current_user).and_return(@user)  get :index,{:flag => “test”}  response.should render_template("index") endend

有些controller會(huì)設(shè)置session或者flash,這時(shí)的測(cè)試代碼就一定要檢查這個(gè)值設(shè)置的是否正確,而且還需要增加測(cè)試用例來覆蓋不同的值,這樣才能對(duì)方法進(jìn)行全面的測(cè)試。如下例:

describe "create action" do it "should donot create new user with wrong params" do  post :create  response.should redirect_to(users_path)  flash[:notice].should == "Create Fail!" end it "should create a new user with right params" do  post :create, {:email => "abc@eleutian.com"}  response.should redirect_to(users_path)  flash[:notice].should == "Create Successful!" endend

同時(shí),也需要對(duì)controller的assigns進(jìn)行測(cè)試,以保證返回正確的數(shù)據(jù)。如下例:

before(:each) do @course = Factory(:course)end describe "show action" do it "should render show page when flag != assess and success" do   get :show, :id => @course.id, :flag =>"test"  response.should render_template("show")  assigns[:test_paper].should == @course  assigns[:flag].should == "test" end it "should render show page when flag == assess and success" do  get :show, :id => @course.id, :flag =>"assess"  response.should render_template("show")  assigns[:test_paper].should == @course  assigns[:flag].should == "assess" end  end

View的測(cè)試

View的測(cè)試代碼寫的比較少,基本上是把核心的view部分集成到controller中來測(cè)試。主要用integrate_views方法。如下例:

describe AccountsController do integrate_views describe "index action" do  it "should render index.rhtml" do   get :index   response.should render_template("index")   response.should have_tag("a[href=?]",new_account_path)   response.should have_tag("a[href=?]",new_session_path)  end endend

在編寫測(cè)試代碼的時(shí)候,其實(shí)不必做任何詳細(xì)的工作。一些簡(jiǎn)單的方法和Rails內(nèi)部方法,完全不需要測(cè)試,希望武林技術(shù)頻道介紹的知識(shí)能幫到您!?

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表

圖片精選

综合久久给合久久狠狠狠97色| 日韩精品中文字幕一区二区| 精品精品国产国产自在线| www.一区| 日韩色性视频| 高清一区二区三区四区| 久久露脸国语精品国产91| 色综合中文网| 亚洲尤物在线视频| 日产精品一区二区| 91精品一区二区三区久久久久久| 久久99久久99精品免视看婷婷| 99久久久久国产精品免费| 国产欧美va欧美不卡在线| 91美女福利视频高清| 欧美精品一区三区| 精品无人区乱码1区2区3区免费| 特黄视频免费看| 一区二区三区四区欧美日韩| 日韩毛片在线观看| sm捆绑调教国产免费网站在线观看| 色哟哟一一国产精品| 欧美大肥婆大肥bbbbb| 中文字幕一区免费在线观看| 国产精品免费看久久久无码| 欧美日韩精品亚洲精品| 亚洲天堂男人网| 国产区视频在线| 亚洲精品中文字幕乱码三区| 欧美日韩在线播放一区| 国产日韩欧美激情| 日韩欧美国产免费播放| 俄罗斯xxxx性全过程| 激情网站在线| 摸bbb搡bbb搡bbbb| 粉嫩av在线播放| 色噜噜成人av在线| 日韩美一区二区三区| 亚洲一级在线| 欧美a级在线| 91国产在线播放| 在线观看电影av| www.5588.com毛片| 日韩在线观看第一页| 福利在线网站| 全球最大av网站久久| 日韩av大片在线观看| 国产一区欧美一区| 国产午夜精品久久久久免费视| 日本理论中文字幕| 国产传媒免费在线观看| 3d动漫啪啪精品一区二区免费| 欧美凹凸一区二区三区视频| 91传媒免费看| 第一中文字幕在线| 激情四射综合网| 亚洲综合图片区| 日本免费一区二区三区视频| 91亚洲一区| www免费视频观看在线| 日韩精品大片| 国产精品青青在线观看爽香蕉| 中文字幕免费在线看线人动作大片| 久操视频在线播放| 久久无码精品丰满人妻| 国产天堂av| 亚洲第一黄色网| 中文字幕免费高清网站| 亚洲网站视频福利| 亚洲成在线观看| 亚洲欧美视频一区二区三区| 国产精品66部| 久久久久国产精品www| 中文字幕在线观看91| 亚洲免费av网站| 中文天堂在线资源| 欧美日韩精品一区二区三区视频| 欧美福利影院| 国产亚洲精品久久久久久| 自拍自偷一区二区三区| 国内精品久久久久影院 日本资源| 天天摸天天碰天天爽天天弄| 精品freesex老太交| 国产精品二三区| 亚洲人成网站精品片在线观看| 欧美国产一区二区在线| 无码人妻aⅴ一区二区三区有奶水| 日日草天天草| 国产盗摄视频在线观看| 永久域名在线精品| 中文字幕日韩精品在线观看| 男人久久天堂| 337p亚洲精品色噜噜| 十八禁视频网站在线观看| 亚洲三级电影在线观看| 国产原创在线| 亚洲高清免费视频| 国产农村妇女精品一区| 日本福利专区在线观看| 国自产拍偷拍福利精品免费一| 欧美日韩成人一区二区| 午夜影院在线看| 品久久久久久久久久96高清| 国产精品成人免费| yellow在线观看网址| 亚洲成av人片在线观看www| 在线观看亚洲大片短视频| 亚洲无人区一区| 免费国产自线拍一欧美视频| 久久久久亚洲av成人网人人软件| 欧美大码xxxx| 国产v综合v亚洲欧美久久| 女人又爽又黄免费女仆| 久久精品一本| 国产又粗又猛又爽又黄av| 欧美在线视频第一页| 亚洲午夜未删减在线观看| 1pondo在线播放免费| www.成人影院| 日韩av第一页| 日韩成人午夜| 久久精品72免费观看| 免费在线观看黄色av| 国产大片中文字幕| wwwxxxx在线观看| 日韩一二三区在线观看| 超碰影院在线| 俺也去精品视频在线观看| 国产午夜手机精彩视频| 奇米777在线| 国产成人一级电影| 激情成人四房播| 国产日韩欧美一区二区| 亚洲a∨日韩av高清在线观看| 性xxxx奶大欧美高清| 欧美色网一区二区| 免费男女羞羞的视频网站中文字幕| 中文字幕亚洲欧美日韩在线不卡| 中文字幕精品在线视频| 91老司机在线| 男人和女人做事情在线视频网站免费观看| 午夜视频在线观看免费视频| 99re在线视频| www视频免费| 色偷偷88欧美精品久久久| a毛片不卡免费看片| 欧美老年两性高潮| 久久成人在线视频| av网站观看| 国产嫩草一区二区三区在线观看| 欧美系列亚洲系列| 免费精品99久久国产综合精品| 日韩国产成人精品| av电影天堂一区二区在线| 欧美人与物videos另类xxxxx| 韩国黄色一级大片| 精品久久综合| 99r国产精品视频| 欧美自拍视频| 国产一区二区色| 91av福利视频| 日韩另类在线| 久久久久亚洲AV成人无码国产| 亚洲精品一区二区三区中文字幕| 欧美日韩综合不卡| 中文字幕日韩一区| 中文字幕视频免费在线观看| 美女一区视频| 97免费视频在线| 久久精品国产成人一区二区三区| 色婷婷综合缴情免费观看| 精品国产乱码久久久久酒店| 五月天网站亚洲| 精品一区二区免费视频| 亚洲第一福利专区| 日本成人三级电影| 91成人观看| 91黄色免费网站| 一区二区三区四区激情| 老鸭窝91久久精品色噜噜导演| 自拍视频亚洲| 福利视频一二区| 久久99欧美| 自拍偷拍亚洲精品| 亚洲超丰满肉感bbw| 全部孕妇毛片丰满孕妇孕交| 黄色一级片在线观看| 亚洲免费小视频| 免费在线视频你懂得| 免费黄网在线看| 丝袜熟女一区二区三区| 在线免费一区三区| 亚洲成熟女性毛茸茸| 中文在线а√在线| 日韩欧美美女一区二区三区| jizz久久久久久| 神马久久久久久久久久久| 亚洲天堂网视频| 亚洲欧美日韩色| 亚洲综合伊人久久| 无码国产精品高潮久久99| 国产欧美一区二区三区网站| 国产69精品久久久久9999小说| 欧美日韩亚洲网| 999国产精品999久久久久久| www.xxx国产| 国产综合久久久久久| 色先锋av资源中文字幕| 韩日成人在线| 四虎影视永久免费在线观看一区二区三区| 一区二区三区四区不卡在线| 国精产品99永久一区一区| 欧美性xxxx极品hd欧美风情| 国精品**一区二区三区在线蜜桃| 91精品国产91久久久| 图片区小说区区亚洲五月| 91国内外精品自在线播放| 久久69国产一区二区蜜臀| 久久影院理伦片| 少女频道在线观看免费播放电视剧| 国产欧美日韩一区| 日本欧美一区二区三区不卡视频| 国产综合精品| 91人人澡人人爽| 亚洲av成人无码久久精品老人| 国产日产一区| 国产馆手机在线观看| 中文av一区二区三区| 91精品天堂福利在线观看| 亚洲一二三四五| 亚洲精品自产拍| 91麻豆精品国产91久久久| 日本高清视频一区二区| 亚洲在线国产日韩欧美| 国产一区二区三区中文字幕| 久久国产精品久久久久久电车| 精品卡一卡二卡三卡四在线| 99精品国产99久久久久久97| 中文字幕高清在线免费播放| 国产精品综合一区二区三区| 国产精品毛片在线| 自拍偷拍第1页| 日韩欧美国产免费| 综合亚洲自拍| 国产精品久久午夜夜伦鲁鲁| 四虎影院一区二区三区| 国产美女www爽爽爽| 欧美熟妇精品一区二区蜜桃视频| 热久久一区二区| 亚洲精品一区二区三区在线播放| 日本女优在线视频一区二区| 九九在线观看免费视频| 亚洲高清在线看| 99久久精品免费视频| 免费一级欧美片在线观看网站| 国产精品久久国产三级国电话系列| 亚洲精品免费在线播放| 国产精品久久久爽爽爽麻豆色哟哟| 久久一夜天堂av一区二区三区| 97久久超碰福利国产精品…| 亚洲精品无码专区在线播放| 伊人成人222| 日本www视频在线观看| 亚洲 精品 综合 精品 自拍| 国产午夜精品全部视频在线播放| 伊人成综合网伊人222| 国产美女喷水视频| 欧美日韩在线三级| 久久久噜噜噜久噜久久综合| 国产九九精品视频| 日韩电影免费观看中文字幕| 国产专区欧美精品| 五月婷婷综合久久| 亚洲欧美日韩国产一区二区三区| 国产变态拳头交视频一区二区| 亚洲成a人v欧美综合天堂下载| 国产欧美一区二区三区米奇| 99国产欧美久久久精品| 欧美成人官网二区| 亚洲免费毛片网站| 精品日韩在线播放| 97超碰蝌蚪网人人做人人爽| 日韩美女视频一区二区在线观看| 日本精品在线视频| 日本91av在线播放| 国产伦精品一区二区三区四区视频| 国产精品一区二三区| 国产一级片免费视频| 免费男女羞羞的视频网站中文版| 99热手机在线观看| 日日骚欧美日韩| 9l视频白拍9色9l视频| 婷婷精品在线| 成人网站免费观看入口| 国产亚洲精品bt天堂精选| 新欧美整片sss第一页| 国产视频手机在线| 蜜芽tv福利在线视频| 国产专区在线播放| 精品久久久久久一区二区里番| 中文字幕亚洲欧美日韩2019| 老司机福利在线视频| 久久国产乱子伦精品| 麻豆精品一二三| 成年在线观看免费人视频| 亚洲国产欧洲综合997久久| 午夜剧场免费在线观看| 国产小视频在线免费观看| 91高跟黑色丝袜呻吟在线观看| 日本黄色录像视频| 日本婷婷久久久久久久久一区二区| av在线影院| 欧美成人乱码一区二区三区| 国产成人精品一区二三区| 免费观看在线一区二区三区| 污视频软件在线观看| 国产精品99久久久久久董美香| 久久精品播放| 秋霞影院午夜丰满少妇在线视频| 性chinese极品按摩| 琪琪亚洲精品午夜在线| 精品在线免费观看视频| 日韩一区二区三区三四区视频在线观看| 欧美一区二区在线观看视频| 国产精品一二三视频| 日韩一级av毛片| 五月天视频一区| 麻豆传媒免费在线观看|