Skip to main content

open-harness-testlens

Test coverage detector. Finds source files that don't have a corresponding test file, across 10 languages. Single native binary, zero runtime dependencies.

Part of the open-harness monorepo. Español abajo.

Same tool, other ecosystems: also available on npm (@open_harness/testlens) and on Packagist (open-harness/testlens). Identical binary, identical config; pick the registry that matches your stack.

Install

pip install open-harness-testlens

pip picks the right native wheel for your platform automatically (Linux x86_64, macOS arm64, macOS x86_64, Windows x86_64). Each wheel embeds the Go binary — no runtime deps.

Usage

testlens check                       # auto-detect language and scan
testlens check --lang typescript     # force a specific language
testlens check --dir ./src           # scan a specific directory
testlens check --config my.json      # use a specific config file
testlens check --fail                # exit 1 if files without tests are found
testlens init                        # generate a default config
testlens version                     # print version

Supported languages

Language Source extensions Test patterns
Go .go *_test.go
TypeScript .ts, .tsx *.test.ts, *.spec.ts, test_*.ts
JavaScript .js, .jsx *.test.js, *.spec.js, test_*.js
Python .py *_test.py, test_*.py
Ruby .rb *_spec.rb, *_test.rb
Rust .rs *_test.rs
Java .java *Test.java
Kotlin .kt, .kts *Test.kt
C# .cs *Tests.cs
Dart .dart *_test.dart (in test/ mirror of lib/)

Configuration

Place a testlens.json at the repo root:

{
  "language": "auto",
  "exclude": ["node_modules", ".git", "vendor", "dist", "build", "testdata"]
}
  • languageauto (default), go, typescript, javascript, python, ruby, rust, java, kotlin, csharp, dart.
  • exclude — directories to skip during the scan.

Alternative: configure inside pyproject.toml or the dedicated testlens.json

If you prefer not to keep a separate testlens.json, add a testlens key in your package.json with the same shape:

{
  "name": "my-project",
  "testlens": {
    "language": "typescript",
    "exclude": ["node_modules", "dist", "fixtures"]
  }
}

Precedence: --config <path> > testlens.json > package.json key > built-in defaults. CLI flags win when passed explicitly (fs.Visit); if you don't pass --lang, the value from the config is used.

Supported test layouts

testlens recognises colocated, adjacent subdirs, mirror trees, and centralised test roots that mirror the source path:

Pattern Example
Colocated src/foo.tssrc/foo.test.ts
Adjacent subdir src/foo.tssrc/__tests__/foo.test.ts
Centralised tests root (F-016) src/services/foo.tssrc/__tests__/services/foo.test.ts
Mirror (Python) src/auth/user.pytests/auth/test_user.py
Mirror (Maven) src/main/java/com/X/Bar.javasrc/test/java/com/X/BarTest.java

Per language defaults:

testlens looks for tests in these locations (per language):

Language Colocated Subdir Mirror
Go foo.gofoo_test.go
TypeScript / JavaScript foo.tsfoo.test.ts __tests__/foo.test.ts, tests/foo.spec.ts
Python foo.pytest_foo.py tests/test_foo.py src/foo.pytests/foo.py
Ruby foo.rbfoo_spec.rb spec/foo_spec.rb lib/foo.rbspec/foo.rb
Java / Kotlin src/main/java/.../Bar.javasrc/test/java/.../BarTest.java
Rust foo.rsfoo_test.rs tests/foo_test.rs

testlens vs vitest --coverage, jest, pytest-cov

These have different goals — use both:

testlens Real coverage tools
Speed milliseconds (file walk) seconds to minutes (compile + execute + instrument)
Detects files without tests partial (only files actually loaded by a test)
Detects untested lines
Detects untested branches
Works as pre-commit hook too slow

testlens is a fast smoke test of test-file existence, intended as a pre-flight gate. For real functional coverage metrics, run Vitest, Jest, pytest-cov, etc. as a separate (slower) CI step.

Why this exists

Coverage tools tell you which lines are tested. testlens tells you which files have no test at all — a different and complementary check. It surfaces orphan modules early, when adding a first test is cheapest. Combine both for a complete picture.

Integrations

# Husky pre-commit
testlens check --fail
# GitHub Actions
- name: Detect source files without tests
  run: npx @open_harness/testlens check --fail --lang typescript --dir src/

Exit codes

Code Meaning
0 All source files have tests (or --fail not passed)
1 Files without tests found and --fail was passed, or config error

Español

Detector de cobertura de tests. Encuentra archivos fuente que no tienen un archivo de test correspondiente, en 10 lenguajes. Un solo binario nativo, cero dependencias.

Parte del monorepo open-harness.

Instalación

pip install open-harness-testlens

pip descarga automáticamente la wheel nativa correcta para tu plataforma.

Uso

testlens check                       # autodetecta lenguaje y escanea
testlens check --lang typescript     # fuerza un lenguaje específico
testlens check --dir ./src           # escanea un directorio específico
testlens check --config my.json      # usa un archivo de config específico
testlens check --fail                # exit 1 si hay archivos sin test
testlens init                        # genera la config por defecto
testlens version                     # imprime la versión

