FormsRefresh

FormsRefresh: proof that a migrated Oracle Forms application behaves like the original

FormsRefresh is for consultancies that migrate Oracle Forms applications. It runs the original application, records exactly what it does, and checks the replacement against that record, screen by screen and row by row. Every number below links to its evidence on formsrefresh.carretera.se.

The problem

A Forms migration is accepted when the customer believes the new application does what the old one did. Conversion is becoming cheap; showing equivalence is not. It is usually shown with hand-written tests and user acceptance testing, and those tests are written from what people think the old system does.

The behaviour that breaks is the kind nobody writes down. When a sequence value is drawn. Which column a form inserts as NULL. When a trigger computes a total. Which alert follows a commit, and where the cursor goes after Tab. Database checks and API tests see the stored rows, and only for the inputs someone thought of. They do not see what the user saw, in which order, or what the form refused to save. On the sample rebuild shown here, an independent database and API evaluation passed most of its checks, and the first recorded scenario still found nine defects that the evaluation had not reported (evidence).

Setup

The runner connects to the original Forms application in the customer's own licensed environment: their Forms Services, their database, one test schema and a client host. FormsRefresh installs no Oracle software.

A small Java agent in the Forms client reads the client's component tree, in which Forms names every item BLOCK.ITEM. The runner finds each element by that name and sends real keystrokes and clicks to it, so input passes through format masks, KEY- triggers, enabled and disabled items, lists of values and alerts as a user's would. It never uses screen coordinates or image matching.

Scenarios

An LLM agent reads the Forms source (the XML export of each module and the PL/SQL) and writes scenarios: business-level steps that address items by name. It keeps writing them until every trigger, program unit and branch is exercised.

Each scenario starts from a restored database baseline. The runner records a golden record for it: after every step, every item on the canvas, the focus, the message line, open alerts and lists of values, and at the end the full database change set (rows inserted, updated and deleted, and every sequence value drawn). Values that depend on the clock or the run date are masked, so a golden record is the same in every run, on any day.

Coverage is measured, not guessed. Forms Runtime Diagnostics shows which triggers and program units fired, and DBMS_PLSQL_CODE_COVERAGE shows the database PL/SQL blocks that ran. Every trigger, unit and branch ends up covered, unreachable (a candidate for retirement before anyone converts it) or blocked with a stated reason.

Conversion

Conversion is done by ordinary coding agents or by the consultancy's own team, on whatever target stack the customer chooses. FormsRefresh is not a converter and produces no target code.

Validation

The same scenarios replay against the new application through an adapter for its stack: the web adapter used here drives the browser and reads the PostgreSQL database. Every recorded value is classified:

A repair agent fixes the defects from the diff and the golden records alone, without the Forms source, and the scenarios run again. Source behaviour that the customer chooses not to keep, such as a debugging message left in a trigger, becomes an explicit waiver with its reason. Each waiver is pinned to the values it covers and is listed in every diff with the number of values it applied to, so nothing is waived silently.

Value

Measured on two public Forms applications, a retail order system (6 modules) and an HR application (3 modules):

Measure Retail HR
Coverage of Forms triggers and program units 60 of 60 24 of 24
Decision branches classified 18: 14 covered, 2 unreachable, 2 blocked 32: 24 covered, 4 unreachable, 4 blocked
Scenarios, each repeating byte for byte in three runs 17 17
Defects found in the first conversion 403 values; 1 of 17 scenarios at parity 73 values in 13 of 17 scenarios
Repair rounds to parity on all 17 scenarios 1 (19 min of agent repair, 4 files changed) 1 (about 4 min, 58 lines changed)
Waivers proposed for the customer's decision 10 2

Onboarding a new application: the HR application took 2 h 39 min of one agent from receiving the source to a passing coverage report, with a full recording loop of 169 seconds per scenario on average. Converting it to .NET took one coding agent about 20 minutes.

Both migrated applications run on this site with the original Forms source linked next to them: retail and HR.

Going forward

What a consultancy gets. For every migrated screen: the scenarios, the golden records, a coverage line and a classified diff the customer can check. A defect list a developer or a repair agent can act on without reading Forms code. Unreachable code listed before anyone pays to convert it. Source quirks turned into explicit waiver decisions for the customer instead of silent fixes.

The limits today.

A clean diff means no difference in the behaviour the scenarios exercise under the agreed policy. It does not mean the applications are equivalent in every respect.

Choosing the next target platforms. Each target stack needs its own adapter and mapping; scenarios and golden records are written once and replay against any of them. Partners choose the next targets from the stacks their customers are moving to (APEX, Java, .NET, others). The natural first engagement is a joint pilot on one module of a real customer application, on that customer's client version, which builds the adapter for the partner's stack and retires the two largest open questions: client versions and scale.

The live demos share one database per app: visitors see each other's changes, and the data resets to the scenario fixture every night.