Your DUnitX tests check the logic. But who checks the forms? Who makes sure that a click on Save really saves, that the label shows the right total, and that the dialog box closes? Usually a person, by hand, before every release.
This page shows how to fully automate the GUI testing of a Delphi application with Autopilot for Delphi (v3): let Claude test your app in plain words, or write DUnitX tests that click buttons and read labels on every build.
Why GUI testing in Delphi is hard
Many ways to drive a GUI see your app from the outside, the way Windows sees it. A script that clicks at screen positions can break when the layout changes. A tool that goes only through Windows UI Automation doesn’t see the Delphi name of a control. Yet that’s what we Delphi developers want: find a control by its TComponent.Name, not by its place on the screen.
You already know the name of every control: you gave it in the Object Inspector. A test should use that name.
How Autopilot does it
Autopilot sees your app from the inside. It answers commands over a private named pipe.
- Every control is found by its Delphi name:
frmMain.btnSave,frmMain.edtName. Move it, resize it, restyle the form: the test still finds it. - Controls with no window of their own work too, like
TLabelandTSpeedButton. - No mouse. A click runs the control’s own click code, and the text of an edit box is set through its
Textproperty, soOnChangefires as usual. The mouse cursor never moves. - VCL and FMX.
There are two ways to use it.
Way 1: Claude tests your app in plain words
Tell Claude what to check: “type a name, press Save, and see that the status bar says Saved”. Claude finds the controls, clicks, types, reads the labels, takes a screenshot when it needs one, and tells you what it found. It can also find the faults nobody wrote a test for, because it looks at the whole form, not only at the one label a test checks. The 14 tools Claude uses are listed on the Details page.
Way 2: DUnitX tests that run on every build, with no AI
New in version 3.0 (coming soon): the unit Autopilot.Client and its class TAutopilotApp. Your DUnitX test project starts the app, sends commands to it and checks the answers with Assert. No AI and no MCP server take part, so the verdict doesn’t depend on an AI model.
This is a real test from the demo test project that comes with Autopilot. A [SetupFixture] method starts the demo app once for all tests, and the test clicks a button and checks the counter:
procedure TDemoTests.StartApp; // [SetupFixture]
begin
App := TAutopilotApp.Start(DemoExePath);
end;
procedure TDemoTests.IncrementCountsUp;
var
Before: Integer;
begin
Before := StrToInt(App.GetText('frmMain.lblCounter'));
App.Click('frmMain.btnIncrement');
Assert.AreEqual(IntToStr(Before + 1), App.GetText('frmMain.lblCounter'));
end;What you get:
- Fast. One command takes about 0.8 ms. The 8 tests of the VCL demo project run in about 1.6 seconds, start and close of the app included.
- Made for a build agent. The test runner returns exit code 0 when every test passed and 1 when one failed, and writes an NUnit XML file. Run it as a step on a build agent in a signed-in Windows session.
- A broken app fails the test, it doesn’t hang the run. An
OnClickthat raises an exception makesClickraiseEAutopilotHandlerError. When the app’s main thread hangs, the command raisesEAutopilotError(code -32004) after its timeout. An app that stops answering as a whole, for example at a breakpoint, raisesETargetNotResponding, and an app that crashed raisesETargetNotRunning. - No orphan apps. The app ends together with the test EXE, even when the test run is killed.
- Dialogs, timers and screenshots.
DismissDialogpresses a button of a native message box, such as one fromMessageBox(VCL) orMessageDialog(FMX).WaitForTextwaits for a label that a timer or a thread fills. A test can callScreenshotto save a PNG of the form.
The full method list of TAutopilotApp is on the Details page.
Note: in a Release build, the bridge disables itself so you can safely deliver your app to the customers without clicking any buttons.
Both together
Use the two ways together. Claude drives a new form once, finds the right control names and the texts the labels really show, and writes the DUnitX tests for you. From then on the tests run on every build, with no AI and at no token cost. When a test fails, you call Claude back to find out why.
Try it, then buy it
Version 3.0 comes with a free demo: a small Delphi app with the bridge already inside, and the MCP server, so you can connect Claude to it and see Autopilot at work. Version 3 is sold per developer: every developer who uses it needs a seat. A seat is for life, per major version: it covers every update of the major version you bought (for example 3.0, 3.1, 3.2). The next major version is a new purchase. See the Autopilot for Delphi page.