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

高效的單元測試Rails該怎樣進(jìn)行

開發(fā) 測試
主要介紹如何高效的進(jìn)行單元測試Rails,希望對你有幫助,一起來看。

在筆者開發(fā)的系統(tǒng)中,有大量的數(shù)據(jù)需要分析,不僅要求數(shù)據(jù)分析準(zhǔn)確,而且對速度也有一定的要求的。沒有寫測試代碼之前,筆者用幾個很大的方法來實(shí)現(xiàn)這種需求。結(jié)果可想而知,代碼繁雜,維護(hù)困難,難于擴(kuò)展。借業(yè)務(wù)調(diào)整的機(jī)會,筆者痛定思痛,決定從測試代碼做起,并隨著不斷地學(xué)習(xí)和應(yīng)用,慢慢體會到測試代碼的好處。

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

環(huán)境搭建

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

第一步 安裝rspec和rspec-rails

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

 

  1. $ sudo gem install rspec v = 1.3.0  
  2. $ sudo gem install rspec-rails v = 1.3.2 

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

 

  1. $ script/generate rspec   
  2. exists lib/tasks  
  3. identical lib/tasks/rspec.rake  
  4. identical script/autospec  
  5. identical script/spec  
  6. exists spec  
  7. identical spec/rcov.opts  
  8. identical spec/spec.opts  
  9. identical spec/spec_helper.rb 

第二步 安裝factory-girl

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

 

  1. $ sudo gem install factory-girl 

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

 

  1. config.gem "factory_girl" 

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

第三步 安裝autotest

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

 

  1. $ sudo gem install ZenTest  
  2. $ sudo gem install autotest-rails 

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

 

  1. RSPEC=true autotest or autospec 

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

 

  1. $ sudo gem install autotest-growl  
  2. $ sudo gem install autotest-fsevent  
  3. $ sudo gem install redgreen 

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

 

  1. require 'autotest/growl'   
  2. require 'autotest/fsevent'   
  3. require 'redgreen/autotest'   
  4. Autotest.add_hook :initialize do |autotest|  
  5. %w{.git .svn .hg .DS_Store ._* vendor tmp log doc}.each do |exception|  
  6. autotest.add_exception(exception)  
  7. end  
  8. end 

 

#p#

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

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

 

  1. describe "User absence or not during [start_time,end_time]" do  
  2. before :each do   
  3. @user = Factory(:user)  
  4. end 
  5. it "should return false when user not absence " do  
  6. start_time = Time.utc(2010,11,9,12,0,0,0)  
  7. end_time = Time.utc(2010,11,9,12,30,0)   
  8. @user.absence_at(start_time,end_time).should be_false  
  9. end 
  10. it "should return true when user absence " do  
  11. start_time = Time.utc(2010,11,9,13,0,0,0)  
  12. end_time = Time.utc(2010,11,9,13,30,0)   
  13. @user.absence_at(start_time,end_time).should be_ture  
  14. end 
  15. end 

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

