Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

Creating Unit Tests in ObjectScript for HL7 pipelines using %UnitTest class

One of the pain points for maintaining HL7 interfaces is the need to run a reliable regression test upon deployment to new environments and after upgrades. The %UnitTest class allows unit tests to be created and packaged alongside…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

One of the pain points for maintaining HL7 interfaces is the need to run a reliable regression test upon deployment to new environments and after upgrades. The %UnitTest class allows unit tests to be created and packaged alongside interface code. Test data can also be maintained within the unit test class, allowing for quick and easily repeatable smoke-testing and regression testing.






Resources:








Scenario:



A unit test class is created for each inbound feed based on the data profiling, routing, and mapping requirements.



Sample requirements:



Image description



To test each scenario, we need to run through a sample of each event type and confirm the routing rules. We also need to confirm the specific mapping requirements and find sample data for each scenario.






HL7 Production



The purpose for this UnitTest-RuleSet is to test a HL7 pipeline: Business service → Routing Rules → Transformation.



In this example created for the production shown below, the ADT process flow goes through several additional hops. A class extending the UnitTest.RuleSet.HL7 was modified to allow for handling more complex process flows.



Process Flow: FromHSROUTER.TESTAdt → FromTESTAdt.ReorgSegmentProcess → RouteTESTAdt → TEST.ADTTransform → HS.Gateway.HL7.InboundProcess



Image description






Create Unit Test Class



