Behavioral equivalence testing
Prove the new service does what the old code did.
PYD ENTERPRISES generates boundary-condition fixtures from real legacy execution branches, with expected values computed using the legacy arithmetic. Run them against your new services and every regression names its source line.
Decisions
312
Paths
2,061
Fixtures
1,244
- Threshold boundaries58%
- Rounding and truncation17%
- PIC capacity and size error9%
- Invalid codes and ELSE paths11%
- Plain equivalence classes5%
Boundary test runner
Three builds. Ten fixtures. One cent apart.
Pick a build of the replacement loan service and run the fixtures PYD ENTERPRISES generated from the legacy accrual and fee programs. Float arithmetic and banker's rounding both fail on exact half-cent results that COBOL ROUNDED handles half-up.
| Fixture | Rule | Input | Legacy expects | Target returned | Result |
|---|---|---|---|---|---|
| ACCR-001plain accrual | LNACCR-0412 | principal 250000.00, rate 0.062500 | 43.40 | · | queued |
| ACCR-002exact .xx5 (0.225) | LNACCR-0412 | principal 1800.00, rate 0.045000 | 0.23 | · | queued |
| ACCR-003exact .xx5 (0.455) | LNACCR-0412 | principal 2184.00, rate 0.075000 | 0.46 | · | queued |
| ACCR-004exact .xx5 (0.525) | LNACCR-0412 | principal 5400.00, rate 0.035000 | 0.53 | · | queued |
| ACCR-005exact .xx5 (1.545) | LNACCR-0412 | principal 6180.00, rate 0.090000 | 1.55 | · | queued |
| FEE-001balance boundary, below | DDAFEE R2 | tier B, avgBal 1499.99, age 40 | 12.00 | · | queued |
| FEE-002balance boundary, at | DDAFEE R3 | tier B, avgBal 1500.00, age 40 | 0.00 | · | queued |
| FEE-003both conditions true | DDAFEE R4 | tier P, avgBal 4999.99, deposits 0 | 18.00 | · | queued |
| FEE-004age boundary, at | DDAFEE R1 | tier R, avgBal 100.00, age 65 | 0.00 | · | queued |
| FEE-005ELSE: unknown tier code | DDAFEE R6 | tier Z, avgBal 100.00, age 40 | 30.00 | · | queued |
- Pass
- 0
- Fail
- 0
- Accepted
- 0
Binary floating point: 0.455 is stored as 0.45499999999999996 and rounds down. Two accrual fixtures differ by one cent.
How fixtures are derived
From branches, not from guesses.
- 1
Enumerate paths per decision
From the control-flow graph of each extracted rule, PYD ENTERPRISES lists the feasible paths, including fall-through and PERFORM THRU ranges, and the condition that selects each one.
- 2
Solve for boundaries
Each path condition is solved for values at, just below and just above every threshold: 1499.99 and 1500.00, age 64 and 65, the largest value a PIC clause can hold, and exact half-cent results that expose rounding.
- 3
Evaluate with legacy semantics
Expected outputs are computed with the legacy program's arithmetic: packed decimal precision, ROUNDED or truncation, ON SIZE ERROR behavior and intermediate result rules, not with the test author's assumptions.
- 4
Emit fixtures with provenance
Every fixture records its rule, source lines, path and the semantics that produced the expected value, so a failure points straight at the line of COBOL that disagrees with the new code.
1{2 "id": "ACCR-003",3 "rule": "LNACCR-0412",4 "source": "LNACCR02.cbl:1187-1204",5 "path": ["2200-ACCRUE", "COMPUTE ROUNDED"],6 "kind": "rounding-boundary",7 "input": { "principalBalance": "2184.00", "annualRate": "0.075000" },8 "expect": { "dailyAccrual": "0.46" },9 "semantics": {10 "exact": "0.455",11 "rounding": "half-up to 2 decimals (COBOL ROUNDED)",12 "targetPic": "S9(7)V99 COMP-3"13 }14}
Fixtures also export as Postman collections and verify DMN exports in Drools.
“1,200 edge-case equivalence tests showed exactly where our new Go services disagreed with the mainframe, down to the cent.”
Honest scope
What the suite covers, and what it does not.
Equivalence suites test behavior on the paths PYD ENTERPRISES extracted. Anything outside them is listed, so your test plan can cover it another way.
- Every branch of every extracted decisioncovered
- Numeric boundaries and PIC capacity limitscovered
- Rounding, truncation and ON SIZE ERROR outcomescovered
- Invalid and unexpected codes the ELSE branch acceptscovered
- Response codes mapped to HTTP statusescovered
- Performance, throughput and batch window timingout of scope
- Concurrency and locking behaviorout of scope
- Behavior inside unresolved external calls (flagged instead)out of scope
FAQ
Test generation questions.
Where do the expected values come from?
From the legacy code paths themselves. PYD ENTERPRISES evaluates each fixture's inputs along the extracted path with the program's own arithmetic rules (packed decimal precision, ROUNDED versus truncation, size error handling), so the expected value is what the legacy system computes, not what a specification author believes it computes.
Do we need to run the mainframe to generate fixtures?
No. Fixtures are generated statically from the analysis. Many teams also replay a sample of fixtures on the legacy system in a test region as an extra check, and PYD ENTERPRISES can export them in a record layout for that purpose.
What format are the fixtures in?
JSON files with inputs, expected outputs and provenance, one file per decision or interface. They can also be exported as Postman 2.1 collections, and the documentation includes harness examples for JUnit, Go and pytest that read the JSON directly.
What if the new system is meant to behave differently?
Then the fixture should fail, and someone should decide. Mark the difference as an accepted change with a reason, and PYD ENTERPRISES records it so the deviation is deliberate and auditable rather than accidental.
Does a passing suite prove the systems are equivalent?
It shows the new service matches the legacy behavior on every extracted branch and boundary the suite covers. It does not cover performance, concurrency, or logic inside components that could not be analyzed, which PYD ENTERPRISES lists explicitly so your test plan can address them.
Catch the one-cent regressions before cutover.
Run PYD ENTERPRISES on 100,000 lines of COBOL or Java in your private VPC and review OpenAPI specs and DMN tables tomorrow.