Stub的使用

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

  1. class User < ActiveRecord::Base 
  2. def absence_at(start_time,end_time)   
  3. return false if have_connection_or_review?(start_time,end_time)  
  4. return (login_absence_at?(start_time,end_time) ? true : false)   
  5. end  
  6. end 

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

 

  1. before(:each) do  
  2. @user = User.new  
  3. end  
  4. describe "method <absence_at(start_time,end_time)>" do   
  5. s = Time.now  
  6. e = s + 30.minutes  
  7. # example one  
  8. it "should be false when user have interaction or review" do  
  9. @user.stub!(:have_connection_or_review?).with(s,e).and_return(true)  
  10. @user.absence_at(s,e).should be_false  
  11. end  
  12. # example two  
  13. it "should be true when user has no interaction and he no waiting at platform" do  
  14. @user.stub!(:have_connection_or_review?).with(s,e).and_return(false)  
  15. @user.stub!(:login_absence_at?).with(s,e).and_return(true)  
  16. @user.absence_at(s,e).should be_true  
  17. end  
  18. # example three  
  19. it "should be false when user has no interaction and he waiting at platform" do  
  20. @user.stub!(:have_connection_or_review?).with(s,e).and_return(false)  
  21. @user.stub!(:login_absence_at?).with(s,e).and_return(false)  
  22. @user.absence_at(s,e).should be_false  
  23. end   
  24. end 

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

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

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

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

 

  1. class A < ActiveRecord::Base 
  2. has_many :records  
  3. def tech_finish?  
  4. self.records.each do |v_a|  
  5. return true if v_a.files.size == 5  
  6. end  
  7. return false  
  8. end  
  9. end  
  10. class Record < ActiveRecord::Base 
  11. belongs_to :a  
  12. has_files # here is a service in gem  
  13. end 

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

 

  1. describe "tech_finish?" do  
  2. it "should return true when A’s records have five files" do  
  3. record = Factory(:record)  
  4. app = Factory(:a,:records=>[record])  
  5. record.stub!(:files).and_return([1,2,3,4,5])   
  6. app.tech_finish?.should == true  
  7. end  
  8. it "should return false when A’s records have less five files" do  
  9. record = Factory(:record)  
  10. app = Factory(:a,:records=>[record])  
  11. record.stub!(:files).and_return([1,2,3,5])   
  12. app.tech_finish?.should == false  
  13. end  
  14. end 

 

Factory的使用

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

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

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

 

  1. Factory.define :user_absence_example,:class => User do |user|  
  2. user.login "test"  
  3. class << user 
  4. def default_history_records  
  5. [Factory.build(:history_record,:started_at=>Time.now),  
  6. Factory.build(:history_record,:started_at=>Time.now)]  
  7. end  
  8. def default_calendars  
  9. [Factory.build(:calendar),  
  10. Factory.build(:calendar)]   
  11. end  
  12. def default_loggings  
  13. [Factory.build(:logging,:started_at=>1.days.ago),  
  14. Factory.build(:logging,:started_at=>1.days.ago)]  
  15. end  
  16. end  
  17. user.history_records {default_history_records}  
  18. user.calendars {default_calendars}  
  19. user.loggings {default_loggings}  
  20. end 

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

 

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

 

#p#

Readonly的測試

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

 

  1. readonly_for_test:  
  2. logings:  
  3. datetime: created_at  
  4. string: status  
  5. integer: trainer_id 

Gem的測試

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

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

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

 

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

 

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

  1. --colour  
  2. --format progress  
  3. --loadby mtime  
  4. --reverse 

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

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

 

  1. test_app  
  2. |- app  
  3. |- config  
  4. | |- environments  
  5. | |- initializers  
  6. | |- app_config.yml  
  7. | |- boot.rb  
  8. | |- database.yml  
  9. | |- environment.rb  
  10. | \- routes.rb  
  11. |- db  
  12. | \- test.sqlite3  
  13. |- log  
  14. \- spec  
  15. \- spec_helper.rb 

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

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

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

 

  1. require File.join(File.dirname(__FILE__), 'test_app/spec/spec_helper')  
  2. describe "helpers" do  
  3. describe "url_of" do  
  4. before do  
  5. Rails.stub!(:env).and_return("development")  
  6. @controller = ActionController::Base.new  
  7. end 
  8. it "should get url from app's configration" do  
  9. @controller.url_of(:article, :comments, :article_id => 1).should == "http://www.idapted.com/article/articles/1/comments" 
  10. @controller.url_of(:article, :comments, :article_id => 1, :params=>{:category=>"good"}).should == "http://www.idapted.com/article/articles/1/comments?category=good" 
  11. end 
  12. end 
  13. end 

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

 

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

#p#

