自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一次單元測試優(yōu)化的過程總結(jié)

開發(fā) 新聞
本文將介紹淘寶用戶運營平臺團隊最近在實踐單元測試過程中遇到的一個問題。

前言

淘寶原用戶增長團隊(現(xiàn)用戶運營平臺團隊)是比較早踐行單測增量覆蓋率的團隊,堅持了近兩年下來,我們積累了數(shù)千個test case,在開發(fā)新功能、修改原功能的過程中幫助我們發(fā)現(xiàn)了許多問題,顯著地提升了代碼質(zhì)量、減少線上故障。在這里鄭重地向大家推薦,單測是值得認真做的,開頭是痛苦的,但是積累一段時間后,量變就會帶來質(zhì)變。

言歸正傳,接下來談一談最近在實踐單測過程中遇到的一個問題。在研發(fā)協(xié)同平臺aone(下文簡稱aone)的發(fā)布流水線中,我們針對單元測試設(shè)置了增量代碼覆蓋率85%和test case 100%通過的流程卡點,在每次發(fā)布前,要保證test case完全通過才能提交工單。我們遇到了因并發(fā)導(dǎo)致的test case失敗,調(diào)整并發(fā)度導(dǎo)致的單測時間過長,但又影響研發(fā)效能的問題。最終在并發(fā)度和成功率之間找到了一個平衡點,解決了單測流程降低研發(fā)效率的問題。

單側(cè)流水線配置

在單測流程中呢,我們主要用到了JUnit、JaCoCo和Surefire三套工具,通過aone提供的容器自動化運行單元測試,搜集測試報告。下面簡單介紹一下這三個工具。

?  JUnit

java界最大名鼎鼎的單元測試框架,無須多言,會java的應(yīng)該都知道。

?  JaCoCo

EclEmma團隊開發(fā)的開源代碼覆蓋率統(tǒng)計工具,也是java業(yè)內(nèi)最主流的代碼覆蓋率統(tǒng)計工具。增量代碼覆蓋率就是通過該工具進行統(tǒng)計的,全量、增量、按類、包統(tǒng)計都支持,非常靈活。

?  Maven Surefire Plugin

surefire是maven的一個插件,在maven生命周期的test階段執(zhí)行單元測試用例。運行完成后還會生成測試報告,方便用戶查看單測情況。

我們利用三種工具,加上aone提供的容器和流水線配置能力,完成了自動化單測的流程和發(fā)布卡點校驗。

單元實踐過程

?  兩個階段

  • 積累test case時期

在剛剛開始單測時,大家新增的代碼都相對比較獨立,隨著業(yè)務(wù)的發(fā)展、工作職責的調(diào)整,單測會不斷變復(fù)雜,不同的service之間互相交織、單測的維護、運行成本都會增加。我們在這個階段遇到了一個比較棘手的問題。日常開發(fā)過程中,單測都是以類為粒度在本地跑的,都能通過后再去流水線驗證,一旦提交到流水線,就會遇到個別case失敗的問題,一開始排查起來完全沒有思路,test case的失敗可以說是隨機的,任何一個類的任何一個用例都有可能失敗。

圖片

經(jīng)過分析和排查,得出結(jié)論是并發(fā)導(dǎo)致的,于是我們限制了并發(fā),做了如下配置,確實解決了這個問題。

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
</configuration>
</plugin>

大家可以留意一下reuseForks和forkCount參數(shù),這時候我們還沒有深究兩個配置的含義,只是簡單的限制了并發(fā),這也為后續(xù)的故事埋下了伏筆。

  • test case達到一定規(guī)模時期

在完成了test case的初始積累以后,新的問題又隨之而來。因為沒有并發(fā),test case又很多,所以每次單測運行時長長達50分鐘。也嚴重影響了大家的研發(fā)效率。在分秒必爭的發(fā)布窗口期,經(jīng)常會出現(xiàn)大家等著單測跑完提交發(fā)布單的情況。

圖片

?  問題

看了上述兩個不同階段反映的問題,本質(zhì)上就是成功率和實效性的trade off問題,如何能提高并發(fā)、提升運行速度的同時保障成功率,這就是我們需要解決的最終命題。

?  原理和解決方案

上文提到了reuseForks和forkCount參數(shù),這些都是maven-surefire-plugin提供的配置項,把surefire插件研究清楚了,應(yīng)該就能解決如何兼顧速度和實效性的問題。

  • Surefire配置詳解

parallel

jvm內(nèi)并行執(zhí)行

通過parallel參數(shù)開啟,可選為methods,classes,both,suites等

其他參數(shù)

  1. useUnlimitedThreads,不限制線程數(shù)
  2. threadCount,線程數(shù)
  3. perCoreThreadCount,每核(默認true,和threadCount組合使用)
  4. parallelTestsTimeoutInSeconds,timeout時間


  1. 設(shè)置了parallel后,useUnlimitedThreads或者threadCount必須設(shè)置一個,不然會報錯
  2. parallel級別還有suitesAndClasses等更復(fù)雜的配置項,本文不多探討

