{"id":25834,"library":"kmp-test-runner","title":"kmp-test-runner","description":"Parallel test runner for Kotlin Multiplatform and Android Gradle projects. v0.6.2 is the current stable release, with frequent iterative releases (10+ versions since v0.3.7). Key differentiator: token-efficient output for AI coding agents — provides markdown-summarised stdout or single-line JSON envelopes, reducing token cost up to 1200× vs raw Gradle output. Supports parallel, coverage, changed, and benchmark test modes with summary JSON, parallel execution, and lockfile-based concurrent-invocation safety. Requires Node >=18 and a Gradle-based KMP or Android project.","status":"active","version":"0.6.2","language":"javascript","source_language":"en","source_url":"https://github.com/oscardlfr/kmp-test-runner","tags":["javascript","kotlin","kotlin-multiplatform","kmp","android","gradle","test-runner","parallel-tests","coverage"],"install":[{"cmd":"npm install kmp-test-runner","lang":"bash","label":"npm"},{"cmd":"yarn add kmp-test-runner","lang":"bash","label":"yarn"},{"cmd":"pnpm add kmp-test-runner","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"ESM-only package since v0.3.0. CommonJS require will fail.","wrong":"const createTestRunner = require('kmp-test-runner')","symbol":"createTestRunner","correct":"import { createTestRunner } from 'kmp-test-runner'"},{"note":"Named export, not default.","wrong":"import kmpTestRunner from 'kmp-test-runner'","symbol":"runTests","correct":"import { runTests } from 'kmp-test-runner'"},{"note":"CamelCase name. Underscore variants will not resolve.","wrong":"import { parse_script_output } from 'kmp-test-runner'","symbol":"parseScriptOutput","correct":"import { parseScriptOutput } from 'kmp-test-runner'"}],"quickstart":{"code":"import { runTests } from 'kmp-test-runner';\n\nconst result = await runTests({\n  projectRoot: process.cwd(),\n  features: ['parallel', 'coverage'],\n  json: true\n});\n\nif (result.exitCode !== 0) {\n  console.error('Tests failed:', result.errors);\n} else {\n  console.log('Passed:', result.tests.passed, 'Failed:', result.tests.failed);\n}","lang":"typescript","description":"Shows how to programmatically run parallel and coverage tests with JSON output, handling errors and test counts."},"warnings":[{"fix":"Ensure Gradle JDK toolchain matches the runtime JDK, or use --no-fail-on-toolchain-mismatch flag.","message":"v0.5.0 changed JDK toolchain mismatch from warning to blocking error by default. Projects with mismatched JDK versions will fail.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Use --force flag to bypass lockfile (careful: may corrupt output) or wait for first run to finish.","message":"Concurrent-invocation lockfile v0.3.8+ prevents multiple kmp-test runs on same project root. Second arrival refuses to run if first PID is alive.","severity":"gotcha","affected_versions":">=0.3.8"},{"fix":"Check build-logic files for unintended coverage signals. Consider --no-detect-build-logic-coverage.","message":"v0.5.2 build-logic coverage detection may false-positive on convention plugin names (e.g., 'androidApplicationJacoco').","severity":"gotcha","affected_versions":">=0.5.2"},{"fix":"Replace --no-summary with --json.","message":"v0.4.1 deprecated the old CLI flag --no-summary in favor of --json. --no-summary still works but will be removed in 1.0.","severity":"deprecated","affected_versions":">=0.4.1"},{"fix":"Update consumer code to handle objects with property 'source' ('convention' or 'self').","message":"v0.6.0 changed detectBuildLogicCoverageHints output format: now distinguishes CONVENTION vs SELF kover/jacoco signals. Custom consumers may break.","severity":"breaking","affected_versions":">=0.6.0"},{"fix":"Check dry_run field before consuming test counts.","message":"--dry-run flag exits 0 without running tests, but under --json it outputs a dry_run: true envelope with all-zero counts. Agents expecting real test data will misinterpret.","severity":"gotcha","affected_versions":">=0.3.7"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Run 'npm install -g kmp-test-runner' for CLI or 'npm install kmp-test-runner' for programmatic use.","cause":"Package not installed or global install missing.","error":"Error: Cannot find module 'kmp-test-runner'"},{"fix":"Use 'import { runTests } from \"kmp-test-runner\"'.","cause":"Default import instead of named import (ESM-only package).","error":"TypeError: runTests is not a function"},{"fix":"Check module names: use --list-modules to see available modules, adjust filter pattern.","cause":"Filter pattern does not match any test module, or module has no test source set.","error":"[ERROR] No modules found matching filter: <pattern>"},{"fix":"Install JDK 21+ or set GRADLE_HOME to a compatible JDK version. Use --no-fail-on-toolchain-mismatch to disable blocking error (v0.5.0+).","cause":"Gradle toolchain requires a newer JDK (e.g., JDK 21 for class version 65.0) but runtime is older JDK.","error":"UnsupportedClassVersionError: class file version 65.0"},{"fix":"Wait for other process to finish, or kill it. Use --force to override (risks output corruption).","cause":"Another process holds the lockfile in same project root.","error":"Lockfile active: another kmp-test instance is running"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}