測試 🧪#
在本節中,我們概述在 Arrow 中進行單元測試所需的步驟。
我們在 Python 中使用 pytest 進行單元測試。有關所需套件的更多資訊,請參閱 Python 單元測試章節。
結構
PyArrow 中的測試佈局遵循 pytest
結構,適用於 作為應用程式碼一部分的測試
pyarrow/
__init__.py
csv.py
dataset.py
...
tests/
__init__.py
test_csv.py
test_dataset.py
...
Parquet 的測試位於單獨的資料夾 pyarrow/tests/parquet/
中。
執行測試
若要執行特定的單元測試,請從終端機的 arrow/python
資料夾中使用此命令
$ pytest pyarrow/tests/test_file.py -k test_your_unit_test
從一個檔案執行所有測試
$ pytest pyarrow/tests/test_file.py
執行所有測試
$ pytest pyarrow
您也可以使用 python -m pytest [...]
執行測試,這幾乎等同於直接使用 pytest [...]
,但透過 python 呼叫也會將目前目錄新增至 sys.path
,並且在某些情況下,如果 pytest [...]
導致 ImportError 時,這可能會有所幫助。
重新編譯 PyArrow 或 Arrow C++
如果測試開始失敗,請嘗試重新編譯 PyArrow 或 Arrow C++。請參閱 建置其他 Arrow 函式庫 章節中 PyArrow 標籤下的註解。
夾具 (Fixtures)
在 PyArrow 測試檔案中,可以定義輔助函數和夾具 (fixtures)。也使用了其他 pytest 裝飾器,例如 @parametrize
或 @skipif
。
例如
_alltypes_example
在test_pandas
中為所有資料類型提供一個包含 100 列的資料框架。_check_pandas_roundtrip
在test_pandas
中斷言從Pandas
經過pa.Table
或pa.RecordBatch
再回到Pandas
的往返是否產生相同的結果。large_buffer
夾具 (fixture) 為test_serialization.py
中的函數test_primitive_serialization(large_buffer)
提供固定大小的 PyArrow 緩衝區。
因此,最好瀏覽您計劃新增測試的檔案,看看是否有任何已定義的函數或夾具 (fixtures) 會有所幫助。
有關 pytest
的更多資訊,請訪問 完整 pytest 文件
我們在 R 中使用 testthat 進行單元測試。更具體地說,我們使用 testthat 的第三版。在極少數情況下,我們可能需要 testthat 第二版的行為,這由 testthat::local_edition(2)
指示。
結構
預期常見的 testthat 資料夾結構
tests
├── testthat # test files live here
└── testthat.R # runs tests when R CMD check runs (e.g. with devtools::check())
這是使用 testthat
在 R 中進行測試的基本結構。testthat.R
等檔案預期不會經常變更。對於 arrow
R 套件,testthat.R
也定義了各種測試的結果如何在主控台中顯示/報告。
通常,R/
子資料夾中的大多數檔案在 tests/testthat
中都有對應的測試檔案。
執行測試
若要在本機執行套件中的所有測試,請呼叫
devtools::test()
在 R 主控台中。或者,您可以使用
$ make test
在 Shell 中。
您可以使用以下命令在您開啟的單個測試檔案中執行測試
devtools::test_active_file()
所有測試也會作為我們的持續整合 (CI) 管道的一部分執行。
Arrow R 開發人員指南也有一個章節 介紹如何執行測試。
良好實務
一般來說,對原始碼的任何變更都需要附帶單元測試。所有測試都應在 Pull Request 合併之前通過。
新增功能 -> 新增單元測試
修改功能 -> 更新單元測試
解決錯誤 -> 在解決錯誤之前新增單元測試,這有助於證明錯誤及其修復
效能改進應反映在效能基準 (benchmark) 中 (這也是測試)
例外情況可能是重構完全由單元測試涵蓋的功能
一個好的經驗法則是:如果新功能是面向使用者或 API 的變更,您幾乎肯定需要變更測試 — 如果不需要變更測試,則可能表示測試不正確!如果新功能是重構且沒有 API 變更,則可能不需要變更測試。
測試輔助函數
為了補充 testthat
功能,arrow
R 套件定義了一系列特定的實用函數 (稱為輔助函數),例如
期望 (expectations) - 這些以
expect_
開頭,用於比較物件例如,
expect_…_roundtrip()
函數接受一個輸入,將其轉換為其他格式 (例如 arrow, altrep),然後再轉換回來,以確認值是否相同。x <- c(1, 2, 3, NA_real_) expect_altrep_roundtrip(x, min, na.rm = TRUE)
skip_
- 跳過單元測試 - 將它們視為可接受的失敗。我們可能想要跳過單元測試的情況skip_if_r_version()
- 這是特定的arrow
跳過。例如,當 R 版本為 3.5.0 及更低版本時,我們使用它來跳過單元測試 (skip_if_r_version(“3.5.0”)
)。當我們正在測試的功能依賴於 R 3.5.0 版本之後引入的功能時 (例如向量的替代表示法 Altrep,在 R 3.5.0 中引入,但在後續版本中進行了重大新增),您可能會看到它被使用。作為我們 CI 工作流程的一部分,我們會針對不同版本的 R 進行測試,而這就是此功能的作用所在。skip_if_not_available()
- 另一個特定的 {arrow} 跳過。Arrow (libarrow) 有許多可開啟或關閉的可選功能 (這在建置時發生)。如果單元測試依賴於此類功能,並且此功能不可用 (即在建置 libarrow 時未選擇),則會跳過測試,而不是測試失敗。skip_if_offline()
- 將不會執行需要網際網路連線的測試skip_on_os()
- 用於特定於 OS 的單元測試。
重要:一旦滿足
skip_()
語句的條件,同一個test_that()
測試區塊中的其他程式碼行將不會被執行。如果skip
在test_that()
程式碼區塊之外,它將跳過檔案的其餘部分。
有關 R 中單元測試的更多一般資訊