Recruiter Snapshot

Hornet

2012

A test language for a pricing rules engine, and the compiler front end that runs it.

Product screens

01 / 04
Hornet
A test case in Hornet Lingo: value lists expand into data rows. Sample data.

Overview

I designed Hornet Lingo in 2012, a domain-specific language for data-driven tests of a bank's payment pricing rules, and built its toolchain: ANTLR grammars that compile test scripts into an executable model, a concurrent engine that runs them against the rules service, and a workbench that highlights the language as you type.

Problem statement

A rules engine priced every international payment quote: client type, tier, margin, fee, promotion and expiry, across more than 160 currencies, client segments, channels and business hours. Testers checked it with hand-built SOAP requests, so coverage ended where someone's patience for XML did, and every new rule meant another batch of requests to write and compare by eye.

Solution

I wanted testers to write what a rule should do, not how to call the service: a few readable lines per rule, a list of values instead of a loop, and a tool that turns those lines into hundreds of checked requests.

A language for one domain.

A Hornet Lingo test case is a header of properties, then SETUP, TEST and TEARDOWN blocks of operations, each pairing its inputs with an EXPECT section. The lexer types every value as a string, number, boolean, date or one of 164 ISO 4217 currency codes, so a mistyped currency is a syntax error rather than a failed test.

Defined as grammars.

I wrote the language as three ANTLR 3 grammars: a lexer, a parser whose rewrite rules build an abstract syntax tree, and a tree grammar that walks that tree into the Java objects the engine runs. The syntax went through four iterations, from comma-separated text to typed, space-separated lists, and about 300 lines of grammar generate 6,700 lines of parser code.

Lists instead of loops.

Any parameter takes a list of values. The engine expands each operation into data rows, pairing values row by row and repeating shorter lists, so one GET-RULE with ten amounts and three currencies becomes ten priced quotes, each checked on its own.

Templates and environments.

Each operation maps to a request template with {{placeholders}}, and environment files supply the endpoint, SOAP action, headers, proxy, request delay and thread-pool size, so the same script runs against SIT, UAT or pre-production unchanged.

A concurrent engine, local or remote.

The engine sends data rows from a thread pool and reports a tree of results: run, test case, block, operation, data row and field. It runs inside the workbench or as a remote engine published as a SOAP web service, so long regressions can run on a test server.

A workbench that knows the language.

A Swing workbench edits scripts in tabs with syntax highlighting from a JFlex lexer I wrote for the language, loads test cases, templates and environments from HP Quality Center through a client I built for its protocol, and streams the execution log as tests run.

Language definition

Hornet Lingo is defined by three ANTLR 3 grammars. The lexer types every value as it reads it, the parser checks the structure of a test case and rewrites it into an abstract syntax tree, and a tree grammar (not shown) walks that tree into the Java objects the engine executes.

Outcome

I designed the language and built the toolchain end to end: grammars, engine, workbench and Quality Center client. Hornet was used in production to regression-test the pricing rules, and a rule test became a short script a tester could read, review and keep in Quality Center beside its requirement. The screenshots are the original 2012 build, run again in 2026 against a mock rules service, with client names and data replaced.

Technologies used

ANTLR 3DSL designJavaSwingJFlexJAX-WSSOAPHP Quality Centerlog4j

Data volumes & scale

  • 3 ANTLR 3 grammars, ~300 lines
  • ~6,700 lines of generated parser code
  • 164 currency codes typed by the lexer
  • 4 iterations of the syntax
  • ~8,400 lines of hand-written Java
  • 6 levels of result reporting