Controller的測試

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

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

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

 

  1. describe "create action" do  
  2. it "should donot create new user with wrong params" do  
  3. post :create  
  4. response.should redirect_to(users_path)  
  5. flash[:notice].should == "Create Fail!"  
  6. end  
  7.  
  8. it "should create a new user with right params" do  
  9. post :create, {:email => "abc@eleutian.com"}  
  10. response.should redirect_to(users_path)  
  11. flash[:notice].should == "Create Successful!"  
  12. end  
  13. end 

 

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

 

  1. before(:each) do  
  2. @course = Factory(:course)  
  3. end   
  4. describe "show action" do  
  5. it "should render show page when flag != assess and success" do   
  6. get :show, :id => @course.id, :flag =>"test"  
  7. response.should render_template("show")  
  8. assigns[:test_paper].should == @course  
  9. assigns[:flag].should == "test"  
  10. end  
  11. it "should render show page when flag == assess and success" do  
  12. get :show, :id => @course.id, :flag =>"assess"  
  13. response.should render_template("show")  
  14. assigns[:test_paper].should == @course  
  15. assigns[:flag].should == "assess"  
  16. end   
  17. end 

View的測試

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

 

  1. describe AccountsController do  
  2. integrate_views  
  3. describe "index action" do  
  4. it "should render index.rhtml" do  
  5. get :index  
  6. response.should render_template("index")  
  7. response.should have_tag("a[href=?]",new_account_path)  
  8. response.should have_tag("a[href=?]",new_session_path)  
  9. end  
  10. end  
  11. end 

總結(jié)展望

在寫測試代碼的時(shí)候,并不一定要事無巨細(xì),有些比較簡單的方法以及Rails的內(nèi)部的方法,如named_scope,就完全沒有必要測試。本文中,只介紹了用rspec寫單元測試的代碼,對于集成測試沒有涉及,這也是今后努力的一個方向。

另外,用cumumber + rspec + webrat的BDD開發(fā)模式也是相當(dāng)不錯的。尤其是cumumber對需求的描述,完全可以用它來做需求分析。

【編輯推薦】

  1. 如何做好單元測試
  2. 淺談軟件測試嵌入式單元測試技能
  3. 單元測試徹底測試的方法
  4. 詳細(xì)講解單元測試的內(nèi)容
  5. 淺談單元測試的意義
責(zé)任編輯:于鐵 來源: InfoQ
相關(guān)推薦

2017-01-16 12:12:29

單元測試JUnit

2017-01-14 23:26:17

單元測試JUnit測試

2011-11-30 22:03:49

ibmdwJava

2013-06-04 09:49:04

Spring單元測試軟件測試

2017-03-23 16:02:10

Mock技術(shù)單元測試

2012-11-01 11:32:23

IBMdw

2012-11-01 11:37:05

JavaScript單元測試測試工具

2017-01-14 23:42:49

單元測試框架軟件測試

2021-03-28 23:03:50

Python程序員編碼

2009-08-19 09:00:48

單元測試框架自動化測試

2021-03-24 09:30:02

Jupyter not單元測試代碼

2023-08-02 13:59:00

GoogleTestCTest單元測試

2023-07-26 08:58:45

Golang單元測試

2011-05-16 16:52:09

單元測試徹底測試

2017-12-12 13:17:36

機(jī)器學(xué)習(xí)代碼單元測試

2023-12-11 08:25:15

Java框架Android

2011-06-14 15:56:42

單元測試

2020-08-18 08:10:02

單元測試Java

2022-05-12 09:37:03

測試JUnit開發(fā)

2021-05-05 11:38:40

TestNGPowerMock單元測試
點(diǎn)贊
收藏

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

