Test Impact Analysis for C# / .NET, Java, and Node.js — selects only tests affected by a git diff.
Project description
opentia — Test Impact Analysis
Analyses a git diff and selects only the tests whose execution path could have been affected by the change. Skips the full suite on every push.
No external dependencies — Python 3.8+ stdlib only.
Language support: C# / .NET, Java (Maven / Gradle), and Node.js (Jest / Vitest — single packages and npm workspaces).
Requirements
| Tool | Version | Purpose |
|---|---|---|
| Python | 3.8+ | Run opentia |
| Git | any | Diff source |
Installation
pip install opentia
This installs the opentia command on your PATH.
Quick start
# Analyse the last commit
opentia --base HEAD~1 --root <path-to-your-project>
# Analyse uncommitted (staged + unstaged) changes — no commit needed
opentia --unstaged --root <path-to-your-project>
# Analyse and immediately run the selected tests
opentia --base HEAD~1 --root <path-to-your-project> --run
--root is where your .sln / .csproj / pom.xml / build.gradle / package.json lives. It does not need to be the git root — opentia locates the actual git root automatically.
Usage reference
opentia [OPTIONS] [-- TEST_ARGS]
--base REF Git ref to diff against (e.g. HEAD~1, main, origin/main)
--head REF Head ref to diff from (default: HEAD)
--root DIR Directory containing project files (default: .)
--strategy project | convention | symbol | hybrid (default: hybrid)
--output, -o human | json | github-actions | azure-devops (default: human)
--run Execute the test command after analysis
--unstaged Analyse working-tree changes instead of a git diff
-- Everything after this is forwarded to the test runner
Output formats
# Human-readable (default)
opentia --base HEAD~1 --root .
# JSON — pipe into scripts or CI steps
opentia --base HEAD~1 --root . --output json
# GitHub Actions
opentia --base HEAD~1 --root . --output github-actions
# Azure DevOps
opentia --base HEAD~1 --root . --output azure-devops
JSON output fields
{
"run_all": false, // true = targeted selection was abandoned
"language": "dotnet", // dotnet | java | node
"test_filter": "FullyQualifiedName~PricingServiceTests",
"test_project_paths": ["...SampleApp.Services.Tests.csproj"],
"affected_test_projects": ["SampleApp.Services.Tests"],
"affected_test_classes": ["PricingServiceTests"],
"test_command": "dotnet test \"...\" --filter \"...\"",
"reason": "Analysis complete",
"strategy_notes": [] // warnings / fallback explanations
}
Node.js projects
opentia detects Jest and Vitest automatically. For npm workspaces, each sub-package is analysed independently and the dependency graph is resolved across workspace:* references — changing a shared package triggers tests in every package that depends on it.
The test command is always a single npx jest (or npx vitest run) invocation run from the workspace root with a --testPathPattern filter.
Mixed-language monorepos
Each opentia run uses one adapter — .NET, Java, or Node — based on what it finds under --root. Point --root at each language root separately:
opentia --base HEAD~1 --root ./backend # Java or .NET tests
opentia --base HEAD~1 --root ./frontend # Node.js tests
In CI, run both steps. Each one exits cleanly with "no tests to run" when its language has no changes — nothing is wasted.
CI integration
GitHub Actions — pull request
on:
pull_request:
branches: [main, staging]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Test Impact Analysis
id: tia
run: opentia --base ${{ github.event.pull_request.base.sha }} --root . --output github-actions
- name: Run affected tests
if: steps.tia.outputs.has_tests == 'true'
run: ${{ steps.tia.outputs.test_command }}
Available outputs: test_filter, run_all, has_tests, test_project_paths, test_command.
GitHub Actions — push to branch
- name: Test Impact Analysis
id: tia
run: opentia --base ${{ github.event.before }} --root . --output github-actions
- name: Run affected tests
if: steps.tia.outputs.has_tests == 'true'
run: ${{ steps.tia.outputs.test_command }}
Azure DevOps
- script: opentia --base $(System.PullRequest.TargetBranchName) --root . --output azure-devops
displayName: Test Impact Analysis
- script: $(testCommand)
condition: eq(variables['hasTests'], 'true')
displayName: Run affected tests
Available variables: testFilter, runAllTests, hasTests, testProjectPaths, testCommand.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file opentia-1.0.5.tar.gz.
File metadata
- Download URL: opentia-1.0.5.tar.gz
- Upload date:
- Size: 23.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ccd732cbedc977f6c45103f6a0cc81fe95535520b5b5c24abc58317ff464f074
|
|
| MD5 |
dbcfdd234c988f59d5a7a2a1bf785514
|
|
| BLAKE2b-256 |
527e65da72c24f058f27d8acb644675a655aa73dc1721eab96c41cc459a75f11
|
File details
Details for the file opentia-1.0.5-py3-none-any.whl.
File metadata
- Download URL: opentia-1.0.5-py3-none-any.whl
- Upload date:
- Size: 22.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea6bbc22af3b4e73a27f3eaa942887ca5277da0f5816f7691766ab73c93c21cd
|
|
| MD5 |
fb6d9b3a370982b7e2d7d378288b6e00
|
|
| BLAKE2b-256 |
6202ac9f3536bc334aa3a859af9a7598a45460f138bba23a0a0217eace354f67
|