4Test
The domain-specific test automation language of Segue Software's QA Partner — later Silk Test — an object-oriented 4GL built around GUI window declarations, an automatic recovery system, and testcases as a first-class language construct.
Created by Segue Software, Inc.
4Test is a domain-specific programming language built for one job: describing, running, and recovering from automated GUI tests. It first shipped in 1993 inside QA Partner, Segue Software’s automated functional and regression testing tool, and it is still present today — largely unchanged in shape — inside Silk Test Classic, the descendant of that same product now owned by OpenText.
What makes 4Test worth studying is not its syntax, which is a lightly restyled C, but its vocabulary. Most test automation of the era was written in a general-purpose language plus a library. 4Test instead made the concepts of the testing domain into language keywords. A testcase is a declaration, not a naming convention. An appstate is a language construct that declares the precondition a test needs. A window declaration is a first-class binding between a symbolic name and a real GUI object. The result is a language where a test script reads much closer to a test plan than to a program.
History and Origins
Segue Software introduced QA Partner in 1993; according to USPTO records indexed by Justia, the trademark application for SEGUE QA PARTNER was filed on February 4, 1993. The product’s premise was that GUI regression testing should be scripted and repeatable rather than performed by hand, and that the scripts should survive cosmetic changes to the interface. 4Test was written to make both of those things practical for QA engineers who were not necessarily career software developers — hence its positioning as a fourth-generation language (4GL) rather than as a systems language.
In the mid-1990s — reportedly 1996 — Segue renamed QA Partner to SilkTest, aligning it with the company’s broader Silk product line. The language name did not change, and by all accounts the rename was essentially a marketing event: 4Test scripts written for QA Partner continued to run.
The product then passed through a chain of acquisitions that shaped 4Test’s long, slow decline in prominence:
| Year | Event | Effect on 4Test |
|---|---|---|
| 2006 | Borland acquires Segue Software (completed April 19, 2006, ~$100M) | 4Test continues as the sole scripting language; SilkTest 8.0 adds Eclipse application support |
| 2009 | Micro Focus acquires Borland; Silk4J introduced | Java becomes an alternative to 4Test for writing tests |
| 2010 | Silk Test Workbench and Silk4NET introduced | The 4Test client is renamed Silk Test Classic; VB.NET and C# join the list |
| 2017 | Silk WebDriver offered as a free Selenium recorder | Selenium-style scripting offered alongside the proprietary stack |
| 2023 | OpenText acquires Micro Focus | 4Test remains shipped, maintained rather than advanced |
The 2010 rename is the pivotal moment in the language’s history. Calling the 4Test client “Classic” was an honest label, and it marked the point at which 4Test stopped being the way to use the product and became one way — the legacy way — to use it.
Design Philosophy
Testing concepts as language constructs
The central design decision in 4Test is that the testing domain gets syntax. A test is written as:
testcase SaveNewFile () appstate DefaultBaseState
STRING sFile = "C:\\temp\\hello.txt"
TextEditor.File.New.Pick ()
TextEditor.Document.TextField.SetText ("Hello, World!")
TextEditor.File.SaveAs.Pick ()
TextEditor.SaveAs.FileName.SetText (sFile)
TextEditor.SaveAs.OK.Click ()
Verify (SYS_FileExists (sFile), TRUE, "File was written to disk")
The appstate clause is not a function call or an annotation — it is part of the testcase declaration, and it tells the runtime which application state must be established before the body runs. This is the same idea that later frameworks express as setup fixtures or @Before methods, expressed a decade or more earlier as a keyword.
Window declarations as an abstraction layer
4Test separates what the test does from where the controls are. GUI objects are declared, conventionally in include files with a .inc extension, using the window keyword followed by a class, an identifier, and locator information:
window MainWin TextEditor
multitag "Text Editor"
"$C:\\Program Files\\Silk\\SilkTest\\TextEdit.exe"
Here MainWin is the class, TextEditor is the 4Test identifier that scripts refer to, and the multitag supplies the tags that identify the window at runtime — in this case both a caption and an executable path, so that a change to one does not break recognition. Nested controls (menus, menu items, dialogs, text fields) are declared beneath their parent, and indentation establishes the hierarchy. Scripts then address controls through dotted paths like TextEditor.File.New, which is why a caption change requires editing one declaration rather than every test that touches that control.
The Classic Agent uses tag/multitag; the later Open Agent uses locator with simpler criteria. Both are consumed by the same 4Test declaration syntax.
The recovery system
Segue’s other signature idea was that a failed test must not poison the tests that follow it. Silk Test’s recovery system ensures the application is in its declared base state before and after every testcase. Crucially, that machinery is itself written in 4Test and shipped as source in defaults.inc: teams override it by defining their own ScriptEnter, ScriptExit, TestcaseEnter, TestcaseExit, TestPlanEnter, or TestPlanExit functions, which the runtime uses in place of the defaults. Declaring appstate none opts a testcase out of recovery entirely.
Key Features
4Test’s designers described it as an object-oriented language similar to C++, and the official documentation includes a direct C-to-4Test comparison. The differences are the interesting part:
Types
- Static declarations, but with
ANYTYPE, which can hold any base type — an escape hatch C has no equivalent for. - A real
BOOLEANtype, rather than C’s integer stand-in. - No character type; strings replace
char. LISTfor dynamic sequences (LIST OF STRING,LIST OF ANYTYPE), and arrays that resize dynamically rather than being fixed at declaration.- A
NUMBERtype that holds either an integer or a floating-point value.
No pointers
4Test has no pointers at all. Indirect reference to variables and functions is done with the @ operator instead. Function parameters are annotated in, out, or inout rather than passed by address — a choice that removes an entire class of errors from scripts written by non-systems programmers.
Control flow
Beyond C-style loops, 4Test adds a counted form (for i = 1 to n step 5) and a for each statement for iterating a list:
LIST OF STRING lsUsers = {"alice", "bob", "carol"}
STRING sUser
for each sUser in lsUsers
LogIn (sUser)
switch cases break automatically at the end of each case, and a separate select statement dispatches on boolean expressions. There is no do while. Assignment inside a conditional — C’s if ((i = 5) == TRUE) — is prohibited outright.
Exceptions and concurrency
4Test includes statements with no C counterpart: exit, raise, and reraise for exception handling, and parallel, spawn, and rendezvous for concurrent execution — the latter reflecting the need to drive client/server applications from multiple machines at once. Error handling is written with do ... except:
do
Verify (LoginDialog.UserName.GetText (), "admin")
except
ExceptLog ()
reraise
No preprocessor
There is no #include and no macro layer. The use statement pulls in include files instead, which keeps the declaration hierarchy explicit.
Recording as code generation
Because window declarations bind GUI classes to methods, Silk Test can record a session and emit readable 4Test. Picking a menu item records as Pick, checking a checkbox as Check, typing as SetText, selecting a list item as Select, closing a dialog as Close. Recorded scripts are ordinary 4Test source and are meant to be edited afterwards — a middle path between pure capture-replay tools and pure hand-written frameworks.
Evolution
4Test’s evolution is unusual: the language itself changed relatively little, while the world around it was rebuilt several times.
The Classic Agent, the original technology that attached to applications under test, was joined around the 2010 releases by the Open Agent, built for newer technology stacks. Silk Test Classic can drive either one from 4Test, choosing automatically based on the project — Apache Flex and Windows API-based client/server projects use the Open Agent, while a project or script developed against the Classic Agent continues to use it. That dual-agent arrangement let decades-old 4Test suites keep running while new scripts targeted browsers, Java, .NET, SAP, and mobile.
Meanwhile the product grew clients that bypassed 4Test entirely: Silk4J (Java, circa 2009), Silk Test Workbench and Silk4NET (VB.NET and C#, circa 2010), and Silk WebDriver (Selenium, circa 2017). Modern Silk Test documentation presents 4Test as one of four scripting options, and describes it as the language of the Classic client — accurate, and also a fair description of its status.
Current Relevance
4Test is dormant rather than dead. It is not developed as a language in any meaningful sense: there is no independent implementation, no package ecosystem, no compiler outside the Silk Test product, and little visible community activity outside OpenText’s Silk Test forums. It cannot be run without a licensed Silk Test installation, which is why there is no container image or standalone toolchain for it.
But 4Test code is still executing. Large 4Test regression suites — some of them decades old — represent exactly the kind of investment organizations do not rewrite voluntarily, and the Classic Agent’s continued presence in the product exists largely to protect them. Publicly named customer case studies are scarce; the language’s footprint lives mostly inside private enterprise QA repositories rather than in open source.
For anyone encountering a 4Test codebase today, the practical notes are: scripts live in .t files, shared declarations and helper functions in .inc files, the recovery defaults in defaults.inc, and the whole thing is driven from Silk Test Classic on Windows.
Why It Matters
4Test is a clean historical example of a domain-specific language that got its domain right. Concepts that today’s test frameworks express through conventions, annotations, and library calls, 4Test expressed as syntax three decades ago:
- Setup/teardown as a declared precondition — the
appstateclause anticipates fixtures and@Before/@After. - Page objects before page objects — window declarations are, functionally, the page-object pattern, with an indentation-based hierarchy and a locator layer that isolates tests from UI churn. The page-object pattern later popularized in the Selenium community arrives at a similar separation of concerns, though there is no documented direct lineage between the two.
- Test isolation as a runtime guarantee — the recovery system’s insistence on returning to a base state before and after every test is the same discipline modern frameworks enforce with fresh fixtures and containerized environments.
- Readable generated code — recording produced editable source, not an opaque binary trace, acknowledging that recorded tests are a starting point rather than a deliverable.
Its decline is equally instructive. 4Test lost not because those ideas were wrong but because they were locked inside a single proprietary product. When Selenium and WebDriver made browser automation scriptable from Java, Python, C#, and JavaScript — languages teams already knew, with package managers and CI integration they already used — a bespoke 4GL that only ran inside one vendor’s IDE had no answer. The parent product’s own move to Java, .NET, and WebDriver clients was an admission of that. The lesson 4Test leaves behind is that a well-designed domain-specific language still has to compete with the general-purpose ecosystem surrounding it, and that ecosystems, in the end, tend to win.
Sources
- Silk Test — Wikipedia
- The 4Test Language — Micro Focus / OpenText documentation
- C Compared to 4Test — Micro Focus / OpenText documentation
- Main Window and Menu Declarations — Silk Test Classic Help
- Core Data Types — Silk Test Classic Help
- Silk Test Agents Overview (Classic Agent and Open Agent)
- Segue Software, Inc. trademarks — Justia
- Borland Completes Deal to Acquire Segue — eWeek
- Borland Releases SilkTest 8.0 — Enterprise Systems Journal
Timeline
Notable Uses & Legacy
OpenText Silk Test Classic
4Test is the native scripting language of the Silk Test Classic client. Every test recorded or hand-written in Classic is 4Test source, stored in script files (.t) and include files (.inc), and driven by test plan files.
The Silk Test recovery system (defaults.inc)
Silk Test's own base-state recovery logic — the machinery that returns an application under test to a known state before and after each testcase — ships as 4Test source in defaults.inc, and users extend or override it by redefining functions such as ScriptEnter, TestcaseEnter, and TestcaseExit in their own 4Test code.
Desktop GUI regression suites
Per the product documentation, Silk Test drives .NET (WinForms, WPF), Java (Swing, SWT), and Windows API-based client/server applications; 4Test window declarations map those controls to named identifiers that testcases manipulate with methods like Pick, SetText, Check, and Select.
Browser and SAP GUI automation
Later Silk Test releases extended the same scripting model, via the Open Agent, to DOM-based browser testing and to the SAP Windows GUI. The browser list varies by release; the product documentation names Internet Explorer, Firefox, Chrome, and Edge among supported targets, with support for any given browser depending on the specific Silk Test version and client.