Skip to content

Add CLI integration tests for find and resolve commands #355

@karthiknadig

Description

@karthiknadig

Summary

We have end-to-end tests for the JSONRPC server (see crates/pet/tests/e2e_performance.rs and related test files), but no integration tests for the CLI find and resolve commands. We need CLI tests that exercise the same binary via std::process::Command, similar to how the server tests spawn the pet process.

Scope

Test 1: find --json basic output validation

  • Run pet find --json
  • Parse stdout as JSON
  • Validate the structure has managers and environments arrays
  • Validate each environment has required fields (executable, kind, etc.)

Test 2: resolve --json output validation

  • Run pet find --json, pick an executable from the results
  • Run pet resolve <exe> --json
  • Parse stdout as JSON
  • Validate the resolved environment has a version field populated
  • Validate executable matches what was passed in

Test 3: find --kind filtering

  • Run pet find --kind <known_kind> --json
  • Validate all returned environments match the specified kind

Test 4: find --workspace scoping

  • Run pet find --workspace --json with a known directory
  • Validate only workspace-scoped environments are returned

Test 5: CLI args + env var equivalence (after #353)

  • Run pet find --conda-executable /path/to/conda --json
  • Run PET_CONDA_EXECUTABLE=/path/to/conda pet find --json
  • Validate both produce the same results
  • Validate CLI flag takes precedence over env var when both are set

Test 6: Glob expansion in search paths (after #354)

  • Create temp directories matching a glob pattern
  • Run pet find '/tmp/test_*/venv' --json (quoted glob)
  • Validate the glob was expanded and environments were searched in matching directories

Implementation approach

  • Create crates/pet/tests/cli_test.rs
  • Use std::process::Command to spawn ./target/debug/pet (same pattern as e2e_performance.rs)
  • Use the ci feature flag for tests that need a real Python on PATH
  • Parse JSON output with serde_json
  • Use assert_cmd crate if desired, but std::process::Command is sufficient

Example test skeleton

#[test]
#[cfg(feature = "ci")]
fn find_json_output_is_valid() {
    let output = Command::new(env!("CARGO_BIN_EXE_pet"))
        .args(["find", "--json"])
        .output()
        .expect("failed to run pet");

    assert!(output.status.success());
    let result: Value = serde_json::from_slice(&output.stdout)
        .expect("stdout is not valid JSON");
    assert!(result["environments"].is_array());
    assert!(result["managers"].is_array());
}

#[test]
#[cfg(feature = "ci")]
fn resolve_json_output_has_version() {
    // First find an environment
    let find_output = Command::new(env!("CARGO_BIN_EXE_pet"))
        .args(["find", "--json"])
        .output()
        .expect("failed to run pet find");
    let found: Value = serde_json::from_slice(&find_output.stdout).unwrap();
    let exe = found["environments"][0]["executable"].as_str().unwrap();

    // Then resolve it
    let resolve_output = Command::new(env!("CARGO_BIN_EXE_pet"))
        .args(["resolve", exe, "--json"])
        .output()
        .expect("failed to run pet resolve");

    assert!(resolve_output.status.success());
    let resolved: Value = serde_json::from_slice(&resolve_output.stdout).unwrap();
    assert!(resolved["version"].is_string());
}

Depends on

Tests for the base find --json and resolve --json can land independently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions