[CS193P] 第十八堂課摘要及心得筆記

在這一堂課程中,我們將看到OCUnit這套Objective-C的Unit testing framework,還有看到Objective-C一些有趣的使用方式,可以幫助我們深入研究Cocoa Touch中framework的內部結構,最後還會提到如何幫應用程式設計多國語言版本,以下是筆者的一些整理,還請多多指教!
評論
評論

在這一堂課程中,我們將看到 OCUnit 這套 Objective-C 的 Unit testing framework,還有看到 Objective-C 一些有趣的使用方式,可以幫助我們深入研究 Cocoa Touch 中 framework 的內部結構,最後還會提到如何幫應用程式設計多國語言版本,以下是筆者的一些整理,還請多多指教!

Unit Testing

Unit Testing 是近年來很熱門的一種測試方法,特點有:

  • 測試特定某部份的功能性
  • 盡量減少外部的相依性
  • 在開發期間頻繁測試

伴隨著 Unit Testing,Test-Driven Development(簡稱 TDD)也逐漸的受大家矚目、採用,TDD 顧名思義,就是在開發程式之前先行撰寫測試的 cases,並且隨著開發一一通過這些預先撰寫的 cases。

用個比喻,編譯器是用來檢查程式的語法正確性,而 unit test 則是檢查語意是否正確。因此,許多 unit testing 的 framework 會在每次編譯完成後進行測試,以確保程式的開發順利。而這樣的框架在 Python 平台有 PyUnit、Java 平台有 JUnit,同樣的,在 Cocoa 的平台上也有 OCUnit 來幫助我們撰寫各種 cases 並且進行 unit testing。而 OCUnit 跟 XCode 也做了完美的結合,可以自動在每次 build 完成後進行測試,並且顯示錯誤。

雖然聽起來有點奇怪,不過 OCUnit 在 Cocoa 中是被稱作 SenTest,所以如果你在文件中看到任何 SenTest 有關的類別,其實就是 OCUnit 測試框架的一部份。

那我們要如何開始撰寫測試程式呢?首先我們必須先建立一個 SenTestCase 的子類別,而這個子類別中所有以 test 開頭的方法都會自動被執行進行測試,而在那些方法中,我們可以使用 SenTestCase.h 中所定義好的 Macros,像是 STAssertNotNil(someObject, @"Some object was nil"); 可以檢查某物件是否並非為 nil,若為 nil 則顯示第二個參數的字串。

此外 SenTestCase 還提供了 - setUp 和 - tearDown 兩個方法可以重載,而這兩個方法分別會在每個 test 方法的執行前和執行後被呼叫。也就是說,我們可以在這兩個方法中建立新的物件,這樣就可以確定每個測試方法之間所使用的物件不會互相干擾。

在課程影片以及投影片的第 14 到第 20 張中有簡單的測試範例,有興趣的讀者還請自行參考。

Objetive-C 的樂趣

Objetive-C 本身是個相當有趣的語言,或許讀者在剛剛閱讀前一部分的時候曾經感到疑惑,為什麼 SenTestCase 可以找到所有以 test 開頭的方法呢?還是有什麼其他有趣的技巧呢?

在學習這些技巧之前,我們得先看看電腦中的 /usr/include/objc 目錄,這裡面包含了 Objetive-C 中的許多定義標頭檔,包含以下:

  • objc.h -- 定義了 id、nil、BOOL 等基本類型
  • message.h -- 定義了 objc_msgSend() 這個方法,用來處理 [foo bar] 這樣的方法呼叫
  • runtime.h -- 在執行期間檢視以及操作 class、protocol 和 methods

而這裡面最有趣的莫過於 runtime.h,裡面包含了以下檢視類別和方法的函式:

  • Method *class_copyMethodList(Class cls, unsigned int *outCount); -- 取得某類別的所有方法,outCount 為方法總數,以陣列方式回傳
  • SEL method_getName(Method m); -- 取得某方法的名稱,也就是 selector
  • IMP method_getImplementation(Method m); -- 取得某方法的實做,也就是實際執行的程式片段
  • char *method_copyReturnType(Method m); -- 取得某方法的回傳值

而得到了這些資訊之後,我們甚至可以修改內容:

  • BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types); -- 增加方法到某個類別中
  • IMP method_setImplementation(Method method, IMP imp); -- 修改方法的實做
  • void method_exchangeImplementations(Method m1, Method m2); -- 交換兩個方法的實做

你可能會很好奇,那為什麼不用 Category 來加入、修改方法就好了呢?背後的原因是,Category 先天上就限制了我們只能做有限的修改,假使我們想要呼叫類別原本所擁有的方法,在 Category 上是無法做到的。

然而,Apple 建議大家盡量不要使用以上這些技巧在公開發佈的軟體當中。事實上,這些修改會影響整個程式的執行,假使你使用了其他人所撰寫的類別方法,你所作的修改很有可能也會影響到那些由他人撰寫的程式碼,而造成一些難以理解的 bugs 產生。

多國語系