Lenguajes soportados

Go, TypeScript, JavaScript, Python, Ruby, Rust, Java, Kotlin, C#, Dart. Ver la tabla arriba para las extensiones y patrones de naming de test que reconoce cada uno.

Configuración

Colocá un testlens.json en la raíz del repo (ver ejemplo arriba).

  • languageauto (default), go, typescript, javascript, python, ruby, rust, java, kotlin, csharp, dart.
  • exclude — directorios a ignorar durante el escaneo.

Alternativa: configurar dentro de pyproject.toml o testlens.json

Si preferís no tener un testlens.json separado, agregá una key testlens en tu package.json con la misma forma. Precedencia: --config <path> > testlens.json > key en package.json > defaults. Los flags CLI ganan solo cuando se pasan explícitamente; si omitís --lang, se usa el valor de la config.

Layouts de test soportados

testlens busca tests en estas ubicaciones (por lenguaje):

Lenguaje Co-ubicado Subdir Mirror
Go foo.gofoo_test.go
TypeScript / JavaScript foo.tsfoo.test.ts __tests__/foo.test.ts, tests/foo.spec.ts
Python foo.pytest_foo.py tests/test_foo.py src/foo.pytests/foo.py
Ruby foo.rbfoo_spec.rb spec/foo_spec.rb lib/foo.rbspec/foo.rb
Java / Kotlin src/main/java/.../Bar.javasrc/test/java/.../BarTest.java
Rust foo.rsfoo_test.rs tests/foo_test.rs

testlens vs vitest --coverage, jest, pytest-cov

Tienen finalidades distintas — usá los dos:

testlens es un smoke test ultra-rápido de existencia de archivos de test, pensado como gate de pre-commit. Para métricas funcionales de cobertura (líneas/branches ejercidas) corré Vitest, Jest, pytest-cov, etc. como step separado de CI. testlens corre en milisegundos; un coverage tool real toma segundos a minutos.

Por qué existe

Las herramientas tradicionales de cobertura te dicen qué líneas están testeadas. testlens te dice qué archivos no tienen ningún test — una verificación distinta y complementaria. Detecta módulos huérfanos temprano, cuando agregar el primer test es más barato. Combinalos para tener una vista completa.

Integraciones

Sirve con Husky, lefthook o GitHub Actions usando los snippets de la sección en inglés.

Códigos de salida

Código Significado
0 Todos los archivos fuente tienen tests (o no se pasó --fail)
1 Hay archivos sin test con --fail, o error de configuración

License

MIT — see the main repository.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

open_harness_testlens-0.3.3-py3-none-win_amd64.whl (2.2 MB view details)

Uploaded Python 3Windows x86-64

open_harness_testlens-0.3.3-py3-none-macosx_11_0_arm64.whl (988.4 kB view details)

Uploaded Python 3macOS 11.0+ ARM64

open_harness_testlens-0.3.3-py3-none-macosx_10_9_x86_64.whl (1.1 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file open_harness_testlens-0.3.3-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for open_harness_testlens-0.3.3-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 97c6aa286f05e3818d88c3c2e3ecf2ca68f9c61a457c4fc6c26668cb849bed3d
MD5 2bd7f359b0b9be5153412df0b80c5c4a
BLAKE2b-256 0ce411c70ec3737cd9c8d485cc64a80a0aabf7d02a5ed67b226a0b2c6d63b93d

See more details on using hashes here.

File details

Details for the file open_harness_testlens-0.3.3-py3-none-manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for open_harness_testlens-0.3.3-py3-none-manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 39852eda59808dba12c8a8300fa1c542eddf3d0ea55c7af6dd4f6094466151ce
MD5 0349a46d5809c2bb7187cb871700547c
BLAKE2b-256 c2c4fbf512cd8675d07f4c723110728f6b2c1dab80af0c06e8ea6f446e4ef9fe

See more details on using hashes here.

File details

Details for the file open_harness_testlens-0.3.3-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for open_harness_testlens-0.3.3-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2774545f6d782de51ac90c4ad5d80e3e89f4e3e2a64d426ef86c5e6bbd70c87f
MD5 8bb7a3dc5246db8c5b2955966b9a7fea
BLAKE2b-256 65f3fc12bbd997b99aa041fa7bf4c72db40572a534ff50384cb79c93754287f4

See more details on using hashes here.

File details

Details for the file open_harness_testlens-0.3.3-py3-none-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for open_harness_testlens-0.3.3-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 0145bf3cd93550033c6acdbb1857a597f8e22dc07c64d5caa3c7ceb9e44ef64f
MD5 eccae7fb6da6eee72f083f3e00101e19
BLAKE2b-256 842a392eb08e77ee8a17c2d90531e5e0db4f10a25e44a5cf88ab0c5cacd62a65

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.3.3 This release

4 files

0.3.2

4 files

0.3.1

4 files

0.3.0

4 files

0.2.5

4 files

0.2.3

4 files

0.2.2

4 files

0.2.1

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page