UnitAutogen

0.16.8

PowerShell module for UnitAutogen - auto-generated tSQLt unit tests with real branch coverage for SQL Server. Installs the framework AND the in-database (SQLCLR) predicate parser, runs generation and coverage, and exports Cobertura XML, JUnit XML, and HTML reports for Azure DevOps, GitHub Actions, Jenkins, GitLab CI, and SonarQube. The single C# predicate parser runs
PowerShell module for UnitAutogen - auto-generated tSQLt unit tests with real branch coverage for SQL Server. Installs the framework AND the in-database (SQLCLR) predicate parser, runs generation and coverage, and exports Cobertura XML, JUnit XML, and HTML reports for Azure DevOps, GitHub Actions, Jenkins, GitLab CI, and SonarQube. The single C# predicate parser runs inside SQL Server (no PowerShell-side parser); installation registers it and requires sysadmin once plus 'clr enabled'=1.
Show more

Minimum PowerShell version

5.1

Installation Options

Copy and Paste the following command to install this package using PowerShellGet More Info

Install-Module -Name UnitAutogen

Copy and Paste the following command to install this package using Microsoft.PowerShell.PSResourceGet More Info

Install-PSResource -Name UnitAutogen

You can deploy this package directly to Azure Automation. Note that deploying packages with dependencies will deploy all the dependencies to Azure Automation. Learn More

Manually download the .nupkg file to your system's default download location. Note that the file won't be unpacked, and won't include any dependencies. Learn More

Owners

Copyright

(C) 2026 Munaf Ibrahim Khatri. Licensed under AGPL-3.0.

Package Details

Author(s)

  • Munaf Ibrahim Khatri

Tags

SQL SQLServer tSQLt Coverage CI-CD Cobertura JUnit AzureDevOps Testing UnitTest CodeCoverage BranchCoverage DatabaseTesting AutomatedTesting

Functions

Install-UnitAutogenDatabase Invoke-UnitAutogen Export-CoverageCoberturaXml Export-TestResultsJunitXml Export-CoverageHtmlReport Export-UnitAutogenTests

Dependencies

This module has no dependencies.

Release Notes

## v0.16.8 (beta) - 2026-06-18

- **Parenthesised sub-expressions in per-row arithmetic gates are now seeded.** A branch whose value
 groups an additive sub-expression in parentheses - e.g. `value = (qty + fee) * rate` or
 `value = qty * (price - fee)` - was previously left NOT_TESTABLE. A lightweight paren-depth tracker now
 splits the expression into top-level factors and neutralises each non-driving column correctly (0 for an
 additive sibling, 1 for a multiplicative one), so both arms are covered. Pure-product parens and
 paren-free expressions are unchanged.
- Fail-safe by design: a top-level sum mixing paren groups, nested parens, a constant inside a paren, or any
 unresolved column still falls back to an honest NOT_TESTABLE - never a wrong witness.
- Validated on a synthetic per-row procedure (correct co-factors; coverage identical to the non-paren
 equivalent) with full PredicateZoo + reference-DB regression unchanged. Pure T-SQL; no CLR change.

## v0.16.7 (beta) - 2026-06-18

- **Nondeterministic-gate guard (no more runaway searches).** A branch whose operand is built from a
 runtime value the seeder cannot control - a clock (SYSDATETIME / GETDATE / CURRENT_TIMESTAMP / ...),
 NEWID, or RAND - is now detected up front and reported as an honest NOT_TESTABLE, instead of the
 search-seeding sweep grinding (in one pathological loop-accumulator fixture, 37+ minutes of CPU)
 before giving up. The detector scans the operand's own assignment lineage; @@ROWCOUNT-style globals
 are deliberately NOT treated as nondeterministic (they reflect seedable row state).
- **Search backstops.** A per-gate wall-clock budget (default 90s) abandons any non-converging search,
 and the loop-count row-count knob is capped at @MaxSeedRows (default 500) so a large comparand can't
 request 100k+ seeded rows per probe. Raise @MaxSeedRows to test a gate that genuinely needs more.
- Pure T-SQL; no CLR change. Validated on AdventureWorks2025 (the fixture now resolves in ~10s; pz
 loop/count/aggregate/scalar/OR gates unchanged) and HighValueCustomer (AssessCustomer 6/6, Reconcile
 15/16 with all witnesses intact) - all 0 fail / 0 err.

## v0.16.6 (beta) - 2026-06-17

- **IN / BETWEEN in a WHERE are now seeded** (in-database parser enhancement). A branch gated on
 EXISTS/COUNT over "... WHERE col IN (v1, v2, ...)" was previously NOT_TESTABLE; the parser now
 expands it to an OR of equalities, so coverage generates one TRUE test PER value (each seeding a row
 matching only that value). "col BETWEEN a AND b" expands to col >= a AND col <= b and is seeded.
 Requires the updated in-database CLR parser (re-run installer step 2).
- Validated on AdventureWorks2025 (IN gate -> per-value tests with distinct seeds; BETWEEN seeded);
 PredicateZoo regression unchanged.

## v0.16.5 (beta) - 2026-06-17

- **OR per-arm coverage.** A branch gated on a multi-condition OR over a table (e.g.
 EXISTS(... WHERE a = 1 OR b = 2 OR c = 3)) now generates one TRUE test PER disjunct - each seeding a
 row that satisfies only that arm - instead of a single TRUE test for the first arm, so every OR arm
 is exercised independently. (Branch coverage is unchanged; this adds condition-level thoroughness.)
