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

關(guān)于寫異步代碼測(cè)試用例的一些思考

開發(fā) 前端
如果說異步代碼不好寫是共識(shí)的話,那么寫異步代碼測(cè)試用例就更難了。最近我剛剛完成了一個(gè) Flaky 測(cè)試,所以想和大家分享一些關(guān)于寫異步測(cè)試用例的想法。

如果說異步代碼不好寫是共識(shí)的話,那么寫異步代碼測(cè)試用例就更難了。最近我剛剛完成了一個(gè) Flaky 測(cè)試,所以想和大家分享一些關(guān)于寫異步測(cè)試用例的想法。

這篇文章里,我們會(huì)探索一個(gè)關(guān)于異步測(cè)試用例的常見問題 —— 如何強(qiáng)制規(guī)定某些線程的順序,如何強(qiáng)制某一個(gè)線程操作早于另一些執(zhí)行。通常我們并不想強(qiáng)行規(guī)定線程之間的順序,因?yàn)檫@違背了多線程的原則,所謂多線程就是 為了做到并發(fā),從而使得 CPU 可以根據(jù)當(dāng)前資源及應(yīng)用狀態(tài)選擇最佳的執(zhí)行順序。但是在測(cè)試中,為了確保測(cè)試結(jié)果的穩(wěn)定性,又必須明確線程順序。

[[151574]]

測(cè)試節(jié)流閥(Throttler)

在軟件業(yè)里節(jié)流閥指的是用于限制并發(fā)操作個(gè)數(shù),預(yù)留資源的模式,好比連接池,網(wǎng)絡(luò)緩存,或者 CPU 密集型操作。和其他同步工具不同的是,節(jié)流閥的角色是啟動(dòng)“快速失敗”機(jī)制,即促使超額請(qǐng)求立即失敗,而不是等待。“快速失敗”機(jī)制之所以重要,是因?yàn)榍?換操作,等待操作會(huì)消耗資源 —— 端口,線程,內(nèi)存等。

