変異体 (へんいたい, hen’itai) Pronunciation: he-n-i-ta-i (4 morae; no stress accent) Meaning: mutant, mutated organism, or variant entity
A Ruby mutation testing framework
- This is alpha software, there will be bugs
- Henitai tests itself and other projects
- It might break with a release
- If you need a mature solution for mutation testing in ruby, take a look at the [https://github.com/mbj/mutant](Mutant gem)
Mutation testing answers the question that code coverage cannot: does your test suite actually verify the behaviour of your code?
A mutation testing tool makes small, systematic changes — mutants — to your source code (e.g. replacing > with >=, removing a return statement, flipping a boolean) and then runs your tests. A mutant that causes at least one test to fail is killed. A mutant that passes all tests is survived — evidence that your tests are not covering that behaviour.
The ratio of killed mutants to total mutants is the Mutation Score (MS). A high mutation score is a strong quality signal.
As mutation testing modifies your code you make sure that your tests cannot have any unintended side-effects.
Add to your Gemfile:
gem "henitai", group: :developmentOr install globally:
gem install henitaiRequires Ruby 4.0.2+
# Run mutation testing on the entire project
bundle exec henitai run
# Run only on subjects changed since main (CI-friendly)
bundle exec henitai run --since origin/main
# Run on a specific subject pattern
bundle exec henitai run 'MyClass#my_method'
bundle exec henitai run 'MyNamespace*'Configuration lives in .henitai.yml:
# yaml-language-server: $schema=./assets/schema/henitai.schema.json
integration:
name: rspec
includes:
- lib
mutation:
operators: light # light | full
timeout: 10.0
max_flaky_retries: 3
sampling:
ratio: 0.05
strategy: stratified
reports_dir: reports
thresholds:
high: 80
low: 60Henitai warns on unknown config keys and aborts with Henitai::ConfigurationError
when a value is invalid.
CLI flags override the corresponding values from .henitai.yml.
Before mutation testing starts, Henitai checks whether the current coverage data
covers the configured source files. If not, Henitai runs the configured test
suite once to bootstrap a usable coverage baseline. If coverage is still
unavailable for the current sources, henitai run aborts with
Henitai::CoverageError.
Surviving mutants are retried up to mutation.max_flaky_retries times before
they are classified as survivors. The default retry budget is 3.
Per-test coverage reporting is currently wired through the RSpec child runner. Minitest integration reuses the same selection and execution flow, but does not yet enable the per-test coverage formatter.
Henitai currently defaults to linear mutant execution. Set jobs in
.henitai.yml or pass --jobs N to opt into parallel mutant execution.
By default, Henitai keeps child test output out of the live terminal. Each
baseline or mutant run writes captured stdout/stderr to reports/mutation-logs/
and the terminal only shows progress plus a concise summary. Pass
--all-logs (or --verbose) to print every captured child log.
henitai version prints the installed version. henitai run exits with 0
when the mutation score meets the low threshold, 1 when it does not, and 2
for framework errors.
The repository ships a JSON Schema at assets/schema/henitai.schema.json for editor autocompletion.
Light (default) — high-signal, low-noise operators covering the majority of real-world defects:
ArithmeticOperator—+↔-,*↔/EqualityOperator—==↔!=,>↔<, etc.LogicalOperator—&&↔||BooleanLiteral—true↔false,!exprConditionalExpression— remove branch bodiesStringLiteral— empty string replacementReturnValue— mutate return expressions
Full — adds lower-signal operators:
ArrayDeclaration,HashLiteral,RangeLiteralSafeNavigation—&.→.PatternMatch— case/in arm removalBlockStatement— remove blocksMethodExpression— remove callsAssignmentExpression— mutate compound assignment
# .henitai.yml
reporters:
- terminal
- html
- json
- dashboard
dashboard:
project: "github.com/your-org/your-repo"
base_url: "https://dashboard.stryker-mutator.io"Set STRYKER_DASHBOARD_API_KEY in your CI environment to publish reports.
JSON reports are written to reports/mutation-report.json by default. Set
reports_dir to change the output directory.
git clone https://github.com/martinotten/henitai
cd henitai
bundle install
bundle exec rspec # run tests
bundle exec rake smoke:integration:all # run rspec/minitest integration smoke projects
bundle exec rubocop # lint
bundle exec henitai clean # remove stale generated report artifacts
bundle exec henitai run # dogfoodFramework integration smoke projects live under spec/fixtures/integration_smoke/
and exercise henitai against small RSpec and Minitest apps via the local path
dependency.
Git hook support is tracked in .githooks/pre-commit.
Enable it with git config core.hooksPath .githooks so commits run RuboCop,
RSpec, and the integration smoke suite before they are created.
A Dev Container configuration is included (.devcontainer/) for VS Code with the official ruby:4
image, the Codex CLI, and RTK preinstalled. Codex support is bootstrapped with
rtk init -g --codex --auto-patch during container creation.
See docs/architecture/architecture.md for the full design document, including:
- Phase-Gate pipeline (5 gates)
- AST-based operator implementation
- Fork isolation model
- Stryker JSON schema integration
- Architecture decisions in
docs/architecture/adr/ - Three-phase roadmap
MIT License — © 2026 Martin Otten