大家都知道 iPhone OS 本身就是一個多國語言的作業系統,我們可以輕易的在設定中切換所想要使用的語言,而整個系統中的內建應用程式也會隨之改變,而對於應用程式開發者而言,我們也可以透過同樣的機制處理。

要注意的是,iPhone OS 會自動的幫我們判斷在取用多國語系的資源時所要使用的語言,在做後續的操作時都不需要另外做去指定語言。

多國語言化的整個過程可以分成兩個步驟:

  • 國際化 (i18n) -- 將程式修改成可以支援多國語言的版本
  • 在地化 (l10n) -- 針對每個語言設計所需要的資源

在 iPhone OS 上,我們可以所需要處理的部份僅制於使用者端的顯示元素,這些元素可能會是字串、圖片或是 Nib 等。

以字串來講,對於那些使用者介面上的文字,我們可以將其另外存成.strings 檔案,這檔案透過 UTF-16 編碼紀錄了一組組 key-value 的值。而我們可以透過下列方法來取用這些字串:

// 讀取 Localizable.strings 中的字串 NSLocalizedString(@"Hello", @"Greeting for welcome screen"); // 讀取特定某個 table 的字串,本例為 Greetings.strings NSLocalizedStringFromTable(@"Hello", @"Greetings", @"Greeting for welcome screen");

而為了方便我們能夠快速的建立這些 strings 檔,我們可以在終端機下面使用 genstrings 這個指令,會自動的掃描我們的.m 檔並且產生出.strings 的檔案。

至於對於其他的圖片、nib 檔這類資源而言,我們則是可以透過 XCode 中的下列選項建立多重語系的版本:
而在之後我們就可以在 XCode 中看到同一個資源擁有了多個版本:

結論

我們逐漸走向了課程的尾聲,不知道大家是不是也跟我一樣從 CS193P 的一系列課程中學到很多呢?在下一次,也就是最後一次的正課中,我們將看到如何在 iPhone 平台上使用 OpenGL ES 建立 3D 應用程式,還請各位讀者繼續指教。

參考資源


開發者享受 CI/CD 價值!運用 Amazon EKS 整合 GitLab 創建自動化部署

企業如何在 Amazon EKS(Elastic Kubernetes Services)上使用 GitLab 創建自動化部署,減輕人力負擔,提升專案服務運作效率?
評論
評論

所謂現代化智慧 IT,所有工程師最希望的境界,莫過於只要輕鬆點幾下設定,系統就會自動跑起來,管理者再也不用隨時待命在機台旁邊,從此工作悠哉又快樂!儘管這樣情境還沒到來,但隨著敏捷式開發的流行,除了 DevOps 人員,有越來越多開發者將 CI/CD 概念融入到工作流程當中,例如從 build code、執行 unit test、到部署應用程式。

打造第一個在 AWS 上的應用程式

上述種種反覆步驟自動化執行,也就能提昇服務品質、主動通知開發人員以減輕人力負擔,讓專案服務能持續運作。

其中,GitLab 是執行 CI/CD 常用的工具之一,也是開發者使用程式碼儲存庫的地方。為了讓 GitLab Runner 在雲端快速實踐 CI/CD,《AWS 開發者系列》透過影片分享,如何在 Amazon EKS(Elastic Kubernetes Services)上使用 GitLab 創建自動化部署。

以下節錄工作坊影音內容,幫助開發者快速理解如何運用 Amazon EKS 的高可用性且安全的叢集,將修補、部署節點、更新等關鍵任務,全部做到自動化設定。同時影片也會示範 Amazon EKS 搭配 GitLab 如何展開自動部署,幫助工程團隊實踐 CI/CD 價值。

Amazon EKS 對容器管理輕鬆簡單、維運省時省力

容器化服務越來越興盛,當容器(Container)越來越多,在複雜的微服務(Microservice)系統環境之下,運維團隊的管理成本可能相對會增加不少,為了有效調度容器部署, 導入Kubernetes 無疑是近年企業熱門的話題之一。

建構 Kubernetes Cluster 流主要可區分兩大塊,一是安排容器調度的Control Plane、另一則是容器運行時需要用到的 Worker Node。

Control Plane 裡面涵蓋有儲存狀態的 ETCD、CoController manager 、Scheduler 的調度管理、甚至是操作時進行互動的 APIServer,若是自己創建 的 Kubernetes Cluster ,需要自己安裝這些元件,後續仍需要對 Control Plane 進行相關管理、維護、升級工作。為了減少上述 Components 的繁複維護,在透過 AWS EKS 代管的 Kubernete Control Plane 部可以獲得以下三大好處。

透過 AWS 增加雲端技能 在組織發揮影響力

Amazon EKS 一鍵式部署,展現三大優勢

第一,Amazon EKS代管的 Control Plane實踐了跨AZ的高可用部署,使用者不需要擔心單一節點故障的風險。

第二,Amazon EKS 支持至少四個 Kubernetes版本,持續跟進每季 CNCF 的發佈,同時 EKS 也完全符合上游 CNCF 規範。