以下就是一個(gè)節(jié)流閥的簡(jiǎn)單實(shí)現(xiàn)(基本上是信號(hào)量的包裝,實(shí)際應(yīng)用中應(yīng)該是等待,重試等等)

 

  1. class ThrottledException extends RuntimeException("Throttled!"
  2. class Throttler(count: Int) { 
  3.   private val semaphore = new Semaphore(count) 
  4.   def apply(f: => Unit): Unit = { 
  5.     if (!semaphore.tryAcquire()) throw new ThrottledException 
  6.     try { 
  7.       f 
  8.     } finally { 
  9.       semaphore.release() 
  10.     } 
  11.   } 

現(xiàn)在我們開始基本的單元測(cè)試:測(cè)試單線程的節(jié)流閥(我們使用測(cè)試框架 specs2)。本例里,我們會(huì)驗(yàn)證順序調(diào)用是否會(huì)超過節(jié)流閥的最大限制(maxCount變量如下所示)。注意,這里我們用的是單線程,所以我們并不驗(yàn)證節(jié)流閥的“快速失敗”功能,這里的節(jié)流閥都處于不飽和狀態(tài)。事實(shí)上,我們只會(huì)測(cè)試節(jié)流閥在不飽和狀態(tài)下不會(huì)終止操作。

 

  1. class ThrottlerTest extends Specification { 
  2.   "Throttler" should { 
  3.     "execute sequential" in new ctx { 
  4.       var invocationCount = 0 
  5.       for (i <- 0 to maxCount) { 
  6.         throttler { 
  7.           invocationCount += 1 
  8.         } 
  9.       } 
  10.       invocationCount must be_==(maxCount + 1
  11.     } 
  12.   } 
  13.   trait ctx { 
  14.     val maxCount = 3 
  15.     val throttler = new Throttler(maxCount) 
  16.   } 

測(cè)試并發(fā)節(jié)流閥

前一個(gè)例子里,節(jié)流閥處于不飽和狀態(tài),因?yàn)閱尉€程里節(jié)流閥一般都不會(huì)飽和。下面我們來測(cè)試一下多線程環(huán)境下節(jié)流閥是否還能工作良好。

設(shè)置如下:

 

  1. val e = Executors.newCachedThreadPool() 
  2. implicit val ec: ExecutionContext=ExecutionContext.fromExecutor(e) 
  3. private val waitForeverLatch = new CountDownLatch(1
  4.  
  5. override def after: Any = { 
  6.   waitForeverLatch.countDown() 
  7.   e.shutdownNow() 
  8.  
  9. def waitForever(): Unit = try { 
  10.   waitForeverLatch.await() 
  11. catch { 
  12.   case _: InterruptedException => 
  13.   case ex: Throwable => throw ex 

 

ExecutionContext 用來構(gòu)建 Future,waitForever 方法用來持有線程,直到測(cè)試結(jié)束前的鎖釋放。接下來的函數(shù)里,我們會(huì)關(guān)閉一個(gè)執(zhí)行服務(wù)。

以下就是一個(gè)測(cè)試節(jié)流器多線程行為的例子:

 

  1. "throw exception once reached the limit [naive,flaky]" in new ctx { 
  2.   for (i <- 1 to maxCount) { 
  3.     Future { 
  4.       throttler(waitForever()) 
  5.     } 
  6.   } 
  7.   throttler {} must throwA[ThrottledException] 

我們創(chuàng)建了 maxCount 個(gè)線程(調(diào)用 Future{})來調(diào)用 waitForever 函數(shù),該函數(shù)會(huì)一直直到道測(cè)試結(jié)束。然后我們繞開節(jié)流閥執(zhí)行另一個(gè)操作 —— maxCount + 1。預(yù)期的行為是,此時(shí)應(yīng)該拋出 ThrottledException 例外。但是,也許預(yù)期的例外并不發(fā)生,因?yàn)榻恿ζ鞯淖詈蟮囊粋€(gè)調(diào)用可能會(huì)比 future 里的先執(zhí)行(future 里會(huì)拋出例外,但是這不是預(yù)期結(jié)果)。

上面這個(gè)測(cè)試的問題是,在像期望中那樣節(jié)流閥拋出異常然后導(dǎo)致節(jié)流閥被違反之前,我們無法確定所有的線程都已經(jīng)開始并且在 waitForever 函數(shù)中被阻塞。為了修復(fù)這個(gè)問題,我們需要一些方法去等待所有 future 開始。這有一個(gè)我們大多數(shù)都很熟悉的一種方法:只要增加一個(gè) sleep 函數(shù)等待一些合適的時(shí)間。

 

  1. "throw exception once reached the limit [naive, bad]" in new ctx { 
  2.   for (i <- 1 to maxCount) { 
  3.     Future { 
  4.       throttler(waitForever()) 
  5.     } 
  6.   } 
  7.   Thread.sleep(1000
  8.   throttler {} must throwA[ThrottledException] 

好了,現(xiàn)在這個(gè)測(cè)試幾乎都能通過了,但是這個(gè)方法還是錯(cuò)的因?yàn)橄旅孢@兩個(gè)原因:

測(cè)試持續(xù)的時(shí)間至少會(huì)和我們?cè)O(shè)置好的”合適的時(shí)間”差不多久。

在非常罕見的情況下,比如機(jī)器處于高負(fù)載的時(shí)候,這個(gè)合適的時(shí)間不一定足夠。

如果你仍然感到疑惑,可以搜索一下 Google 更多的原因。

一個(gè)更好的方式是將我們的線程(future)的開始和我們期望的東西同步起來。我們來使用 java.util.concurrent 里面的 CountDownLatch 類:

 

  1. "throw exception once reached the limit [working]" in new ctx { 
  2.   val barrier = new CountDownLatch(maxCount) 
  3.  
  4.   for (i <- 1 to maxCount) { 
  5.     Future { 
  6.       throttler { 
  7.         barrier.countDown() 
  8.         waitForever() 
  9.       } 
  10.     } 
  11.   } 
  12.  
  13.   barrier.await(5, TimeUnit.SECONDS) must beTrue 
  14.  
  15.   throttler {} must throwA[ThrottledException] 

 

我們使用 CountDownLatch 處理障礙同步。 這個(gè)等待的方法會(huì)阻塞主線程直到鎖存計(jì)數(shù)變?yōu)?0。隨著其它線程的運(yùn)行(我們把這些其它線程表示為 future),每一個(gè) future 都會(huì)調(diào)用 countDown 方法使鎖存計(jì)數(shù)減 1。一但計(jì)數(shù)變?yōu)?0,所有的 future 就都已經(jīng)運(yùn)行到 waitForever 方法中了。

通過那一點(diǎn),我們可以確保 throttler 是飽和的,內(nèi)部有最大數(shù)量(maxCount)的線程。另一個(gè)線程試圖進(jìn)入 throttler 將導(dǎo)致異常。我們有一個(gè)確定的方式建立我們的測(cè)試,測(cè)試會(huì)有一個(gè)主線程進(jìn)入 throttler。主線程可以恢復(fù)到這個(gè)點(diǎn)(門閂計(jì)數(shù)為 0 并等 CountDownLatch 釋放等待線程)。

如果一些意想不到的事情發(fā)生,我們使用超時(shí)略高保障避免無限阻塞發(fā)生。如果這樣的事情發(fā)生,我們的測(cè)試就失敗了。這個(gè)超時(shí)不會(huì)影響到測(cè)試時(shí)間,除非發(fā)生意外情況,否則,我們都不應(yīng)該等待。

結(jié)論

測(cè)試異步程序時(shí),通常需要在具體的測(cè)試用例中指定多個(gè)線程之間的執(zhí)行順序。不使用任何同步策略的測(cè)試是不可靠的,測(cè)試結(jié)果有時(shí)成功有時(shí)失敗。使用 Thread.sleep 降低了測(cè)試出錯(cuò)的概率,但沒有完全解決這個(gè)問題。

在大多數(shù)情況下,當(dāng)需要在測(cè)試中保證多個(gè)線程的執(zhí)行順序時(shí),可以使用 CountDownLatch 代替 Thead.sleep。使用 CountDownlatch 的好處是通過它可以指定釋放(保持)線程的時(shí)機(jī),有兩個(gè)優(yōu)點(diǎn):確保按順序執(zhí)行使測(cè)試結(jié)果更可靠;加快了測(cè)試程序的執(zhí)行速度。即使對(duì)于普通的 waiting 操作,比如 waitForever 函數(shù),盡管也可以使用 Thread.sleep(Long.MAX_VALUE) 這樣的函數(shù)實(shí)現(xiàn),但為了保證程序的健壯性最好不要這樣做。

完整的代碼可以在 GitHub 中找到。

責(zé)任編輯:王雪燕 來源: oschina
相關(guān)推薦

2012-12-19 09:36:49

測(cè)試自動(dòng)化測(cè)試

2021-06-15 07:10:14

JavaScript異步編程

2021-03-04 15:43:29

前端測(cè)試工具開發(fā)

2017-12-21 07:54:07

2021-06-10 10:02:19

優(yōu)化緩存性能

2020-08-20 10:16:56

Golang錯(cuò)誤處理數(shù)據(jù)

2024-12-27 10:51:53

2020-02-03 16:03:36

疫情思考

2009-06-25 09:50:32

JSF

2011-05-31 17:50:07

白盒測(cè)試

2021-06-10 20:17:04

云網(wǎng)融合超融合

2021-08-08 10:44:33

安卓系統(tǒng)開發(fā)者手機(jī)廠商

2018-06-29 14:51:41

Java健壯性實(shí)踐

2011-11-30 15:57:18

2011-01-19 10:50:31

軟件設(shè)計(jì)師

2011-07-13 09:13:56

Android設(shè)計(jì)

2011-06-14 14:04:11

測(cè)試用例

2020-05-12 14:03:51

RedisZooKeeper分布式鎖

2020-07-14 09:23:49

安全運(yùn)營甲方乙方
點(diǎn)贊
收藏

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

在线视频免费观看一区| 国产真实乱人偷精品人妻| 3d玉蒲团在线观看| av亚洲精华国产精华| 庆余年2免费日韩剧观看大牛| 人人妻人人澡人人爽| 电影91久久久| 欧美性猛交xxxx| 一区二区三区视频在线播放| 丰满人妻一区二区三区四区53| 亚洲专区一区二区三区| 色老头一区二区三区在线观看| 伊人av在线播放| 超级碰碰久久| 亚洲一区二区三区小说| 欧美精品亚洲| 亚洲精品免费在线观看视频| 日本sm残虐另类| 欧美精品九九久久| 国产又黄又粗视频| 国产成人精品亚洲线观看| 91精品办公室少妇高潮对白| 无码熟妇人妻av在线电影| 北岛玲一区二区三区| 成人久久18免费网站麻豆| 国产精品视频白浆免费视频| 好吊操这里只有精品| 91精品久久久久久久久久不卡| 亚洲美女中文字幕| 久久久久国产免费| 亚洲欧美专区| 欧美手机在线视频| 欧美亚洲另类色图| 国产丝袜精品丝袜| 亚洲人成网站在线| 亚洲高清在线播放| 久青青在线观看视频国产| 成人免费毛片高清视频| 亚洲最大福利视频网站| 国产偷人爽久久久久久老妇app | 91香蕉视频mp4| 99在线视频首页| 国产chinasex对白videos麻豆| 免费成人av在线播放| 国产97色在线| 天天干天天色综合| 性欧美videos另类喷潮| 欧美国产在线电影| 国产亚洲精品女人久久久久久| 伊人久久大香线蕉综合四虎小说 | 日韩国产精品一区二区| 噜噜噜在线观看播放视频| 99精品国产热久久91蜜凸| 国产精品免费观看高清| 亚洲第一大网站| 国产成人综合网| 91热精品视频| www.xxx国产| 国产乱子轮精品视频| 91麻豆国产精品| 国产aⅴ爽av久久久久成人| 狠狠色丁香九九婷婷综合五月| 国产精品自拍偷拍视频| 中文字幕一区2区3区| 免费视频一区二区| 国产精品亚洲自拍| 国产精品人妻一区二区三区| 国产在线精品一区二区夜色| 99在线视频首页| 视频三区在线观看| 久久久久久久久久电影| 色中色综合成人| 久久久久久久久免费视频| 一区在线播放视频| www成人免费| 九色porny丨入口在线| 大伊人狠狠躁夜夜躁av一区| 免费在线观看的毛片| 青草综合视频| 精品噜噜噜噜久久久久久久久试看 | 日本免费高清一区二区| 92国产在线视频| 亚洲欧美日韩国产手机在线| 男女日批视频在线观看| 成人福利av| 正在播放一区二区| 亚洲制服丝袜在线播放| 成人情趣视频网站| 欧美黑人xxxx| 最近中文字幕在线观看| 国产激情偷乱视频一区二区三区| 韩国一区二区三区美女美女秀 | 日本亚洲不卡| 中国日韩欧美久久久久久久久 | 一本一道久久a久久精品 | avav在线播放| 国产精品字幕| 欧美不卡在线视频| 国产1区2区在线观看| 欧美涩涩网站| 国产精品羞羞答答| 日韩一级片免费| 18成人在线视频| 草草久久久无码国产专区| 色综合久久久| 亚洲欧美日韩天堂| 国产免费无码一区二区视频| 日韩精品国产欧美| 99影视tv| 免费a级人成a大片在线观看| 欧美日韩国产影院| 性色av浪潮av| 日韩精品一卡| 热久久免费视频精品| 精品毛片一区二区三区| 国产精品乱人伦| 日本黄色三级大片| 亚洲**毛片| 日韩在线观看免费高清完整版| 国产成人综合欧美精品久久| 久久国产精品99久久久久久老狼| 免费影院在线观看一区| 影音先锋男人在线资源| 欧美日产国产精品| 久久成人激情视频| 9色精品在线| 成人动漫视频在线观看免费| 欧美69xxxx| 精品视频一区二区三区免费| 中文人妻一区二区三区| 国产综合精品| 99伊人久久| 午夜伦理大片视频在线观看| 在线成人免费观看| 999久久久国产| 日本aⅴ精品一区二区三区| 精品欧美一区二区三区久久久| 亚洲区欧洲区| 日韩欧美国产成人一区二区| 91香蕉视频在线播放| 美女视频一区二区三区| 视频一区亚洲| 精品久久福利| 中文字幕综合在线| 中文天堂在线播放| 国产精品午夜电影| 丁香婷婷激情网| 不卡在线一区二区| 国产精品专区h在线观看| 成人好色电影| 欧美男男青年gay1069videost| 极品蜜桃臀肥臀-x88av| 玖玖精品视频| 一区二区精品在线观看| 欧美成人毛片| 久久综合久久88| 国产三级小视频| 一区二区三区在线免费观看| 久久久久99人妻一区二区三区| 国产精品久久| 久久99欧美| 美女18一级毛片一品久道久久综合| 亚洲精品资源在线| 无码人妻av一区二区三区波多野 | 亚洲精品国精品久久99热一| 日韩女同强女同hd| 久久久久久一二三区| 三级在线视频观看| 亚洲国产精品91| 国产精品亚洲一区| 欧美momandson| 色777狠狠综合秋免鲁丝| 91福利在线观看视频| 伊人性伊人情综合网| 人妻av一区二区| 羞羞答答国产精品www一本| 日韩视频在线播放| 精品一区二区三区免费看| 欧美激情视频给我| 欧美91精品久久久久国产性生爱| 欧美网站大全在线观看| www青青草原| 久久久久久电影| 欧美视频亚洲图片| 99在线精品免费视频九九视| 亚洲一卡二卡区| 99久久人爽人人添人人澡| 欧美一乱一性一交一视频| 成年网站在线| 欧美xfplay| 探花国产精品一区二区| 一区二区三区四区不卡视频| 波多野结衣一本| 国产一区二区三区蝌蚪| 亚洲自偷自拍熟女另类| 97在线精品| 蜜桃av色综合| 日韩免费一级| 国产精品普通话| av中文字幕在线看| www国产精品视频| 神马精品久久| 欧美日韩精品一区二区在线播放| 国产精品成人网站| 国产精品三级视频| 免费看黄色aaaaaa 片| 国内精品国产成人| av免费在线播放网站| 国产精品mv在线观看| 亚洲国产欧洲综合997久久 | 亚洲激情国产精品| 国产露脸国语对白在线| 欧美性精品220| 久久久久久久久久一区二区三区| 国产精品三级视频| 亚洲第一香蕉网| 99麻豆久久久国产精品免费| 91精品国产三级| 美女诱惑一区二区| 热久久精品国产| 国产情侣一区| 国产无限制自拍| 欧美成人高清| 中文字幕中文字幕在线中心一区| 狠狠做六月爱婷婷综合aⅴ | 国产乱人伦真实精品视频| 欧亚av在线| 97在线看福利| www在线看| 欧美大片在线影院| 99在线视频观看| 久久精品视频在线观看| 92国产在线视频| 最新国产成人av网站网址麻豆| 激情福利在线| 国产一区二区三区视频| 欧美孕妇性xxxⅹ精品hd| 亚洲激情视频在线播放| 色窝窝无码一区二区三区| 欧美xxxxxxxx| 色窝窝无码一区二区三区成人网站| 精品国产一区久久| 亚洲免费不卡视频| 亚洲电影免费观看高清| 好吊色一区二区| 亚洲黄色av女优在线观看| 日韩在线视频第一页| 亚洲第一男人av| 天堂视频中文在线| 亚洲日韩欧美视频| 二人午夜免费观看在线视频| 中文字幕在线亚洲| 欧美成人hd| 色在人av网站天堂精品| 国产色婷婷在线| 欧洲s码亚洲m码精品一区| 老司机2019福利精品视频导航| 国产成人激情小视频| 国产成人精品一区二三区在线观看 | 国产丝袜一区视频在线观看| 日本a一级在线免费播放| 亚洲视频在线观看网站| 在线观看av黄网站永久| 欧美成人午夜视频| 91豆花视频在线播放| 日本亚洲精品在线观看| 久久免费资源| 成人精品一二区| 免费看av成人| 一区二区三区我不卡| 欧美天天在线| 日本在线观看a| 紧缚捆绑精品一区二区| 日本黄色大片在线观看| 91麻豆视频网站| 最新日韩免费视频| 亚洲一区二区偷拍精品| 国产性生活视频| 91精品国产综合久久婷婷香蕉| 丰满熟妇乱又伦| 亚洲天堂第二页| 色www永久免费视频首页在线| 91精品国产91| 不卡精品视频| 免费日韩电影在线观看| 天天影视欧美综合在线观看| 人妻无码久久一区二区三区免费| 青青草国产精品97视觉盛宴| 欧美熟妇精品一区二区| 国产午夜精品一区二区三区视频| 我家有个日本女人| 在线影视一区二区三区| www.天堂在线| 中文字幕日韩av综合精品| 国模雨婷捆绑高清在线| 国产精品视频色| 欧美色资源站| 久久天天东北熟女毛茸茸| 久久中文在线| 日韩女优在线视频| 亚洲欧洲成人av每日更新| 99久热在线精品996热是什么| 欧美丰满少妇xxxbbb| 天堂av中文在线资源库| 欧美精品免费播放| 国产91精品在线| 久久精品一区二区三区不卡免费视频| 国产精品国内免费一区二区三区| 日本免费黄视频| 成人性生交大片免费看中文 | 99热精品久久| 国产精品亚洲二区在线观看 | 日本污视频网站| 精品福利在线观看| 精品国产黄色片| 日韩一区二区在线视频| 日韩大尺度黄色| 国产一区视频观看| 欧美另类综合| aaa一级黄色片| 国产精品天干天干在线综合| 国产精品suv一区| 亚洲а∨天堂久久精品9966 | 欧美freesextv| 久久精品午夜福利| 99久久99久久综合| 久久精品一区二区三| 欧美一级精品大片| 麻豆网站视频在线观看| 国产精品午夜一区二区欲梦| 精品日韩一区| 天堂社区在线视频| 国产三级一区二区| 国产女同在线观看| 亚洲激情在线观看| 96av在线| 久久99久久精品国产| 国产一区导航| 亚洲精品视频大全| 狠狠躁天天躁日日躁欧美| 天天干,夜夜操| 日av在线播放中文不卡| 免费看成人哺乳视频网站| 激情网站五月天| 欧美激情在线观看视频免费| a片在线免费观看| 自拍亚洲一区欧美另类| 日本欧美在线| 日本三日本三级少妇三级66| 久久99久久99精品免视看婷婷 | 无码av免费一区二区三区试看| 亚洲乱色熟女一区二区三区| 欧美精品久久久久久久| 久久夜色精品国产噜噜av小说| 欧美日韩成人免费视频| 久久免费看少妇高潮| 国产情侣小视频| 日韩专区在线观看| 日韩三级网址| 亚洲熟妇无码一区二区三区导航| 99视频一区二区| 91丨九色丨海角社区| 日韩在线中文字| 亚洲视频国产| 精品久久一二三| 国产日产欧美精品一区二区三区| 亚洲特级黄色片| 欧美成在线视频| 理论片一区二区在线| 乱子伦视频在线看| 亚洲婷婷国产精品电影人久久| 国产成人久久精品77777综合| 久久久久久一区二区三区| 天美av一区二区三区久久| 牛夜精品久久久久久久| 亚洲女人****多毛耸耸8| 欧洲精品久久一区二区| 日本中文字幕成人| 久久久久国产精品| 日韩aaaaa| 欧美另类变人与禽xxxxx| 手机电影在线观看| 青青草国产精品| 国产福利一区二区三区视频在线 | 欧美三级精品| 久久免费一级片| 久久久精品免费免费| 国产美女无遮挡永久免费| 97av在线播放| 五月天久久久| 搡老熟女老女人一区二区| 欧美日韩一区三区四区| 182在线视频观看| 超碰在线免费观看97| 91亚洲精华国产精华精华液| 在线观看日批视频| 91国内在线视频| 欧美在线高清| 夜夜春很很躁夜夜躁| 精品国产一区二区三区忘忧草|