- A column IN (...) / BETWEEN in a WHERE, and COUNT(col) NULL semantics, remain dependent on a future
 in-database parser enhancement.
- Validated on AdventureWorks2025 (synthetic OR gate: per-arm seeds verified distinct); PredicateZoo
 regression unchanged. No C#/CLR change.

## v0.16.4 (beta) - 2026-06-17

- **Temp-table tracing.** A branch gated on a #temp populated by SELECT ... INTO #t FROM <base>
 (e.g. a loop bounded by the temp's row count) is now covered: the seeder traces the #temp back to
 its base table and seeds that, since the procedure itself fills the #temp at run time. These gates
 were previously skipped ("target table not found").
- **Parenthesised derived locals - correctness guard.** A per-row arithmetic gate whose value groups
 an additive sub-expression in parentheses (e.g. value = qty * (price - fee)) is now left as an
 honest NOT_TESTABLE instead of being mis-flattened into a wrong witness. (Full distribution is
 future work; pure-product parens and paren-free expressions are unaffected.)
- Validated on AdventureWorks2025 synthetics; PredicateZoo regression unchanged. No C#/CLR change.

## v0.16.2 (beta) - 2026-06-17

Seeder-robustness batch (1 of 2 from an external code review). The deeper test-generator
and parser items follow in v0.16.3.

- A new per-run **@MaxSeedRows** parameter on GenerateAndRunCoverage / GenerateAndCoverDatabase
 makes the seed-row cap tunable (was hardcoded 500); a COUNT(*) gate needing more rows can now
 be covered by raising it. Default 500 - existing behaviour unchanged.
- **Date and string range predicates are now seeded.** A comparand using >, >=, <, <= on a
 date/datetime or string (reporting windows, alphabetical filters) was previously a silent skip;
 the seeder now produces a satisfying value (DATEADD past a date bound; a collation-safe boundary
 for strings). The aggregate-filter seeder reuses the same logic, so "... WHERE d <= '<date>'"
 no longer excludes the seeded row.
- A branch gated on a **single-column contradiction** (e.g. x > y AND x < y) is now reported as
 PROVABLY UNREACHABLE (dead code) instead of a generic skip, via a new constraint classifier.
- Validated on AdventureWorks2025 (configurable-cap and dead-branch synthetics; PredicateZoo
 count/scalar/sum gates unchanged at 100%). No C#/CLR change.

## v0.16.1 (beta) - 2026-06-15

Two narrower derived-value and aggregate shapes are now seeded to full branch coverage.

- A derived local that uses SUBTRACTION (e.g. value = qty * price - fee, or qty * price
 - 100) is now covered. A subtracted column is neutralised to 0 like any other term; a
 subtracted (or added) numeric constant is folded into the knob so the driving term
 still crosses the threshold exactly.
- An aggregate gate whose source has a NON-equality filter is now satisfied: numeric
 >, >=, <, <= seed a value just inside the bound; IN (...) seeds the first list value;
 BETWEEN seeds the low bound. (Equality and date ">=" windows were already handled.)
- Validated on a synthetic loop procedure (100% line + branch); full regression on
 AdventureWorks2025 (PredicateZoo aggregate/scalar gates), a JSON/MERGE/transaction
 procedure, and a multi-procedure analytics DB all unchanged. No C#/CLR change.

## v0.16.0 (beta) - 2026-06-15

Two more derived-value and aggregate shapes are now seeded to full branch coverage.

- A derived local that MIXES multiplication and addition (e.g. value = qty * price +
 fee) is now covered. The generator splits the expression into additive terms, drives
 the term holding the chosen column and neutralises the rest, so the computed value
 crosses the threshold exactly. Pure-product and pure-sum cases are unchanged.
- An aggregate gate whose source has a NON-date filter (e.g. AVG(Score) FROM Metrics
 WHERE Status='ACTIVE') now seeds a row that PASSES the filter instead of a placeholder
 the filter excluded (which left the aggregate NULL and the branch uncovered). This also
 fixes compound gates that reuse such an aggregate to set a flag.
- Validated on a synthetic loop procedure (100% line + branch); full regression on
 AdventureWorks2025 (PredicateZoo aggregate/scalar gates), a JSON/MERGE/transaction
 procedure, and a multi-procedure analytics DB all unchanged. No C#/CLR change.

## Earlier releases

Full release history (v0.15.x back to v0.9.0) is in CHANGES.md and on the GitHub
Releases page: https://github.com/unitautogen/unitautogen-public-repo/releases

FileList

Version History

Version Downloads Last updated
0.16.8 (current version) 5 6/22/2026
0.16.7 5 6/18/2026
0.16.1 4 6/15/2026
0.14.1 6 6/13/2026
0.14.0 4 6/12/2026
0.13.0 5 6/11/2026
0.12.0 8 6/7/2026
0.11.1 5 6/7/2026
0.11.0 8 6/6/2026
0.10.0 10 6/5/2026
0.9.14 18 6/4/2026
0.9.12 6 6/4/2026
0.9.11 9 6/4/2026
0.9.10 10 6/4/2026
0.9.9 9 6/3/2026
0.9.2 4 6/1/2026
0.9.1 4 5/30/2026
0.9.0 6 5/29/2026
Show more