第三,部署 Amazon EKS 之後,可直接使用 AWS 平台上現成的服務工具,在安全性管理、網路設定方面,可以做到無縫整合。

最後 AWS 台灣解決方案架構師也提到,若想在容器環境進行 CI/CD 及應用程式的管理,可以進一步透過 IaC 整合部署 Amazon EKS 叢集,透過使用 Console、把 EKS 變成 Cloudformation 的模板、使用 AWS 所開發出來的 eksctl.io、或指令是採用 AWS CDK 可以讓開發者用自身熟悉的語言,在 AWS 平台整合 CI/CD 工具進行維運及部署 EKS。

了解 Amazon EKS 整合 GitLab ,獲得三面向價值

對開發者而言,想把 Amazon EKS 整合到 CI/CD 工具之一的 GitLab 平台上,可以看到那些實際的優勢?

在 DevOps 開發者示範工作坊當中,GitLab 資深解決方案架構師指出,GitLab 使用到 Kubernetes 技術,主要有三種搭配方法,包含 GitLab Server、GitLab Runner、以及創建 Deployment Environment。

本次示範教學會主要聚焦在 GitLab Runner 如何採取 Auto-scaled 方式進行 Build、Test、Package Apps;以及在 Deployment Environment 運用 Kubernetes 技術,做到 Auto Deploy、Review App。

正因為 Amazon EKS 能夠在 DevOps 過程提供所需要的彈性計算資源,幫助開發者在 GitLab 平台上面獲得以下三個層次的優勢:

  • 在 GitLab 內建的部署工作流程當中,自動生成整套 CI/CD 最佳實踐腳本。
  • Review App 過程,從 Merge Request 中可直接訪問應用程式 /App 的 UI 介面,並且根據 Git branch 名稱、專案名稱,自動生成 Review App 的 URL,以及在 Merge 前的最後防線進行 Approval 檢查。
  • 加速 CI/CD 流水線,GitLab Runner 運行時候還可藉由 Amazon EKS Cluster 進行 Auto-scaled 的支援。

Amazon EKS 整合 GitLab ,需要兩大流程

影片最後,GitLab 資深解決方案架構師示範如何把 Amazon EKS 整合至 GitLab 執行 Auto Deploy,主要可分為兩大區塊流程,第一部分聚焦在 Amazon EKS cluster 的設置,第二部分則執行 Auto Deploy 設置。

第一塊可拆分為四個階段,首先教學怎麼創建 EC2 節點的 EKS cluster,第二階段示範把 EKS Cluster 連接到開發者的 GitLab Instance、Group 或 Project,下一步則使用 Cluster Management Project Template 創建一個 Cluster Management Project,以及最後一階段透過 Cluster Management Project 自帶的 Helm Chart,安裝在 Cluster 所需要的內建 App。

第二塊執行 Auto Deploy 設置,針對需要部署的 App 創建一個 GitLab Project,接著再把 gitlab-ci.yml 添加到 Project,並從 Web IDE 選擇及導入 Auto Deploy 的 CI 模版,讓 GitLab 自動生成最佳實踐的整套流水線。

幫助開發者更了解 Amazon EKS 整合 GitLab 的 QA 系列

Q:使用 Amazon EKS 之後,如何更有效率或優化資源去配置 Worker Node 的機器數量,以及如何有效空管開發維運的成本?

A:Kubernetes 除了本身有 HPA(Horizontal Pod Autoscaling)可根據使用程度自動調整資源流量,另外也能延伸使用 AWS Auto Scaling 方案,針對可擴展資源去設定自動擴展管理。另外在成本管控,雖然 Amazon EKS 會收取額外管理費用,但可透過 AWS 平台的 Calculato r計算每個 EKS 的價格,你會發現自動化部署及管理的費用,相對工程師人力的成本更加便宜。

Q:越來越多客戶考慮把現有 Application 變成容器部署,大多是爲了加快部署的效率,那麼變成容器模式之後,對 CI/CD 的工作流程有什麽影響嗎?

A:運用容器技術最直接的效果,可以讓應用程式的環境更一致化,例如 testing 環節、stage production,讓容器避開一些差異問題。至於 CD 部分要 delivery 一些 usage 不太一樣的時候,容器會幫忙做配置,所以 CI/CD 對容器的效益是相輔相成的。

Q: 客戶在開發流程漸漸會把 Infrastructure 變成代碼或文檔,是不是可以把程式碼跟現有的應用程式的 CI/CD 流水線整合在一起,達到一套完整的 CI/CD 部署流程?

A:觀察目前市場作法,主要分成兩個階段去做整體部署。如果規模比較小的團隊,會把 Infrastructure 代碼跟 App 代碼分開,在管理上會比較靈活;如果企業規模比較大,會有另外一個 Infrastructure 團隊來控制部署事情,這種情况之下,APP 的項目會生成一個 APP package,主要做到 delivery 這個階段爲止。而 Infrastructure 的項目會指定把需要版本的文檔,部署到他們的 Kubernetes Cluster。

填寫表單 找到適合的快速上雲服務與工具!