Create a TestAdtUnitTest class that extends UnitTest.RuleSet.HL7. (UnitTest.RuleSet.Example in the UnitTest-RuleSet repository contains an example of such a class.



*Note: In this example, everything was moved under HS.Local in HSCUSTOM for ease of testing. *



Signature:

Class HS.Local.EG.UnitTest.TestAdtUnitTest Extends HS.Local.Util.UnitTest.RuleSet.HL7






Class Structure Preview



The Unit Test class is organized with this layout:



Image description






Set Up Parameters



These class parameters are used to set up testing.




// Namespace where production is located
Parameter Namespace = "EGTEST";

// Base directory for unit tests

Parameter TestDirectory = "/tmp/unittest";

// sub-directory name for unit tests

Parameter TestSuite = "TEST-HL7ADT";

/// Override for different schema
Parameter HL7Schema = "2.5.1:ADT_A01";

/// Override with name of existing service on production
Parameter SourceBusinessServiceName = "FromHSROUTER.TESTAdt";

/// Override with name of existing business process routing engine on production
Parameter TargetConfigName = "FromTESTAdt.ReorgSegmentProcess";

/// Primary routing process name on production
Parameter PrimaryRoutingProcessName = "RouteTESTAdt";

/// Secondary routing process name on production
Parameter SecondaryRoutingProcessName = "TEST.ADTTransform";




Note: The primary and secondary routing processes are referenced in various test methods in order to test the output and results from two routing processes chained together.






Create Sample Input Messages



To create a reusable Unit Test class, we save anonymized samples of each event type and any additional messages needed to fulfil the testing scenarios into the Unit Test class in XDATA blocks at the bottom of the file.



Example of an XDATA block:



The name SourceMessageA01 is used to reference the specific XDATA block.




XData SourceMessageA01
{
<test><![CDATA[
MSH|^~\&|Epic|TEST||TEST|20230911060119|RUBBLE|ADT^A01|249509431|P|2.2
EVN|A01|20230911060119||ADT_EVENT|RUBBLE^MATTHEW^BARNEY^D^^^^^TEST^^^^^UH|20230911060000|PHL^PHL^ADTEDI
ZVN||LS23450^LS-23450^^^^RTL
PID|1|000163387^^^MRN^MRN|000163387^^^MRN^MRN||FLINTSTONE^ANNA^WILMA||19690812|F|MURRAY^ANNA~FLINTSTONE^ANNA^R~FLINTSTONE^ANNA|B|100 BEDROCK WAY^^NORTH CHARLESTON^SC^29420-8707^US^P^^CHARLESTON|CHAR|(555)609-0969^P^PH^^^555^6090969~^NET^Internet^[email protected]~(555)609-0969^P^CP^^^555^6090969||ENG|M|CHR|1197112023|260-61-5801|||1|||||Non Veteran|||N
ZPD||MYCH||AC|||N||N
PD1|||TEST HOLLINGS CANCER CENTER^^10003|1134107873^LINK^MICHAEL^J^^^^^EPIC^^^^PNPI
ROL|1|UP|GENERAL|1134107873^LINK^MICHAEL^J^^^^^EPIC^^^^PNPI|20211115
NK1|1|GABLE^BETTY|PARENT||(555)763-5651^^PH^^^555^7635651||Emergency Contact 1
NK1|2|FLINTSTONE^FRED|Spouse|100 Bedrock way^^REMBERT^SC^29128^US|(888)222-2222^^PH^^^888^2222222|(888)222-3333^^PH^^^888^2223333|Emergency Contact 2
PV1|1|O|R1OR^RTOR^07^RT^R^^^^TEST RT OR|EL|||1386757342^HALSTEAD^LUCINDA^A.^^^^^EPIC^^^^PNPI|1386757342^HALSTEAD^LUCINDA^A.^^^^^EPIC^^^^PNPI||OTO||||PHYS|||1386757342^HALSTEAD^LUCINDA^A.^^^^^EPIC^^^^PNPI|SO||BCBS|||||||||||||||||||||ADMCONF|||20230911060000
PV2||PRV||||||20230911||||HOSP ENC|||||||||N|N||||||||||N
ZPV||||||||||||20230911060000
OBX|1|NM|PRIMARYCSN|1|1197112023||||||F
AL1|1|DA|900525^FISH CONTAINING PRODUCTS^DAM|3|Anaphylaxis|20210823
AL1|2|DA|568^PEANUT^HIC|3|Anaphylaxis|20221209
AL1|3|DA|12753^TREE NUT^HIC|3|Anaphylaxis|20221209
AL1|4|DA|1193^TREE NUTS^DAM|3|Anaphylaxis|20130524
AL1|5|DA|1554^HYDROCODONE^HIC||Other|20210728
AL1|6|DA|3102^POLLEN EXTRACTS^HIC||Other|20201204
AL1|7|DA|11754^SHELLFISH DERIVED^HIC||Other|20210728
DG1|1|I10|Q85.02^Neurofibromatosis, type 2^I10|Neurofibromatosis, type 2||ADMISSION DIAGNOSIS (CODED)
DG1|2|I10|D33.3^Benign neoplasm of cranial nerves^I10|Benign neoplasm of cranial nerves||ADMISSION DIAGNOSIS (CODED)
DG1|3|I10|J38.01^Paralysis of vocal cords and larynx, unilateral^I10|Paralysis of vocal cords and larynx, unilateral||ADMISSION DIAGNOSIS (CODED)
DG1|4||^NF2 (neurofibromatosis 2) [Q85.02]|NF2 (neurofibromatosis 2) [Q85.02]||ADMISSION DIAGNOSIS (TEXT)
DG1|5||^Acoustic neuroma [D33.3]|Acoustic neuroma [D33.3]||ADMISSION DIAGNOSIS (TEXT)
DG1|6||^Unilateral complete paralysis of vocal cord [J38.01]|Unilateral complete paralysis of vocal cord [J38.01]||ADMISSION DIAGNOSIS (TEXT)
GT1|1|780223|FLINTSTONE^ANNA^WILMA^^^^L||100 BEDROCK WAY^^NORTH CHARLESTON^SC^29420-8707^US^^^CHARLESTON|(555)609-0969^P^PH^^^555^6090969~(555)763-5651^P^CP^^^555^7635651||19690812|F|P/F|SL|248-61-5801|||||^^^^^US|||Full
ZG1||||1
IN1|1|BL90^BCBS/STATE EMP^PLANID||BCBS STATE|ATTN CLAIMS PROCESSING^PO BOX 100605^COLUMBIA^SC^29260-0605||(800)444-4311^^^^^800^4444311|002038404||||20140101||NPR||FLINTSTONE^THOMAS^^V|Sp|19661227|3310 DUBIN RD^^NORTH CHARLESTON^SC^29420^US|||1|||||||||||||1087807|ZCS49984141|||||||M|^^^^^US|||BOTH
IN3|1|||2||20230911|20230911|RUBBLE^MATTHEW^BARNEY^D|||NOT|||||(800)999-0000^^^^^800^9990000~(888)444-5555^^^^^888^4445555
ZIN|||||||FLINTSTONE^THOMAS^^V|||||16871492
]]></test>
}




Sample code to retrieve data from an XDATA block for use in testing:



set xdata=##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1)_"||"_XDataName,0)



Here’s the sample code from ** GetMessage**, a helper method used to read in and return the data from an XDATA block based on the block name.




ClassMethod GetMessage(XDataName As %String) As EnsLib.HL7.Message
{
#dim SourceMessage as EnsLib.HL7.Message
set xdata=##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1)_"||"_XDataName,0)
quit:'$IsObject(xdata) $$$NULLOREF
set lines=""
while 'xdata.Data.AtEnd
{
set line=$ZSTRIP(xdata.Data.ReadLine(),"<w")
continue:line=""
continue:$Extract(line,1)="<" // ignore opening or closing XML tags and start CData tag
continue:$Extract(line,1)="]" // ignore ]]> closing CDATA
set lines=lines_($S($L(lines)=0:"",1:$C(..#NewLine)))_line
}
set SourceMessage=##class(EnsLib.HL7.Message).ImportFromString(lines,.tSC)
quit:$$$ISERR(tSC) $$$NULLOREF
set SourceMessage.DocType=..#HL7Schema
set tSC=SourceMessage.PokeDocType(..#HL7Schema)
quit SourceMessage
}






Create Testing Methods



The Unit Test class also contains a Test method that programmatically sets up each test, injects the message into the production, and asserts that the resulting transformed message matches what is expected.



The test example contains these test methods:




  • TestMessageA01

  • TestMessageA02

  • TestMessageA03

  • TestMessageA04

  • TestMessageA05

  • TestMessageA06

  • TestMessageA08

  • TestMessageA28

  • TestMessageA31

  • TestCorrectAssigningAuthorityForA01

  • TestEncoutnerNumberPresent

  • TestPD1LocationMapped



Example Method: TestMessageA01

Method to test that A01 messages process without error and are routed to correct transform.



Method TestMessageA01()
{
Set ReturnA01 = ..#SecondaryRoutingProcessName_":HS.Local.EG.ProfSvcs.Router.Base.ADT.TransformA01"
#dim message as EnsLib.HL7.Message

// Load new HL7Message per UnitTest
set ..HL7Message=..GetMessage("SourceMessageA01")
quit:'$IsObject(..HL7Message) $$$ERROR(5001,"Failed to correlate Xdata for Source Message")

set routingProcess = ..#PrimaryRoutingProcessName

set message=..HL7Message.%ConstructClone(1)
do message.PokeDocType(message.DocType)
do message.SetValueAt("SYSA","MSH:3.1")
set expectSuccess=1
set expectReturn="send:"_ReturnA01
set expectReason="rule#8"
do ..SendMessageToRouter(message,"TestMessageA01",routingProcess, expectSuccess, expectReturn, expectReason)
}




Note: SendMessageToRouter() is a method implemented in the UnitTest-RuleSet package.



Example Method: TestEncounterNumberPresent



The method below tests for specific resulting values in the message after the transform.




Method TestEncounterNumberPresent()
{
#dim message as EnsLib.HL7.Message

// Load new HL7Message per UnitTest
set ..HL7Message=..GetMessage("SourceMessageA01")
quit:'$IsObject(..HL7Message) $$$ERROR(5001,"Failed to correlate Xdata for Source Message")

//source of transform process
set routingProcess = ..#SecondaryRoutingProcessName
set message=..HL7Message.%ConstructClone(1)
do message.PokeDocType(message.DocType)
do message.SetValueAt("SYSA","MSH:3.1")
//Check that output has PV1:19 is not empty
set expectSuccess=1
set expectElement="PV1:19"
set expectReturnVal="1197112023"
do ..SendMessageReturnOutput(message,"TestMessageA01", routingProcess, expectSuccess, expectElement, expectReturnVal)
}




Note: SendMessageReturnOutput() is a method modified to return the output message for evaluation.






How to Run the UnitTest



The %UnitTest class implementation depends on the ^UnitTestRoot global for the location of the unit test working folders.



There are two parameters used to set the folders:




// Base directory for unit tests
Parameter TestDirectory = "/tmp/unittest";

// sub-directory name for unit tests
Parameter TestSuite = "TEST-HL7ADT";




In this case, the class would expect the folder: /tmp/unittest/TEST-HL7ADT to exist in the environment where the unit test class is run.



Additionally, the custom implementation sets the ^UnitTestRoot global and changes to the specific namespace in the Namespace parameter.



To run from the terminal:



HSCUSTOM> do ##class(HS.Local.EG.UnitTest.TestAdtUnitTest).Debug()



The results of the run will be sprinted to the console. If any test fails, the overall test is considered failed. In addition to the terminal, you can also see the results from the management portal. Use the link from the output to open the URL.






Snippet of Console Output



TestMessageA31 passed

TestPD1LocationMapped() begins ...

14:50:20.104:...t.TestAdtUnitTest: TestPD1Location Sent

LogMessage:SessionId was 130

LogMessage:Source Config Name name is :TEST.ADTTransform

LogMessage:Message Body Id was 94

LogMessage:Expect Success is 0

LogMessage:Testing for value PV1:39

LogMessage:Found value

AssertNotEquals:Expect No Match:TestPD1Location:ReturnValue= (failed) <<==== FAILED TEST-HL7ADT:HS.Local.EG.UnitTest.TestAdtUnitTest:TestPD1LocationMapped

LogMessage:Duration of execution: .033106 sec.

TestPD1LocationMapped failed

HS.Local.EG.UnitTest.TestAdtUnitTest failed

Skipping deleting classes

TEST-HL7ADT failed



Use the following URL to view the result:

http://192.168.1.229:52773/csp/sys/%25UnitTest.Portal.Indices.cls?Index=3&$NAMESPACE=EGTEST

Some tests FAILED in suites:

TEST-HL7ADT






Viewing Results in the Management Portal



Use the URL displayed on the terminal and paste it into a browser to see the results. Clicking on the test name will provide additional details.



Image description



Clicking on each test link will display more information on the test:



Image description






Conclusion



Building Unit Test classes for each HL7 interface and packaging it with the interface code provides documentation of the testing process and sample data and also allows for quick regression testing of any updates or changes to the data or implementation.



Upon deployment, the Unit Test class serves as a self-contained smoke test to confirm the interface is complete and functional.






Additional Considerations




  • The UnitTest_RuleSet framework can be adapted for CCDA unit testing. The routing tests are relatively similar to the HL7 example. To address the mapping requirements, the Unit Test class must be implemented to handle XSLT and XPaths.


  • QA resources can gather requirements and sample data to set up the Unit Test class before implementation begins.


  • Unit tests for all interfaces can be packaged together unter Unit Test Manager so that the entire package can be run at once to validate the existing configuration and code.


1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - Creating Unit Tests in ObjectScript for HL7 pipelines using %UnitTest class
id: 5399ddf2-7b57-41b0-94fe-9868d2d5fc4b
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-27
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-27"
        description = "YARA Signature for "
    strings:
        $str = "Creating Unit Tests in ObjectS" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("Creating Unit Tests in ObjectScript for ")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*Creating Unit Tests in ObjectScript for *"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "Creating Unit Tests in ObjectScript for "
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

CTI Threat Relationship Graph2 Knoten / 1 Relationen
CVE / Incident Software MITRE ATT&CK CWE Weakness IoC
🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Analyse für identifizierte Bedrohung auf Basis von Live-CTI (ENISA EUVD): CVSS 0.0 · EPSS 0.0% · CISA KEV: nein. Handlungsableitung aus den verlinkten Hersteller-Quellen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Creating Unit Tests in ObjectScript for HL7 pipelines using %UnitTest class

Thematisch verwandte Begriffe: Creating, Unit, Tests, ObjectScript · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2025-71424 | Contrast, Edgeless Systems' runtime for confidential containers on Kuber…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag