Skip to content

Running Tests

shieldkit uses Vitest for unit and integration tests.

Test inventory

CommandTest filesTest casesIn merge gate?
npm run test:run38163Yes (npm run ci)
npm run test:redteam28No (nightly workflow, advisory)

On GitHub Actions (no Ollama), test:run reports 159 passed and 4 skipped — the Ollama integration file. Locally with Ollama running, all 163 run.

Details: Verification matrix.

CI pipeline

GitHub Actions runs on every push and PR to main / master. Full reference: CI and automation.

Merge gate (ci.yml)

StepCommand
Quality gatenpm run ci (lint, format, typecheck, test, full-tree audit)
Librarynpm run build
Docsnpm run docs:build
Packagenpm pack --dry-run

Node 22. Must pass with zero errors and zero warnings.

Other workflows

WorkflowBlocks merge?Purpose
AI SDK CompatibilityWhen triggered on PRai lockfile vs latest matrix
Red TeamNoNightly Ollama injection tests
DocsWhen docs changeVitePress / GitHub Pages
CodeQLAdvisoryStatic security analysis

Vercel AI SDK updates: Dependency policy · npm run check:ai-sdk

Commands

CommandPurpose
npm run testVitest watch mode (re-runs on file changes)
npm run test:runSingle run — used in CI (unit + integration + adversarial)
npm run test:adversarialAdversarial corpus + contrast harness (mock model)
npm run test:redteamOllama live red team (skipped if Ollama off)
npm run test:assuranceAdversarial + red team combined
npm run demo9-section tour, 31 PASS/FAIL checks (mock + optional Ollama)
npm run ciFull quality gate (lint, format, typecheck, test, full-tree audit)
npm run check:ai-sdkCompare lockfile ai pin vs npm latest
npm run verify:ai-sdk-latestTypecheck + test + build on ai@latest (run npm ci after)

Test layout

tests/
├── helpers/
│   ├── mock-model.ts
│   ├── contrast-harness.ts
│   └── load-adversarial-fixtures.ts
├── unit/
│   ├── …
│   └── tools/guard-tools.test.ts
├── integration/
│   └── ollama.test.ts          # Live Ollama (conditional)
├── adversarial/                # Corpus + contrast (always in CI)
│   ├── injection-corpus.test.ts
│   ├── contrast.test.ts
│   └── …
├── redteam/                    # Excluded from test:run — use test:redteam
│   └── ollama-redteam.test.ts
└── fixtures/
    └── adversarial/            # JSON fixture corpus

Vitest config (vitest.config.ts):

  • Environment: Node
  • Pattern: tests/**/*.test.ts (excludes tests/redteam/ — use npm run test:redteam)
  • Timeout: 60 seconds (integration tests may need up to 90s per test)

Ollama integration tests

tests/integration/ollama.test.ts checks Ollama availability at load time:

ts
const ollamaAvailable = await isOllamaAvailable();
describe.skipIf(!ollamaAvailable)('ollama integration', () => { ... });

If Ollama is not running, all four integration tests are skipped (not failed).

Running integration tests locally

  1. Install and start Ollama
  2. Pull a model: ollama pull llama3.2
  3. Run tests:
bash
OLLAMA_HOST=http://127.0.0.1:11434 OLLAMA_MODEL=llama3.2 npm run test:run
VariableDefaultPurpose
OLLAMA_HOSThttp://127.0.0.1:11434Ollama API base URL
OLLAMA_MODELllama3.2Model name for integration tests

What integration tests cover

  • Text generation through shield()
  • Streaming through shield()
  • Injection blocking (strict mode) vs raw model passthrough
  • Structured output with repair enabled

Adversarial assurance

bash
npm run test:adversarial   # corpus + contrast logging
CONTRAST_VERBOSE=1 npm run test:adversarial   # full audit JSON
npm run test:redteam       # Ollama red team (optional; 7 strict-block prompts)
npm run test:assurance     # adversarial then red team

Reports written to test-results/ (gitignored): contrast-report.json, adversarial-summary.json.

Red team vs merge gate

Red team is not part of npm run ci. Nightly workflow .github/workflows/redteam.yml runs with continue-on-error: true and REDTEAM_STRICT=0 so flaky live-model results do not block merges. Locally, use default strict mode (REDTEAM_STRICT=1) to hard-fail on unblockable prompts.

See Adversarial assurance plan and Security assurance report.

Environment variables

VariableDefaultPurpose
TEST_VERBOSEoffLog audit/guard/contrast decisions in tests
CONTRAST_VERBOSEoffAlias for TEST_VERBOSE in contrast suite
OLLAMA_HOSThttp://127.0.0.1:11434Ollama API base URL
OLLAMA_MODELllama3.2Model tag for integration/red team
REDTEAM_STRICT1Set 0 for advisory red team (nightly CI)
RUN_FRONTIER_REDTEAMoffEnable frontier smoke test

What CI does not test

  • Frontier APIs (OpenAI, Anthropic, Google) — no API keys in CI (use RUN_FRONTIER_REDTEAM=1 locally)
  • Code coverage thresholds — not configured in Vitest

CI does run npm run build and npm run docs:build on every push and PR.

Troubleshooting

IssueSolution
Integration tests skippedStart Ollama and verify curl $OLLAMA_HOST/api/tags
Test timeoutIncrease per-test timeout or check Ollama model load time
npm audit fails CIRun npm audit; fix or override transitive deps (see package.json overrides)
ESLint warnings fail CIlint:check uses --max-warnings 0

Cursor Agent Skills

For AI-assisted test runs in Cursor, attach @ai-shield-local-testing — includes Ollama setup per platform (ollama-windows.md, ollama-linux.md, ollama-macos.md), OLLAMA_MODEL explanation, GPU warm-up, and the free validation checklist. See Cursor Agent Skills.

For adversarial / red-team work, see the Adversarial assurance plan.