參數(shù)示例如下,代表methods級別并發(fā),10條線程執(zhí)行。

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M7</version>
<configuration>
<parallel>methods</parallel>
<threadCount>10</threadCount>
</configuration>
</plugin>
</plugins>

fork

  1. 多jvm并行執(zhí)行
  2. forkCount 最多同時生成的JVM個數(shù),特殊語法是nC,代表n倍的CPU核數(shù),2.5C在4核機器上就是10的意思。
  3. reuseForks 是否重復(fù)使用fork出的JVM,true代表一個測試類運行完后,進程繼續(xù)處理下一個,false代表一個類運行完了JVM銷毀,重新生成新的JVM

默認配置 forkCount=1/reuseFork=true,forkCount設(shè)置為0會被自動替換為1

parallel和fork

parallel和fork組合后,就可以有更好的并發(fā)效率,也會帶來更大的沖突可能。

  • 并發(fā)導(dǎo)致case失敗原因

surefire的文檔原文如下,

圖片

簡單說來,就是因為JUnit的實現(xiàn)機制,對于JVM內(nèi)的線程并發(fā),會出現(xiàn)一些race condition或者其他難以復(fù)現(xiàn)的問題;對于forkCount大于1且開啟復(fù)用的情況,因為測試類是在復(fù)用的JVM內(nèi),也會因為相同的原因產(chǎn)生并發(fā)問題導(dǎo)致測試失敗。

  • 結(jié)果和建議

在徹底搞清楚surefire的配置原理后,我們回到問題來。經(jīng)過各種排列組合的嘗試,我們得出了比較合適的配置,reuseForks=true/ forkCount=2C,最終效果是每次運行時間在10分鐘左右,出錯概率較低,通過重跑也能解決。

圖片

小tip

mvn默認是按模塊串行的,可開啟并行提高整體速度(例:mvn -T 1C clean test),但是在我們的場景下,2000多個test case有1800個都在一個模塊里,所以開啟并行的效果不大。

其實這個問題沒有最優(yōu)組合,只有最合適的組合。在優(yōu)化了這個單測耗時最久的應(yīng)用后,我們又分析了其他幾個應(yīng)用,有的應(yīng)用test case不多,單測運行時長不長,就沒有必要開啟并發(fā),優(yōu)先保證成功率即可;有的應(yīng)用test case直接相互干擾較小,并發(fā)度可以調(diào)整得更高……

總的來說,在弄明白了原理之后,還需要具體情況具體分析,“紙上得來終覺淺,絕知此事要躬行”,大家可以分析一下自己應(yīng)用的情況,結(jié)合surefire的并發(fā)機制進行實踐,相信測過幾次以后就能找到最合適的配置組合。

單元實踐過程

在整個過程中,筆者還留有兩個想法:

  1. 有沒有辦法通過提高單測代碼質(zhì)量來避免或者降低因為并發(fā)引起的失敗?一些思路是通過suite分組,將可能沖突的類分開跑,這樣的做法可能會極大的提高單測開發(fā)成本,投入產(chǎn)出比不高。
  2. test case通過率可以不用嚴格卡100%,設(shè)定到99.5%都能顯著的提升效率,因為每次失敗的test case是不固定的,所以偶發(fā)的個別問題不影響整體的回歸。

在實踐卓越工程的過程中,筆者深切的感受到縱觀整個軟件研發(fā)的生命周期,有很多值得研究和切入的點,一些微小的改動,都能有效地提升研發(fā)效能和交付質(zhì)量。在當前的環(huán)境下,業(yè)務(wù)競爭日趨激烈,所謂開源節(jié)流,“開源”難,重心就會偏向“節(jié)流”,降本增效一定會是下一個階段的重點。而且對于技術(shù)人來說,效率一定是永遠的追求。其實提升性能、效率往往不是特別高大上的事情,希望大家能在日常繁重的工作之余,有點時間做些有趣的研究,享受技術(shù)帶來的快樂!

責任編輯:張燕妮 來源: 大淘寶技術(shù)
相關(guān)推薦

2009-12-23 15:03:52

WPF單元測試

2017-01-14 23:42:49

單元測試框架軟件測試

2011-11-18 15:18:41

Junit單元測試Java

2022-02-14 22:22:30

單元測試Junit5

2023-07-26 08:58:45

Golang單元測試

2011-05-16 16:52:09

單元測試徹底測試

2017-01-14 23:26:17

單元測試JUnit測試

2017-01-16 12:12:29

單元測試JUnit

2011-06-14 15:56:42

單元測試

2020-08-18 08:10:02

單元測試Java

2022-05-12 09:37:03

測試JUnit開發(fā)

2017-03-23 16:02:10

Mock技術(shù)單元測試

2021-05-05 11:38:40

TestNGPowerMock單元測試

2024-10-16 16:09:32

2011-07-04 18:16:42

單元測試

2020-05-07 17:30:49

開發(fā)iOS技術(shù)

2011-06-14 15:39:46

單元測試

2012-05-21 09:41:54

XcodeiOS單元測試

2011-04-18 13:20:40

單元測試軟件測試

2013-06-04 09:49:04

Spring單元測試軟件測試
點贊
收藏

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