今天的文章要介紹如何測試 Pulumi。在 Pulumi 中,可以使用不同的程式語言撰寫 IaC 程式。那麼就也可以透過每個程式語言中,所提供的測試框架進行測試。
如果有了解過如何測試程式,可能都有聽過「測試金字塔 (Test Pyramid)」。在這個理論中,將測試分成多個不同的層次。金字塔越下層的測試類別,就需要包含到越多的內容,並儘可能的讓執行速度越快越好。
在 Pulumi 中,測試也分為幾個種類:
單元測試與整合測試都是在傳統軟體測試中,耳熟能詳的詞。屬性測試是屬於 Pulumi 內比較特別的概念。
以下分別介紹在 Pulumi 中,不同的測試目的是什麼。
單元測試顧名思義就是為各別的程式碼單元進行測試,通常也處於測試金字塔的最底層。可以涵蓋越廣、越多的程式邏輯、能快速執行、並希望每個測試案例之間是沒有相依性,可以獨立執行。
基於單元測試的目的,相依性的隔離在單元測試中就成了至關重要的概念。如果不能將相依性隔離,程式之間的狀態關係絞成一坨,要快也很難。
在 Pulumi 程式中,我們最需要隔離的相依性就是 Pulumi 本身了。為什麼在 Pulumi 中,最需要隔離的反而是 Pulumi 呢?
這其實是因為透過 Pulumi 的架構在雲端上處理資源是非常耗費時間、且會相依到雲端環境。
如果我們只是想要測試所撰寫的 Component Resource,在處理傳入資料時,邏輯是否正確。例如,之前實戰練習中的 Vpc Component Resource,我想知道指定 3 個 AZ 與 3 個 Public Subnet,是否真能建立 3 個 Public Subnet,且 Route Table 都指向 Default Route Table。
這需求其實不需要雲端環境我們也能測試,如何說呢?
在使用 pulumi up
指令時,會先執行一次 preview mode,輸出可能的差異,並提供 diff details 的資訊。Pulumi 是透過 state 與 IaC 程式碼的執行結果去產生這些結果的。因此透過執行 IaC 程式碼的 Preview mode,就能很大程度的知道會有多少資源被建立了。
回過頭來說,要如何隔離 Pulumi 呢?Pulumi 內提供了 mock 相關的功能,讓我們可以將專案的程式碼與 Pulumi 之間做隔離。這樣在執行測試時,就不需要真正到雲端上建立資源,或是讀取 state 去做差異比較。可以直接使用 mock 回傳作假的值,測試 IaC 所建立的資源是否符合預期。
整合測試的目標就與單元測試不同了,通常整合測試都會引入真正的相依性進行測試。在 Pulumi 中的整合測試,就會執行整套的 Pulumi 流程,將資源真正的建立出來。
這邊通常會使用一些獨立的雲端帳號,讓測試程式可以在上面建立暫時性的環境 (ephemeral environment)。由於是實際使用真正的 Resource Provider 建立資源,因此執行時間會很長。但也是最接近真實狀況的。可以透過這種測試方式,驗證所設定的資源值是否真的可以在雲端中使用。
Note: 如果有用過 IaC 應該都會遇到這個狀況:就算 IaC 的程式沒問題,參數都有給,但是 Cloud Provider 會因為各種原因建立失敗。例如資源名稱的命名規則不符合 Cloud Provider 所需。這種錯誤就相對能在整合測試中找到,因為他是實際去測試資源是否能夠建立。
屬性測試其實並不在傳統測試的概念中有,他其實比較像 Policy as Code。
Policy as Code 是可以使用程式碼的方式,去定義資源建立的規則與限制的工具。例如我可以定義所有的雲端資源上,都需要設定 Tag 中的 Project 屬性,以方便做資源成本的控管。或是所有的防火牆規則中,都不能允許設定對任意 IP 地址的 SSH port 放行。
這些規則就是 Policy as Code 的內容,而屬性測試則是在資源部屬前,執行這些 Policy as Code 去測試資源的建立是否有違反規則。
今天先介紹了 Pulumi 中可以撰寫那些測試,接下來的文章就會實際開始撰寫測試。