2020年9月26日 星期六

導入敏捷最難的是什麼?

enter image description here
『導入敏捷最難的是什麼?』上課時同學這麼問。

『這問題,我可是很有經驗呢。』我心裡這麼想著,然後慢慢的回答…

導入敏捷最難的是…『組織總想在其他條件都不改變的狀況下,實現敏捷轉型。』

我常說:『人人擁抱敏捷,但真實狀況是…沒人想要改變。』

你說,不會啊,我們公司常常改變! 老闆總是朝令夕改…搞的大家無所適從。

我笑著說:『是啊,那是他改變你,不是改變他自己。況且,你不是也不喜歡別人常常改你的工作模式…對吧?』

總之組織從上到下,沒人喜歡『被改變』。

所以,導入敏捷當然可以…但,不能碰KPI、不能違反ISO、不能調整考績與獎金制度、不能改變合約簽訂方式、不能變更HR既定規則、不能調整休假與簽核流程、不能違反愚蠢的勞基法規法條、不能取消既有的公司會議(不管多麼無效)、不能改變組織結構、不能拆分部門與團隊…在所有外界環境都不改變的狀況下,要我們協助導入敏捷…幹的好。

這不是『難』,這根本是『為難』。

但我得說,這才是企業轉型的真實狀況。有興趣『談』轉型的老闆很多,有膽量豁出去的可算是鳳毛麟角,除非…

『除非什麼?』學生問。

除非…那公司差不多快掛了,死馬當活馬醫,這時候老闆可能會破釜沉舟,孤注一擲。但也往往能帶來最好的成效。

這也是大家常常看到,新創和小公司比較容易導入敏捷的關係。在大概超過百人左右的組織中,即便想要在一個小部門中導入敏捷,都很容易碰到與企業規範衝突的問題。

要知道,你可是在跟整個組織既有的習慣和文化對著幹,後台不夠硬,身段不夠軟,導入到最後,往往沒能改變組織,先陣亡的會是你自己。

『那怎麼辦?』另一位學員問。

『看起來很難,但也不是沒辦法。』我說『先準備好自己,別聽到台上講的精彩,一股熱血就勇往直前。也別亂找顧問,敏捷轉型不是小事。要幫企業實踐轉型,得長時間陪著企業一步步解決問題,身為顧問,你要非常清楚每一個工具、每一個activity想達成的目的,然後幫助企業選擇最適合的方式,量身訂做,趨吉避凶。』

好啦,先上課吧。先搞懂Scrum每一個角色和活動的意義,到時…才能真的幫上企業實現轉型。

2020年9月14日 星期一

什麼是Azure Cosmos DB?

Cosmos DB是微軟的高可用性、低延遲資料庫。近代的電商網站或微服務應用程式,都強調所謂的高可用性(就是網站或服務很難死掉)與快速回應,一旦系統上線,大概都不太容許服務的中止或延遲。

要實現這個能力,我們在Web或AP層可以做HA(high availability)架構,一般透過負載平衡(Load Balance)搭配Auto Scale的方式來實現。從Azure的Web App到常見的Container解決方案(像是K8S, AKS)的使用,背後很多的考量都是為了實現這樣的高可用性需求,讓流量增加的時候動態的在Web或AP層自動延展(動態增加伺服器):
enter image description here

但你慢慢會發現,當Web/AP伺服器可以近乎無限的延展之後,瓶頸接著發生在DB身上,因為傳統的關聯式資料庫,要實現像是Web Server或AP Server這樣快速延展分流成本相對而言非常高。且在資料的抄寫和回應的速度上要能夠有所保障,其架構都不若Web/AP Server的Scale那麼單純。

過去,用戶端的數量大多可以預測,但現在人手一台平板手機加NB,網際網路上的服務所面對的用戶端數量較之以往不可同日而語,如果要支撐一個全球服務的網站,傳統DB的Cluster架構常常力有未逮。

