Skip to content

Test: build real InvocationContexts in the skill-script integration fixtures - #835

Open
AmaadMartin wants to merge 1 commit into
mainfrom
fix/integration-skill-script-test-contexts
Open

Test: build real InvocationContexts in the skill-script integration fixtures#835
AmaadMartin wants to merge 1 commit into
mainfrom
fix/integration-skill-script-test-contexts

Conversation

@AmaadMartin

@AmaadMartin AmaadMartin commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Please ensure you have read the contribution guide before creating a pull request.

Link to Issue or Description of Change

  1. Link to an existing issue (if applicable):
    N/A

  2. Or, if no issue exists, describe the change:
    Problem: The createMockContext helper in both skill-script integration test files casts an object literal through as unknown as InvocationContext. That double cast turns off structural checking, so the compiler cannot see that the fake omits invocationId and pluginManager, which the tool under test reads. If RunSkillScriptTool starts using a field the fake lacks, the suite fails at runtime with a TypeError instead of failing to compile.

Solution: Both helpers now build the real object graph from the @google/adk public entry point: a real LlmAgent, Session, PluginManager and InvocationContext. This follows the ADK JS guideline "Use Factory Functions in Tests" and copies the construction pattern in core/test/tools/agent_tool_test.ts. No production source, test name, assertion, or test count changes.

The three newly-real fields are inert here. invocationId only keys the getOrFetchSkill cache, which returns this.skills[name] before reading the cache for statically registered skills. UnsafeLocalCodeExecutor reads nothing off invocationContext, so the process.cwd() assertions are unaffected. The isLlmAgent(agent) -> agent.codeExecutor fallback stays unreachable because both suites always pass {codeExecutor: executor}.

Collision check: I listed the 300 open PRs on the fork and read the diffs of every PR that touches these two files (#634, #564, #556) plus the adjacent context-fixture PRs (#748, #750, #753). None replaces this cast. #564 removes an identical cast in core/test/utils/artifact_utils_test.ts, a different file. #556 and #634 edit test bodies in these files but not the helper, so this PR branches from main rather than stacking.

Testing Plan

Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.

This change adds no test. It rewrites two fixture helpers, so the acceptance evidence is the unchanged test inventory plus a clean type check.

npx vitest run --project integration \
  tests/integration/tools/run_skill_script_tool_test.ts \
  tests/integration/tools/run_skill_inline_script_tool_test.ts

 ✓ |integration| tests/integration/tools/run_skill_script_tool_test.ts (12 tests | 4 skipped)
 ✓ |integration| tests/integration/tools/run_skill_inline_script_tool_test.ts (10 tests)
 Test Files  2 passed (2)
      Tests  18 passed | 4 skipped (22)

The 4 skips are the Windows-only PowerShell and cmd cases (it.skipIf(!IS_WINDOWS)).

Proof the fixture can fail. For a suppression removal the mutation is a compile-time one. I deleted pluginManager: new PluginManager([]), from createMockContext and ran npx tsc --noEmit:

tests/integration/tools/run_skill_script_tool_test.ts(35,53): error TS2345: Argument of type
'{ invocationId: string; agent: LlmAgent; session: Session; }' is not assignable to parameter
of type 'InvocationContextParams'.
  Property 'pluginManager' is missing in type '{ invocationId: string; agent: LlmAgent;
  session: Session; }' but required in type 'InvocationContextParams'.

The old cast suppressed exactly this error. I restored the line afterwards.

tsc --noEmit has a dirty baseline on main: 771 error lines across pre-existing files, none in these two. I captured the full output before and after this change and diff reports them byte-identical, so this PR adds no type error.

Also clean: npx prettier --check and npx eslint on both files, and grep -rn "as unknown as InvocationContext" tests/integration/ returns nothing.

Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.

npm install
npm run build      # tests/global_setup.ts imports the built @google/adk
npx vitest run --project integration \
  tests/integration/tools/run_skill_script_tool_test.ts \
  tests/integration/tools/run_skill_inline_script_tool_test.ts

These suites run real scripts through UnsafeLocalCodeExecutor, with no mocked executor.

CI note: the first macOS leg failed on tests/integration/app_loader/app_loader_test.ts with Test timed out in 40000ms. That file is unrelated to this diff, and the leg passed on re-run. All three run-tests legs (ubuntu, macos, windows) are green.

Checklist

[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.

…ixtures

Both fixtures cast an object literal through `as unknown as
InvocationContext`, which turns off structural checking for everything the
tool under test reads off the context. Build the real graph instead: a real
LlmAgent, Session, PluginManager and InvocationContext, all from the
@google/adk public entry point.

No test name, assertion or count changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant