一键导入
testing
Use when writing, updating, or reviewing tests for Zeph. Covers unit test conventions, fixture-based integration tests, and cloud regression tests.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when writing, updating, or reviewing tests for Zeph. Covers unit test conventions, fixture-based integration tests, and cloud regression tests.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | testing |
| description | Use when writing, updating, or reviewing tests for Zeph. Covers unit test conventions, fixture-based integration tests, and cloud regression tests. |
Follow these conventions when writing or modifying tests for Zeph.
Pure functions tested with inline #[cfg(test)] modules — no I/O, no mocking.
src/commands/summary.rs| Function | What to test |
|---|---|
friendly_dtype() | Maps NumPy dtype codes to friendly names (<f4 -> float32, etc.) |
is_coordinate() | True when dims.len() == 1 && dims[0] == name |
format_dims_parens() | Formats dims as (time, lat, lon) |
format_shape() | Formats shape as 100 x 200 x 300 |
dir_size_bytes() | Recursive directory size calculation (use a temp dir) |
src/zarr/store.rs| Function | What to test |
|---|---|
StoreLocation::parse() | Classifies s3://, gs://, az://, HTTPS, and local paths |
display_path() | Abbreviates local paths with ~, returns cloud URLs as-is |
src/zarr/metadata.rs| Function | What to test |
|---|---|
parse_store() | Given .zmetadata JSON, produces correct StoreMeta (arrays, dims, attrs) |
For parse_store(), construct StoreLocation::Local pointing at a fixture directory containing a .zmetadata file (see Integration Tests below).
Test the full parsing pipeline using real .zmetadata files as fixtures. These complement the unit tests (which use synthetic JSON) by verifying that real-world metadata files parse correctly end-to-end.
.zmetadata is a pure JSON format with no dependency on the storage backend — the same dataset produces an identical file whether stored on S3, GCS, or local disk. The storage layer only affects how bytes are fetched (already covered by unit tests and cloud regression tests). So fixtures should be chosen for structural diversity, not cloud provider coverage.
tests/
fixtures/
wb2_era5/
.zmetadata <- WeatherBench2 ERA5 (64x32, 1 week) from GCS
The wb2_era5 fixture provides good structural coverage in a single file:
<f4, <f8, <i8long_name/short_name/standard_name/units, others have nonetime, latitude, longitude, level (1D arrays whose sole dimension matches their name)A second fixture would only add value if it's structurally different (e.g., non-empty root attributes, very few arrays, unusual dtypes). Don't add fixtures just to cover different cloud providers.
Test at the parse_store() level — the meaningful contract is the StoreMeta struct, not the rendered terminal output:
parse_store() succeeds without error_ARRAY_DIMENSIONSis_coordinate())This avoids fragile assertions on ANSI escape codes or column alignment.
#[test]
fn parse_wb2_era5_fixture() {
let location = StoreLocation::Local(PathBuf::from("tests/fixtures/wb2_era5"));
let runtime = tokio::runtime::Runtime::new().unwrap();
let meta = parse_store(&location, &runtime).unwrap();
assert_eq!(meta.zarr_format, 2);
assert_eq!(meta.arrays.len(), 66);
assert!(meta.root_attrs.is_empty());
// Coordinate variables (1D, dimension name == array name)
let time = meta.arrays.iter().find(|a| a.name == "time").unwrap();
assert_eq!(time.shape, vec![28]);
assert_eq!(time.dtype, "<i8");
assert_eq!(time.dims, vec!["time"]);
// 4D pressure-level variable
let temp = meta.arrays.iter().find(|a| a.name == "temperature").unwrap();
assert_eq!(temp.shape, vec![28, 13, 64, 32]);
assert_eq!(temp.dtype, "<f4");
assert_eq!(temp.dims, vec!["time", "level", "longitude", "latitude"]);
assert_eq!(temp.attrs["units"], serde_json::json!("K"));
}
Test against real public cloud zarr stores. These are slow and require network access, so they MUST be marked #[ignore] and run explicitly with cargo test -- --ignored.
| Provider | Dataset | Path |
|---|---|---|
| GCS | CMIP6 | gs://cmip6/CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/historical/r10i1p1f1/day/pr/gn/v20190710 |
| S3 | MUR SST | s3://mur-sst/zarr/ |
| HTTPS | CMIP6 | https://storage.googleapis.com/cmip6/CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/historical/r10i1p1f1/day/pr/gn/v20190710 |
| HTTPS | NOAA GEFS (v3) | https://data.dynamical.org/noaa/gefs/analysis/latest.zarr/ |
The GCS and HTTPS tests point at the same underlying dataset via different protocols, which lets us verify that both code paths produce identical results.
The S3 test also exercises the detect_s3_region() auto-detection path, since no AWS_DEFAULT_REGION env var will be set.
The NOAA GEFS test is the only v3 cloud store test. It exercises v3 consolidated metadata discovery (zarr.json), sharding codecs (sharding_indexed), and root-level attributes.
Keep assertions stable — only check properties unlikely to change:
parse_store() succeeds without error#[test]
#[ignore] // requires network
fn cloud_gcs_cmip6() {
let location = StoreLocation::parse(
"gs://cmip6/CMIP6/CMIP/MPI-M/MPI-ESM1-2-LR/historical/r10i1p1f1/day/pr/gn/v20190710",
)
.unwrap();
let runtime = tokio::runtime::Runtime::new().unwrap();
let meta = parse_store(&location, &runtime).unwrap();
assert_eq!(meta.zarr_format, 2);
assert!(meta.arrays.iter().any(|a| a.name == "pr"));
}
az:// and https://*.blob.core.windows.net) but no publicly accessible anonymous Zarr V2 stores on Azure Blob Storage have been identified. Revisit if a suitable public store becomes available.cargo test # unit + fixture integration tests
cargo test -- --ignored # also run cloud regression tests