{"id":40327864,"url":"https://github.com/oeditus/muex","last_synced_at":"2026-06-27T19:01:16.977Z","repository":{"id":331616554,"uuid":"1131605362","full_name":"Oeditus/muex","owner":"Oeditus","description":"Mutation testing library for Elixir, Erlang, and other languages.","archived":false,"fork":false,"pushed_at":"2026-06-27T16:52:37.000Z","size":8042,"stargazers_count":17,"open_issues_count":1,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-06-27T17:19:57.855Z","etag":null,"topics":["elixir","mutation-analysis","mutation-testing","testing-library","testing-tools"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Oeditus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-10T10:49:34.000Z","updated_at":"2026-06-27T16:52:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Oeditus/muex","commit_stats":null,"previous_names":["am-kantox/muex","oeditus/muex"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/Oeditus/muex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oeditus%2Fmuex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oeditus%2Fmuex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oeditus%2Fmuex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oeditus%2Fmuex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Oeditus","download_url":"https://codeload.github.com/Oeditus/muex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Oeditus%2Fmuex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34864431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-27T02:00:06.362Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","mutation-analysis","mutation-testing","testing-library","testing-tools"],"created_at":"2026-01-20T08:00:24.209Z","updated_at":"2026-06-27T19:01:16.970Z","avatar_url":"https://github.com/Oeditus.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Muex\n\nMutation testing library for Elixir, Erlang, and other languages.\n\nMuex evaluates test suite quality by introducing deliberate bugs (mutations) into code and verifying that tests catch them. It provides a language-agnostic architecture with dependency injection, making it easy to extend support to new languages.\n\n## Features\n\n- Language-agnostic architecture with pluggable language adapters\n- Built-in support for Elixir and Erlang\n- Intelligent file filtering to focus on business logic:\n  - Analyzes code complexity and characteristics\n  - Automatically excludes framework code (behaviours, protocols, supervisors)\n  - Skips low-complexity files (Mix tasks, reporters, configurations)\n  - Prioritizes files with testable logic (conditionals, arithmetic, pattern matching)\n- 6 mutation strategies:\n  - Arithmetic operators (+/-, *//)\n  - Comparison operators (==, !=, \u003e, \u003c, \u003e=, \u003c=)\n  - Boolean logic (and/or, \u0026\u0026/||, true/false, not)\n  - Literal values (numbers, strings, lists, atoms)\n  - Function calls (remove calls, swap arguments)\n  - Conditionals (if/unless mutations)\n- Parallel mutation execution with configurable concurrency\n- Sophisticated mutation optimization heuristics (50-70% reduction)\n- Colored terminal output with mutation scores and detailed reports\n- Integration with ExUnit\n- Hot module swapping for efficient testing\n\n## Installation\n\nMuex can be used in three ways:\n\n### 1. As a Mix Dependency (Recommended for CI/CD)\n\nAdd `muex` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:muex, \"~\u003e 0.2.0\", only: [:dev, :test], runtime: false}\n  ]\nend\n```\n\nThen run:\n\n```bash\nmix deps.get\nmix muex\n```\n\n### 2. As a Hex Archive (Recommended for Global Use)\n\nInstall globally to use across all your projects:\n\n```bash\nmix archive.install hex muex\n```\n\nThis makes `mix muex` available in any Elixir project without adding it as a dependency.\n\n### 3. As an Escript (Standalone Binary)\n\nFor standalone usage or distribution:\n\n```bash\n# From muex repository\nmix escript.build\n\n# Install system-wide\nsudo cp muex /usr/local/bin/\n\n# Use in any project\ncd /path/to/your/project\nmuex\n```\n\nFor detailed installation instructions and comparison, see [docs/INSTALLATION.md](docs/INSTALLATION.md).\n\n## Usage\n\nRun mutation testing on your project:\n\n```bash\n# Using mix task (dependency or hex archive)\nmix muex\n\n# Using escript (standalone binary)\nmuex\n```\n\nBoth commands accept the same options and produce identical results.\n\nBy default, Muex intelligently filters files to focus on business logic and skip framework code. This dramatically reduces the number of mutations tested.\n\n### File Filtering Options\n\n```bash\n# Use intelligent filtering (default)\nmix muex\n\n# Show which files are included/excluded\nmix muex --verbose\n\n# Adjust minimum complexity score (default: 20)\nmix muex --min-score 30\n\n# Disable filtering to test all files\nmix muex --no-filter\n\n# Limit total mutations tested\nmix muex --max-mutations 500\n```\n\n### File Selection\n\n```bash\n# Run on specific directory\nmix muex --files \"lib/myapp\"\n\n# Run on specific file\nmix muex --files \"lib/my_module.ex\"\n\n# Run on files matching glob pattern (single level)\nmix muex --files \"lib/muex/*.ex\"\n\n# Run on files matching recursive glob pattern\nmix muex --files \"lib/**/compiler*.ex\"\nmix muex --files \"lib/{muex,mix}/**/*.ex\"\n```\n\n### Other Options\n\n```bash\n# Use specific mutators\nmix muex --mutators arithmetic,comparison,boolean\n\n# Set concurrency and timeout\nmix muex --concurrency 4 --timeout 10000\n\n# Fail if mutation score below threshold\nmix muex --fail-at 80\n\n# Enable mutation optimization (balanced preset)\nmix muex --optimize\n\n# Use conservative optimization (best balance)\nmix muex --optimize --optimize-level conservative\n\n# Use aggressive optimization (fastest)\nmix muex --optimize --optimize-level aggressive\n\n# Custom optimization settings\nmix muex --optimize --min-complexity 3 --max-per-function 15\n\n# Reduce invalid/noisy mutations on framework-heavy projects\nmix muex --preset phoenix   # also: ecto, ash\n\n# Only mutate lines changed since a branch/ref (pull-request scoping)\nmix muex --since main\n\n# Run only the tests that cover each mutated line\nmix muex --coverage-guided\n\n# Disable Trivial Compiler Equivalence (equivalent-mutant skipping)\nmix muex --no-tce\n```\n\n## Mutation Optimization\n\nMuex includes sophisticated heuristics to reduce the number of mutants tested while maintaining mutation testing effectiveness. This can reduce testing time by 50-70% with minimal impact on mutation score.\n\n### When to Use Optimization\n\n- **CI/CD pipelines**: Use conservative mode for fast feedback with \u003c1% score impact\n- **Development iteration**: Use balanced mode for rapid checks\n- **Pre-release validation**: Disable optimization for complete coverage\n\n### Optimization Levels\n\n**Conservative** (recommended for CI/CD):\n- 50-65% reduction in mutations\n- \u003c1% impact on mutation score\n- Focuses on high-complexity code\n- Preserves boundary condition mutations\n\n```bash\nmix muex --optimize --optimize-level conservative\n```\n\n**Balanced** (default, good for development):\n- 70-85% reduction in mutations\n- 5-10% impact on mutation score\n- Fast feedback during development\n- Focuses on highest-impact mutations\n\n```bash\nmix muex --optimize\n```\n\n**Aggressive** (rapid checks only):\n- 85-95% reduction in mutations\n- 10-15% impact on mutation score\n- Very fast but may miss edge cases\n\n```bash\nmix muex --optimize --optimize-level aggressive\n```\n\n### How It Works\n\nThe optimizer uses 7 strategies:\n\n1. **Equivalent Mutant Detection**: Filters semantically equivalent mutations\n2. **Code Complexity Scoring**: Skips mutations in trivial code (getters, simple guards)\n3. **Impact Scoring**: Prioritizes mutations by risk level (1-11 points)\n4. **Mutation Clustering**: Groups similar mutations and samples representatives\n5. **Per-Function Limits**: Caps mutations per function to prevent explosion\n6. **Boundary Prioritization**: Always preserves critical comparison mutations\n7. **Pattern-Based Filtering**: Removes known low-value mutations\n\nFor detailed information, see [docs/MUTATION_OPTIMIZATION.md](docs/MUTATION_OPTIMIZATION.md).\n\n### Example: Cart Project\n\nReal-world results from the shopping cart example (440 LOC, 84 tests):\n\n| Mode | Mutations | Time | Score | Best For |\n|------|-----------|------|-------|----------|\n| Baseline | 886 | ~3 min | 99.77% | Final validation |\n| Conservative | 308 | ~1 min | 99.35% | CI/CD |\n| Balanced | 28 | ~10 sec | 89.29% | Development |\n\nSee `examples/cart/OPTIMIZATION_RESULTS.md` for complete analysis.\n\n## Equivalent Mutants, Coverage, and Incremental Runs\n\nIn addition to the (lossy) optimizer above, Muex applies sound, always-on\nhandling that never hides a killable mutant:\n\n- **Equivalent-mutant detection**: AST identity rules (`a + 0` vs `a - 0`,\n  `a * 1` vs `a / 1`, bitshift-by-zero) drop mutations that cannot change\n  behaviour. They are reported as `Equivalent` and excluded from the score.\n- **Trivial Compiler Equivalence (TCE)**: mutants that compile to byte-identical\n  BEAM (for example, deleting a `@moduledoc`) are skipped. Disable with\n  `--no-tce`.\n- **Coverage-guided execution** (`--coverage-guided`): runs only the tests that\n  execute the mutated line; a line that no test covers is reported as\n  `No coverage` and skipped instead of wasting a full test run.\n- **Incremental `--since \u003cref\u003e`**: scopes mutation testing to the lines changed\n  since a git ref (`git diff \u003cref\u003e...HEAD`), which is ideal for pull-request CI:\n\n```bash\nmix muex --since main\n```\n\n## Compile-Time Configuration\n\nCustom language adapters and mutators can be registered in your `config/config.exs` so they are available via the CLI flags:\n\n```elixir\n# config/config.exs\nimport Config\n\n# Register a custom language adapter (usable with --language lua)\nconfig :muex, languages: %{\"lua\" =\u003e MyApp.Language.Lua}\n\n# Register custom mutators (usable with --mutators string,regex)\nconfig :muex, mutators: %{\n  \"string\" =\u003e MyApp.Mutator.String,\n  \"regex\"  =\u003e MyApp.Mutator.Regex\n}\n```\n\nLanguage adapter modules must implement the `Muex.Language` behaviour and mutator modules must implement the `Muex.Mutator` behaviour. Custom entries are merged with the built-in ones at compile time; entries with the same key override the built-in default.\n\n## Available Mutators\n\nMuex provides 18 mutation strategies. Core operators work across BEAM languages;\nElixir-specific operators target Elixir AST constructs.\n\nCore:\n\n- **Arithmetic**: Mutates `+`, `-`, `*`, `/` operators (swap, remove, identity)\n- **Comparison**: Mutates `==`, `!=`, `\u003e`, `\u003c`, `\u003e=`, `\u003c=`, `===`, `!==` operators\n- **Boolean**: Mutates `and`, `or`, `\u0026\u0026`, `||`, `true`, `false`, `not` (swap, negate, remove)\n- **Literal**: Mutates numbers (±1), strings (empty/append), lists (empty), atoms (change)\n- **FunctionCall**: Removes function calls and swaps first two arguments\n- **Conditional**: Inverts conditions, removes branches, converts `unless` to `if`\n- **ReturnValue**: Replaces a function or block return value\n- **StatementDeletion**: Deletes individual statements from blocks\n\nElixir-specific:\n\n- **Pipe**: Drops a stage from a pipe chain (`x |\u003e f` becomes `x`)\n- **Guard**: Removes a `when` guard by replacing it with `true`\n- **CaseClause** / **CondClause** / **WithClause**: Delete a clause from `case` / `cond` / `with`\n- **MapSemantics**: Mutates map operations\n- **EnumSemantics**: Mutates `Enum` operations\n- **ExtendedMath**: Mutates `rem`, `div`, and bitwise operators\n- **InvertNegatives**: Drops unary negation (`-x` becomes `x`)\n- **NegateConditionals**: Swaps relational operators for their complements\n\n## Supported Languages\n\n- **Elixir**: Full support with ExUnit integration\n- **Erlang**: Full support with native BEAM integration\n\nBoth languages benefit from hot module swapping for efficient mutation testing.\n\n## Example Output\n\n```\nLoading files from lib...\nFound 24 file(s)\nAnalyzing files for mutation testing suitability...\nSelected 8 file(s) for mutation testing\nSkipped 16 file(s) (low complexity or framework code)\nGenerating mutations...\nTesting 342 mutation(s)\nAnalyzing test dependencies...\nRunning tests...\n\nMutation Testing Results\n==================================================\nTotal mutants: 342\nKilled: 287 (caught by tests)\nSurvived: 55 (not caught by tests)\nInvalid: 0 (compilation errors)\nTimeout: 0\n==================================================\nMutation Score: 83.9%\n```\n\nWith `--verbose` flag:\n```\nLoading files from lib...\nFound 24 file(s)\nAnalyzing files for mutation testing suitability...\n  ✗ lib/mix/tasks/muex.ex (Mix task)\n  ✗ lib/muex/application.ex (Application/Supervisor)\n  ✓ lib/muex/compiler.ex (score: 91)\n  ✓ lib/muex/runner.ex (score: 83)\n  ✗ lib/muex/language.ex (Behaviour definition)\n  ...\n```\n\n## Output Formats\n\n### Terminal (Default)\nColored terminal output with progress indicators and summary:\n- Green for killed mutations (tests caught the bug)\n- Red for survived mutations (tests missed the bug)\n- Yellow for invalid mutations (compilation errors)\n- Magenta for timeouts\n- Color-coded mutation score (green ≥80%, yellow ≥60%, red \u003c60%)\n\n```\nMutation Testing Results\n==================================================\nTotal mutants: 25\nKilled: 20 (caught by tests)\nSurvived: 5 (not caught by tests)\nInvalid: 0 (compilation errors)\nTimeout: 0\n==================================================\nMutation Score: 80.0%\n```\n\n### JSON Format\nStructured JSON for CI/CD integration:\n```bash\nmix muex --format json\n# Outputs: muex-report.json\n```\n\n### HTML Format\nInteractive HTML report with color-coded results:\n```bash\nmix muex --format html\n# Outputs: muex-report.html\n```\n\n## Examples\n\nSee the `examples/` directory for example projects:\n- **`examples/cart/`** - Real-world e-commerce shopping cart (recommended)\n  - 440 LOC with complex business logic\n  - 84 comprehensive tests\n  - 99.77% baseline mutation score\n  - Demonstrates optimization heuristics\n  - See [examples/cart/README.md](examples/cart/README.md)\n- `examples/shop/` - Simpler shopping cart example (48 tests)\n- `examples/calculator.erl` - Basic Erlang example\n\n**Note**: The examples demonstrate the mutation testing concept. For production use, consider integrating Muex into your project's mix.exs as a dependency.\n\n## Documentation\n\nDocumentation can be found at \u003chttps://hexdocs.pm/muex\u003e.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foeditus%2Fmuex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foeditus%2Fmuex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foeditus%2Fmuex/lists"}