欧美人牲a欧美精品| 久久综合中文字幕| 欧美日韩成人在线播放| av免费观看不卡| 蜜桃麻豆av在线| 久久久精品国产免费观看同学| 国产精品久久久久免费a∨大胸| 伊人久久久久久久久久久久久久| 日韩在线观看一区二区三区| 亚洲丶国产丶欧美一区二区三区| 天堂√在线观看一区二区| aaaa一级片| 久久成人精品| 欧美俄罗斯性视频| www..com.cn蕾丝视频在线观看免费版| 国产一区二区高清在线| 精品女厕一区二区三区| 香蕉精品视频在线| 欧美另类自拍| 国产电影精品久久禁18| 国产精品久久久久久av福利| 久久国产在线观看| 日本黄色精品| 亚洲激情免费观看| 亚洲精品在线网址| 四虎影视4hu4虎成人| 亚洲激情男女视频| 亚洲一区二区四区| 每日更新av在线播放| 国产精品12区| 国产精品香蕉在线观看| 日韩毛片一区二区三区| 欧美99久久| 中文字幕成人在线| 人妻熟女aⅴ一区二区三区汇编| 国产精品久一| 欧美三级中文字| 久久久免费视频网站| 久久亚洲导航| 亚洲精品乱码久久久久久 | 无尽裸体动漫2d在线观看| 女人高潮被爽到呻吟在线观看| 亚洲男人天堂av网| 咪咪色在线视频| jizz在线观看视频| 国产欧美日韩另类一区| 欧美激情专区| 全部免费毛片在线播放网站| 东方aⅴ免费观看久久av| 国产欧美一区二区三区久久人妖| 亚洲视频 欧美视频| 国产日韩视频| 97在线观看视频| 中文字幕一区二区三区精品 | 日韩黄色在线播放| 一道本一区二区| 欧美激情综合色| 久久久久97国产| 欧美激情91| 欧美激情乱人伦一区| 久久久一区二区三区四区| 欧美一区二区| 九九精品在线视频| 九九九国产视频| 一本色道精品久久一区二区三区 | 久久精品国产精品亚洲综合| 国产精品视频99| 91好色先生tv| 国内精品伊人久久久久av影院| 91精品在线影院| 国产一区二区自拍视频| 国产精品小仙女| 肥熟一91porny丨九色丨| 亚洲国产精彩视频| 99国产欧美另类久久久精品 | 日批免费在线观看| 久久综合九色综合欧美就去吻 | 亚洲一区免费观看| 丰满少妇久久久| 日本免费久久| 欧美日韩mp4| 国产精品欧美性爱| 丝袜久久网站| 日韩在线视频观看正片免费网站| 朝桐光av在线| 99精品视频免费全部在线| 琪琪第一精品导航| 亚洲一级黄色大片| 国产成人啪午夜精品网站男同| 精品亚洲欧美日韩| 国产日韩精品在线看| 国产精品乱码一区二区三区软件| 三上悠亚免费在线观看| 黄色18在线观看| 91国偷自产一区二区开放时间 | 日韩高清不卡| 91精品国产福利| bl动漫在线观看| 精品一区二区三区在线| 欧美日本精品在线| 欧美日韩 一区二区三区| 国产美女av一区二区三区| 久久国产精品亚洲va麻豆| 一级毛片视频在线观看| 亚洲香蕉伊在人在线观| 午夜免费福利在线| 女同另类激情重口| 久久精品亚洲一区| 亚洲欧美综合自拍| 国产成人午夜片在线观看高清观看| 国产一区二区精品免费| 蜜桃视频在线观看免费视频网站www| 亚洲第一福利一区| 色18美女社区| 久久综合色占| 久久久久久香蕉网| 国产又色又爽又黄又免费| 久久色在线视频| 成人免费a级片| 国精品产品一区| 国产婷婷色综合av蜜臀av| 日本妇女毛茸茸| 日韩国产在线观看一区| 精品久久久久久一区二区里番| 亚洲精品承认| 色94色欧美sute亚洲13| 奇米777第四色| 亚洲中无吗在线| 国产精品视频xxx| 国自产拍在线网站网址视频| 婷婷综合五月天| 中文字幕一区二区三区人妻在线视频 | 国产一区二区丝袜高跟鞋图片| 色av男人的天堂免费在线| 一级特黄大欧美久久久| 99热一区二区| 久久国产综合| 国产精品美女www爽爽爽视频| 手机在线精品视频| 亚洲h精品动漫在线观看| 亚洲国产综合av| 亚洲午夜精品一区 二区 三区| 国产精品视频26uuu| www.在线播放| 欧美亚洲国产一卡| 亚洲精品国产一区黑色丝袜| 午夜一区不卡| 蜜桃av久久久亚洲精品| yellow字幕网在线| 亚洲高清免费观看高清完整版| 久视频在线观看| 国产精品1024| 久久综合久久久久| xxxx日韩| 午夜精品美女自拍福到在线| 性生交生活影碟片| 亚洲国产成人av好男人在线观看| 黑森林av导航| 99日韩精品| 美女主播视频一区| 九色成人搞黄网站| 久久久国产视频| 国产农村妇女毛片精品| 亚洲美女区一区| 自拍视频第一页| 亚洲国产mv| 成人免费看片网址| 欧美aa在线观看| 亚洲日本成人女熟在线观看| 亚洲天堂视频在线播放| 中文字幕一区二区三区av| 午夜xxxxx| 精品96久久久久久中文字幕无| 精品国产免费一区二区三区| 高清av不卡| 色伦专区97中文字幕| 国产三级按摩推拿按摩| 亚洲综合清纯丝袜自拍| 精品人妻一区二区三区日产| 乱人伦精品视频在线观看| 亚洲看片网站| 视频一区中文字幕精品| 91精品国产沙发| 91女主播在线观看| 日韩女优av电影| 中文字幕av影院| 国产精品麻豆久久久| 日韩黄色一区二区| 久久一二三四| 妺妺窝人体色www看人体| 午夜欧洲一区| 91久久精品国产91性色| 国产夫妻在线| 日韩中文字幕国产| 人妻中文字幕一区| 精品视频在线视频| 国产精品18p| 亚洲国产精品高清| 逼特逼视频在线观看| 日韩电影一区二区三区| 日韩视频 中文字幕| 亚洲精品3区| 99re资源| 欧美成人毛片| 97精品久久久中文字幕免费| 在线免费看av| 亚洲精品视频免费| 亚洲国产精品久久久久久久| 91电影在线观看| 国产在线一区视频| 自拍视频在线观看一区二区| 国产精品1000部啪视频| 国产乱码精品一区二区三区av| 激情网站五月天| 一区在线免费| 最近免费观看高清韩国日本大全| 国产一区二区精品久| 国产伦理一区二区三区| 国产成人久久精品一区二区三区| 国产99在线|中文| gogo高清午夜人体在线| 久久综合免费视频| aⅴ在线视频男人的天堂| 日韩精品在线影院| 天天射,天天干| 日韩欧美亚洲国产另类| 中文字幕制服诱惑| 在线精品观看国产| 欧美日韩一二三四区| 亚洲妇熟xx妇色黄| 久久久精品人妻一区二区三区四| 综合激情成人伊人| 日本在线观看网址| 中文字幕 久热精品 视频在线| www.色多多| 99久久久国产精品免费蜜臀| 亚洲av午夜精品一区二区三区| 国内精品免费**视频| 亚洲精品久久久久久宅男| 日韩精品欧美成人高清一区二区| ww国产内射精品后入国产| 黄色国产精品| 97久久国产亚洲精品超碰热| 中文字幕免费一区二区三区| 天堂v在线视频| 91精品精品| 99热这里只有精品7| 999久久久91| 在线不卡日本| 天天久久综合| 潘金莲一级淫片aaaaaa播放1| 欧美一区二区三区另类| 91九色国产ts另类人妖| 欧美日韩在线大尺度| 日韩精品免费一区| 国产精品av一区二区| 大伊香蕉精品视频在线| 亚洲青涩在线| 丝袜老师办公室里做好紧好爽 | 中文字幕中文字幕在线一区| 国产黄色片在线| 亚洲欧洲在线观看av| 三级av在线免费观看| 一区二区在线观看不卡| 中文在线观看免费网站| 欧美日韩另类字幕中文| 91久久国产综合久久91| 欧美四级电影网| 国产视频在线免费观看| 精品福利一二区| 四虎精品成人免费网站| 亚洲色图13p| 欧美成年黄网站色视频| 欧美肥臀大乳一区二区免费视频| 3344国产永久在线观看视频| 欧美在线一级va免费观看| 色综合天天色| 成人精品在线观看| 精品少妇3p| 西游记1978| 999久久久亚洲| 人妻少妇精品久久| 三级欧美在线一区| 奇米777在线| 91蝌蚪porny成人天涯| 激情高潮到大叫狂喷水| 一区二区三区精品| 免费视频久久久| 3751色影院一区二区三区| 人妻一区二区三区| 色先锋资源久久综合5566| 黄网av在线| 国产精品成人一区二区三区吃奶| 欧美国产中文高清| 欧洲在线视频一区| 国产精品大片| 国产成人黄色网址| 成人av免费在线播放| 手机av在线不卡| 婷婷国产v国产偷v亚洲高清| 亚洲特级黄色片| 亚洲高清在线观看| 免费看a在线观看| 7777免费精品视频| 日韩黄色碟片| 欧美欧美一区二区| 欧美日本中文| 五月婷婷六月丁香激情| 99v久久综合狠狠综合久久| 女人18毛片毛片毛片毛片区二| 亚洲成人av中文| 国产强伦人妻毛片| 永久免费看mv网站入口亚洲| 91色在线看| 91中文在线视频| 成人一区而且| 国产免费毛卡片| 高清不卡一二三区| 无码黑人精品一区二区| 欧美这里有精品| 亚洲 另类 春色 国产| 色综合久久久久久中文网| 日韩av一级| 欧美一区二区三区在线播放 | 激情五月亚洲色图| 99久久99久久免费精品蜜臀| 日韩女优一区二区| 欧美精品久久久久久久久老牛影院| 奇米影视888狠狠狠777不卡| 久久久久久免费精品| 亚洲专区**| 中文字幕乱码免费| 国内精品写真在线观看| 情侣偷拍对白清晰饥渴难耐| 欧美综合一区二区| 免费黄色片在线观看| 欧美中文在线观看| 欧美日韩一区二区三区四区不卡| 免费在线精品视频| 久久精品久久精品| 最新av电影网站| 欧美日韩久久久| 日本在线观看| 国产日韩欧美夫妻视频在线观看| 不卡日本视频| 久久婷婷国产91天堂综合精品| 久久久精品免费网站| 91丝袜一区二区三区| 亚洲一区二区久久久| 欧美性xxx| 日本一区二区精品视频| 视频一区欧美精品| 国产日韩精品中文字无码| 欧美日韩一区二区三区不卡| 成人精品一区二区| 国产欧美日韩精品丝袜高跟鞋| 青青草国产成人a∨下载安卓| 婷婷激情四射五月天| 国产精品青草综合久久久久99| 中文字幕视频免费观看| 久久电影一区二区| 91在线一区| 18禁免费无码无遮挡不卡网站| 久久先锋影音av鲁色资源| 糖心vlog精品一区二区| www.日韩视频| 日韩区一区二| 欧美,日韩,国产在线| 久久青草国产手机看片福利盒子| 精品视频一二三区| 久久精品一区中文字幕| 成人春色在线观看免费网站| 欧美 日韩 国产 高清| 久久久99精品久久| 91 中文字幕| 久久99久久亚洲国产| 欧美一区二区三区红桃小说| 日日碰狠狠丁香久燥| 亚洲欧美一区二区不卡| 天天舔天天干天天操| 国产成人精品电影久久久| 国产精品成人一区二区不卡| 久久久久国产免费| 日韩欧美一区视频| 麻豆av在线导航| 久久精品国产精品国产精品污 | 免费在线黄色网址| 91精品久久久久久综合乱菊 | 免费无码av片在线观看| 日本一区二区成人在线| 亚洲欧美黄色片| 国产精品pans私拍| 欧美人成网站| 精品人妻无码一区二区三区换脸| 91精品国产综合久久久久| 瑟瑟视频在线看| 中国黄色录像片| 久久久精品免费观看| 丰满人妻av一区二区三区| 国产精品爱久久久久久久|