舉例來說,我們知道在資料處理上,有個CQRS架構(讀者可以上網搜尋相關資訊,例如 https://docs.microsoft.com/zh-tw/azure/architecture/patterns/cqrs ),其基本的概念是,真實世界中,資料查詢(讀取)與寫入的比例其實並非對等的。例如,台灣前陣子的口罩銷售地圖這類的應用,很明顯查詢的需求遠高於更新(寫入),大部分的全球化應用都有類似的情境。而傳統的資料庫程式設計,卻往往將讀取和寫入設計成同樣的工作通道(例如同樣的db access connection)。

倘若我們可以將資料的讀取,分散在全球不同的資料中心,讓讀取的節點可以分散,而工作比例較低的寫入動作,僅在其中一兩個節點進行,再將寫入的資料自動抄寫到不同的讀取節點,將有助於提升應用程式的查詢效能,這對於很多全球化或分散式的應用來說,是一個相對理想的架構。

這時候,NO SQL(Not Only SQL)類型的資料庫,就開始被許多大型網站考慮了,而Cosmos DB就是一個可以滿足這樣需求的資料庫。

透過Cosmos DB,我們可以動態的設定多個讀取區域,讓應用程式的讀取效能大幅提升:
enter image description here

資料會在異動時自動抄寫到不同的資料中心,微軟對資料讀取的效能進行保證,並提供 99.999%高可用性的承諾。開發人員在使用上也很簡單,只需要建立一組CosmosDB Account,就可以建立多個Database以及Container(類似關聯式資料庫的Data Table)。

建立Cosmos DB

要建立Cosmos DB,只需要在Azure Portal新增Azure Cosmos DB即可:
enter image description here

建立完成後,取得endpoint與金鑰,其實就可以使用了:
enter image description here

在取得endpoint與金鑰之後,可以參考筆者的github上的範例:
https://github.com/isdaviddong/dotNetCoreCosmosDB

透過上面這個dotnet core的console app範例,你可以很簡單的把endpoint與金鑰換掉,就可以體驗一下CosmosDB的使用,包含資料庫與Container的建立、資料item的建立與查詢。

CosmosDB的資料item的store是以JSON的形式保存,而查詢也可以透過"類似"SQL方式的語法,在上面這個範例中都有展示。你會看到我們在程式碼中,建立了一個Customer類別,並且動態建立100筆資料存入container:
enter image description here

當你把資料成功的建立好之後,可以回到Azure Portal,你會發現有個資料總管,它是個簡單好用的工具,你可以在資料總管中做簡單的查詢:
enter image description here

當你執行我在Github上的範例,將會看到我們透過C#程式碼新增和查詢資料:
enter image description here

OK,就這樣,高可用性DB唾手可得。

2020年7月26日 星期日

Azure DevOps in Action - 在Build Pipeline當中加入自動化程式碼檢查

enter image description here
在CI Pipeline當中,想要持續提升開發品質,除了單元測試,靜態程式碼檢查也很重要。在Build Pipeline運行過程中,適度的加上程式碼檢查工具,可以幫助我們掃描程式碼的狀況,檢查是否有具有潛在風險的程式碼。

我們常聽到的程式碼壞味道(code bad smells),或是技術債(technical debt),都是靜態程式碼檢查的主要標的。

技術債這個概念是1992年,由Ward Cunningham首次提出。而後常出現於Martin Fowler等大師的文章中。泛指為了縮短開發時程,而在開發過程中做出的妥協(像是安全性、測試、變數的命名…等)雖然可以得到立即的效果,但未來將可能連本帶利付上更大代價。

而SonarCloud,就是這類掃描工具中的翹楚,他是一個獨立的第三方產品,但可以跟Azure DevOps Pipeline做很好的整合。

要在Build Pipeline當中加入SonarCloud進行程式碼檢查非常容易,你只需要到SonarCloud.io申請帳號,並且在Azure DevOps站台上安裝免費套件後,即可進行這樣的掃描。

整個服務完全免費。

安裝SonarCloud

要使用該服務在Build Pipeline上,首先得安裝套件,請至底下網址:

https://marketplace.visualstudio.com/items?itemName=SonarSource.sonarcloud

在出現下列畫面時,選擇 Get it free:
enter image description here

接著在出現的畫面中,選擇你的組織(站台),然後按下Install即可:
enter image description here

安裝完成後,你會發現在建立Pipeline的時候,多了幾個Tempalte:

enter image description here

上面這幾個『…With SonarCloud』的Build Process Tempalte,就是安裝套件後,自動幫您加上的。針對 .Net Core和傳統 .Net Framework環境的開發專案,都有著適合的建置範本可供參考。

申請帳號

在使用之前,我會建議你,先到https://sonarcloud.io/ 這個站台建立帳號,你只需要透過Azure DevOps帳號(也就是MS Account)即可以Single-Sign-On的方式,取得SonarCloud帳號:
enter image description here

進入SonarCloud的Portal後,你可以在畫面右上角看到你的個人帳號,你可以依照需要,新增組織(organization)或專案(project):
enter image description here

你可以選擇上圖1,在既有的組織之下,建立一個新的專案:

enter image description here

首先選擇的是組織名稱(或是建立新組織,上圖2),建立專案比較重要的是設定專案的Key(上圖3),這個Key必須是唯一的,它會跟你的Build Pipeline連結在一起,我會建議你可以把你的Azure DevOps站台名稱,加上專案名稱再加上特定的序號,以此作為Project Key即可,因為該Project Key必須是全球唯一的。這個Key將會作為Build Pipeline將要生成的報表、與SonarCloud專案連結的關鍵。

舉例來說,我在Azure Devops中有一個站台『mytestaz400』,而其中有個專案『testBmiBuild』,該專案的網址就會是:

https://dev.azure.com/mytestaz400/testBmiBuild

那用在這個專案上的project key,我可能就會用底下這樣:

mytestaz400-testBmiBuild-001

其實,你用『mytestaz400-testBmiBuild』當然也行,但有鑑於你的專案中可能有多個Repos,而每一個Repos都可能會有多條Pipeline,所以後面加上『-001』似乎比較理想。

當然,你要在key中再加上Repo Name + Pipeline Bame也可以,看起來更無敵,但這樣就會顯得Project key很長,似乎有些不便。

好,總之填好一個唯一的Project key,並且確認無誤之後,預設狀況下,display name(下圖)會和project key相同,其實無須修改。

有一個地方稍微留意一下,你會發現該專案目前是Public的(下圖A)並且似乎無法修改:
enter image description here

沒錯,因為你採用的是免費方案,預設狀況下無法修改,如果想要改成Private專案,則必須升級(付費)。

那免費專案有什麼缺點呢?

嗯…其實倒也還好,就是你的掃描報告是公開在網際網路上的,任何人只要知道了你的Project key,都有機會可以看到你的掃描結果(其中還包含你該部分的source code)。這一點確實可能造成一些資安顧慮。你可能會擔心如果有人猜到你專案的這個key,豈不是全被看光了嗎? 是啊,所以或許你可以考慮把project key再設定的長一點。(或是乾脆付費成為正式會員吧…) 😊

好,不管如何,最後請按下『Set up』鈕,並牢記你的Project key,我們要接著後續的步驟了…

建立含有SonarCloud掃描的Pipeline

得到了Project Key之後,接著,我們可以回到Pipeline,後面我們以 .net core為例子,底下是填寫Task的參數時幾個主要的關鍵:

enter image description here

首先是上圖A的部分,我們必須建立一個SonarCloud的Service Endpoint,你可以點選『+New』,在跳出的視窗中,輸入Token與連線名稱:

enter image description here

但這個Token該如何取得呢?

你可以在剛才的SonarCloud的Portal,點選My Account --> Security即可產生一個新的Token:

enter image description here

好的,順利取得Token,建立好連線之後,我們重新回到Pipeline:

enter image description here

若連線建立正確,這時候你應該可以很順利地下拉出你的組織(如上圖),選定組織之後,填寫剛才一開始我們取得的Project Key:

enter image description here

完成之後, Pipeline也就設定完成了。

運行程式碼掃描

接著,你可以試著運行這個Pipeline,你會發現,在運行完SonarCloud的『Run Code Analysis』Task之後,報告就出現在底下的網址了

如果你仔細觀察,該網址其實就是剛才你設定的Project Key。

enter image description here

開啟該頁面,你會看到類似底下這樣的畫面:

enter image description here

其中包含了我們最關心的Bugs(上圖B),以及安全性問題(上圖E),技術債(上圖C)以及程式碼壞味道(上圖D)。

我們可以點進去細看問題來源,例如當你點選上圖E中的安全性問題,會發現,它幫我們檢查到我們的 .net core程式碼中有一行潛在的風險:

enter image description here

上面這行code(34行),是讓專案在開發階段碰到執行階段錯誤時,呈現較多錯誤訊息的指令,一般來說我們會建議在正式機上不要這樣寫,以避免可能的資安風險。

你會發現SonarCloud不只幫你掃描,也告訴你為何它認為這是一個問題:
enter image description here

另外,像底下這個建議,則是潛在的技術債建議:
enter image description here

這是因為我們在程式碼中把一個變數設為Public了,其實是沒有必要的。

凡此種種,都是SonarCloud幫我們透過掃描程式碼所發現的可能問題。妥善地逐一檢視這些問題並著手解決,絕對會有效地提升開發品質。

SonarCloud和Azure DevOps算整合得很相當緊密,是一個很值得使用的工具。

2020年7月20日 星期一

Azure DevOps in Action - 透過Trigger實現CI

上一篇,我們介紹過如何建立Build Pipeline,完成自動化的建置之後,我們接著要來看如何透過Build Process中的Trigger實現CI(Continuous Integration)。

也就是說,我們要讓雲端上的CI Build Pipeline在有任何程式碼被簽入(異動)的時候,自動運行雲端的Build

enter image description here
我們來修改一下上面這段程式,讓CI Build可以正確地完成Pipeline中的每一個tasks。

但在開啟Visual Studio 2019進行程式碼修改之前,我們先在Pipeline上做一件事情,請點選下圖的Edit切換到Pipeline設計畫面:
enter image description here

進入到設計畫面之後,請在Triggers分頁,勾選『enable continuous integration』:
enter image description here

請留意上圖中的A選項,這意味著,若source code所在的repo中,master分支上的code有所異動時(不管是直接修改或是透過PR修改),就會自動觸發這個Pipeline進行自動建置,這就是所謂的CI(continuous integration)。

設計完成之後,這次我們只需要選擇Save,暫時先不queue一個執行個體(instance):
enter image description here

因為我們要讓你體驗看看CI Build的威力,待會讓CI機制幫我們自動觸發Build Process。

請依照上圖儲存完之後,回到你用戶端剛才Visual Studio 2019開啟的專案(如果你不想使用Visual Studio 2019,其實也可以用Azure DevOps內建的Web UI,這部分我們日後介紹),我們把關鍵程式碼(\WebBMI\HealthMgr\BmiCalculator.cs)從int改成float:

enter image description here

完成後,我們透過Git工具將程式碼同步到伺服器端:
enter image description here

當同步完成後,我們可以切換到Azure DevOps管理站台,你會發現由於我們修改了master分支上的程式碼,雲端的Pipeline CI Build被自動觸發了:
enter image description here

同時,由於我們把程式碼改成正確的了,因此Unit Test順利過關:
enter image description here
整個CI Build自動完成了。

到這邊,我們可以看到幾個結論:

  1. Pipeline可以在雲端對專案作自動化的建置。
  2. 如果將Pipeline的Trigger設定成C I(continuous
    integration),任何開發人員只要簽入master分支(不管是直接修改或PR),都會觸發雲端的Pipeline進行Auto-Build。
  3. Pipeline中可以加入各種Task,例如進行建置的Build Solutions(下圖A),或是進行Unit Test的Test Assemblies(下圖B)
    enter image description here
  4. Tasks定義了Pipeline中具體要執行的工作與步驟。

好,我們暫且先整理到這邊。

我們曾經說過,不同語言或不同開發框架,所需要設計的Pipeline會有所不同,而Azure DevOps不只支援一種,而是坊間幾乎所有的開發技術都有所支援(Java, PHP, Python, Node.js, …etc.)。

我們剛才看了 .net framework的Web應用程式,後面我們來看 .net core 的Pipeline 該如何設計。

----------------------------------------------------------
本文摘錄自『Azure DevOps敏捷開發與專案管理實戰

Azure DevOps in Action - 建立.net core專案的Build Pipeline

好,接著我們來看 .net core 應用程式的CI Build。

.net core應用程式的建置環境和傳統 .net framework 有所不同,主要是因為 .net core是跨平台開發技術,你根本可以在 Linux環境上對程式碼進行Build的動作,從頭到尾都無須採用Windows環境。

如果是開發網站,也不需要IIS,直接佈署到Linux伺服器上即可(這個我們後面講CD的時候提)。

我們先來看底下這個Github上的範例:

https://github.com/isdaviddong/dotNetCoreBMISample.git

這個範例跟前面 .net framework的範例幾乎一樣,只是以 .net core的Razor Page形式開發。

我們運行起來:
enter image description here

整體功能和先前 .net framework版本完全相同,程式碼結構也相同,唯一的差異就是這個版本是 .net core 3.1開發的。

你可以建立一個新的Azure DevOps Project,並且依照先前介紹過的方法將Github上的程式碼匯入,完成後,應當會看到類似底下這樣:

enter image description here

接著,我們來嘗試建立這個repo的CI Build:

enter image description here

前面的動作都一樣,請留意選擇的Repository別選錯了,按下Continue之後,重點來了,在選擇專案範本的時候,你可以在下圖1的地方,輸入『.net core』作為過濾的關鍵字:

enter image description here

然後在出現的範本中,選擇上圖A的ASP.NET Core。

你可能會納悶有兩個選項(另一個是上圖B),原則上兩個都可以,因為.net core是跨平台開發技術,你可以選擇用Windows或非Windows環境進行Builld,我們選擇上圖A的Ubuntu環境。

接著,會看到該範本中的Tasks大致如下:

enter image description here

你先不用做額外的設定,請直接點選上圖1的Save & queue,系統將會用此範本跑一個Build的執行個體:
enter image description here

請留意上圖中的Agent是ubuntu 16.04。

建置的動作你會發現明顯比Windows環境來的快速很多,很快的整個Build就運行完畢了:

enter image description here

這個.net core版本的程式一樣有運行Unit Test,但我們並沒有故意留下bug,因此建置的過程應該會十分順利。筆者寫稿時雲端的Ubuntu環境上的 .net core版本是3.1版,所以理當能夠順利的建置。

整個過程和剛才的 .net framework版本差不多,甚至和後續我們會介紹到的其他非.net開發語言大致上也相同。

但你可能會有些疑惑,怎麼知道要選擇哪一種範本呢? 還有,這些tasks(例如上面的Restore, Build, Test, Publish…)到底是用來幹嘛的呢? 別擔心,這部分我們在後面會陸續跟讀者介紹。

----------------------------------------------------------------------------

想知道如何快速建立可以將 .net core 程式佈署到 container上運行的 CI pipeline?

同場加映: https://youtu.be/TXOxAljxo90 

本文摘錄自『Azure DevOps敏捷開發與專案管理實戰

2020年7月17日 星期五

Azure DevOps in Action - 建立你的第一個Build Pipeline

當開始邁向CI(continuous integration),我們第一個要實現的任務是,以雲端(伺服器端)的環境為準,來進行系統的開發、建置、佈署、與測試。

在過去(仿佛是上個世紀以前了),開發人員可能是以某一台個人開發環境的電腦為準,在多人開發協作之後,把程式碼集中在這台電腦上,進行最終的建置與測試。

但當我們導入了版控系統(像是Git)之後,即便多人同時開發、修改、增添新功能,甚至嘗試一些特殊調整。但在伺服器端,應該總是保持著一套最穩定的版本,可能是Master分支、或是Release分支(選擇分支的策略由團隊決定),這是之前我們討論版控時候的最終目標與CI的基礎。

當有了這個基礎之後,我們可以建立一個自動化建置的流程,一般稱之為CI Pipeline。由於使用不同的開發語言(或框架),可能會有著不同的建置流程,因此我們接著會逐步來看,在不同的開發技術下,CI Pepiline的設計方式。

建立 .net framework 專案的Build Pipeline

我們先來看基本的 .net framework專案,如果要練習,你可以建立一個新的Azure DevOps專案,並且在Repos處Clone/Import我們底下這個在GitHub上的程式碼。

https://github.com/isdaviddong/dotNetFxBMISample.git

這是筆者在github上的範例,是一個傳統的 .net framework MVC Web專案(後面我們會在介紹 .net core的做法),功能是實現一個計算BMI的Web應用程式。

你可以使用Azure DevOps Repos起始畫面的import功能,匯入這個GitHub上的Repo:

一陣忙碌:
enter image description here

完成後,你會看到類似底下這樣的程式碼:
enter image description here

有了source code在Repos中,接著,我們就可以來試試看建立Build Pipeline了。

請點選Azure DevOps左方主選單的Pipelines a New Pipeline:
enter image description here

在緊接著出現的畫面中(下圖),選擇最下方的『Classic Editor』。

下圖中上面的幾個選項是透過撰寫YAML Code的方式來設計Pipeline,而我們先選用GUI(Classic Editor):
enter image description here

由於我們的source code已經存放在預設的Azure Repo中(就是你剛才import進來的那份),且位於master主幹上,因此我們直接選擇預設的選項後,點選『continue』即可:
enter image description here

在接下來出現的畫面中,我們選擇 ASP.NET,按下Apply:
enter image description here

按下之後,你會發現系統自動帶出ASP.NET適用的Piepline模板:
enter image description here

上圖左方框起來的是Pipeline中的Tasks(自動化建置步驟),你完全無需修改,直接儲存順便跑一個建置動作(Save & queue)即可:
enter image description here

在出現的畫面上(上圖),按下『Save and run』。系統就開始雲端建置工作了:
enter image description here

上圖A中的Agent job1,就是正在雲端跑的自動化建置工作,你可以點進去,會看到運行的即時狀態:
enter image description here

上圖左方的A,是正在跑的Task,右方B的部分則是運行中的console顯示。如果你依照我們前面的說明一步一步做下來,沒一會兒可能會很訝異的看到底下這個錯誤畫面:

enter image description here

別怕,這是我們刻意的。

請注意,發生錯誤的位置是『Test Assemblies』這個Task,如果你對照前面的Editor畫面,就是底下這顆:
enter image description here

這顆Task是負責運行專案中的Unit Test的,我們曾經說過,近代軟體開發中,很倚賴Unit Test這樣的機制作為程式碼的把關。

Unit Test稱作單元測試,我們可以透過撰寫測試程式碼,以自動化的方式來測試主程式。這帶來了許多好處,可以大幅度的提高程式碼的品質,且減少回歸測試的工作量。

上面的Pipeline就是因為單元測試失敗,導致整個建置動作失敗。我們可以把這個專案透過Visual Studio 2019 Clone下來,並開啟。

然後接著以手動的方式Build整個方案:
enter image description here

你會發現,當你嘗試Build這個方案,他是可以正確地被建置的。

這表示這些專案沒有任何語法上的錯誤。然而,當你執行這個專案的程式時,它運算BMI的結果卻是錯誤的:
enter image description here

BMI是體重除以身高的平方,體重是以公斤為單位,身高是公尺。因此,上述計算正確的結果應該是24.22:

70/(1.7x1.7)=24.22

但我們的程式卻顯示為『70』。

這個錯誤源自於底下這段計算BMI的核心程式碼:

public float Calculate()
{
 float result = 0;
 //發生錯誤的位置
 float height = (int)Height / 100;
 result = Weight / (height * height);
 return result;
}

上面程式碼其中的

float height = (int)Height / 100;

造成了錯誤,(int)這樣的型別轉換導致計算結果不正確,如果你修改成

float height = (float)Height / 100;

則運算就會成功。

然而,這個程式碼邏輯上的錯誤,對於Build來說,卻不會造成任何問題(因為沒有寫錯任何語法),但執行的結果卻是錯的。

重點在於,Pipeline中運作Unit Test的tasks,順利地為我們抓取並攔截下了這個錯誤(雖然Build的時候沒有任何的語法異常),但撰寫了Unit Test的程式,在面對這類邏輯性的錯誤上,將可以為我們的系統帶來更大的保障。一切的前提當然是我們在專案中已經先撰寫好Unit Test的code了,但在這邊我們在這邊先不談Unit Test的撰寫,我們先了解Unit Test可以為我們帶來這些好處(後面會再找時間介紹如何開發)。

而用戶端Visual Studio的Test Explorer工具,可以幫我們手動運行Unit Test(下圖中左上角的Play按鈕):
enter image description here

例如上圖A是手動執行該專案中Unit Test的結果。

一般來說,成熟的專案中可能會有幾十甚至數百個Unit Test,這些為數眾多的Unit Test當不然可能頻繁的在開發端手動逐一執行,而Azure DevOps的自動化建置中的『Test Assemblies』這個Task,會在Pipeline進行Build的過程中,幫我們運行Unit Test,以確保開發品質得以提升。

總的來說,我們可以在程式專案中,撰寫更多的Unit Test,透過這些Unit Test,可以在Pipeline被執行時,自動檢查程式碼的正確性,守護系統的品質。當然,你必須先有Unit Test的觀念,如果你不曾寫過,暫且不用擔心,後面我們會介紹。

但你應當開始發現CI Pipeline的種種好處了…除了自動建置、持續整合(多人開發時),自動建置時帶入Unit Test的執行,也是很重要的…


----------------------------------------------------------
Related Posts Plugin for WordPress, Blogger...

熱門文章