The input to a test is an HL7 V2 message with segments. A very long time ago, I resolved to use plain-text files containing messages and divide them with a blank line. Here's an example below of a file with two messages I've previously used for other purposes at IHE Connectathons (I have several years of IHE Connectathon test data lying about):
# Outbound ack:
MSH|^~\&|PAT_IDENTITY_X_REF_MGR_MISYS_TLS|ALLSCRIPTS|OTHER_IBM_BRIDGE_TLS|IBM|20090224114149-0500||ACK^A04|OpenPIXPDQ10.243.0.65.19767899354465|P|2.3.1
MSA|AA|0851077658473390286
# PIX Feed (ADT^A01)
# Inbound feed:
MSH|^~\&|OTHER_IBM_BRIDGE_TLS|IBM|PAT_IDENTITY_X_REF_MGR_MISYS|ALLSCRIPTS|20090224104152-0600||ADT^A01^ADT_A01|8686183982575368499|P|2.3.1
EVN||20090224104152-0600
PID|||102^^^IBOT&1.3.6.1.4.1.21367.2009.1.2.370&ISO||SINGLETON^MARION||19661109|F
PV1||I
You might also note that I allow for comment characters at the start of the line. My test framework simply ignores those lines while reading the test data, and if gives me a way to identify the test case. For testing V2 to FHIR Conversions, I needed a way to create assertions that would be used to verify the assertion. Of course, FHIRPath comes to mind because it's already an expression language widely used in FHIR itself for assertions and other manipulations of FHIR Resources. That's ideal language for my use case.
So, I added a capability in my test case reader to add assertions to the test case. Here's an example for the first test case above. The @ sign introduces an assertion.
@MessageHeader.source.name = "PAT_IDENTIFY_X_REF_MGR_MISYS_TLS"
@MessageHeader.source.endpoint = "ALLSCRIPTS"
@MessageHeader.destination.name = "OTHER_IBM_BRIDGE_TLS"
@MessageHeader.destination.endpoint = "IBM"
I'm actually checking a bundle but use a little string substitution hackery to replace MessageHeader with %context.entry.resource.ofType(MessageHeader) at the head of the expression to save me about 31 characters of typing each time.
The next bit of fun is enabling the assertions to come close to where they are useful in the message. It should be obvious that each test case has two streams of data, the message, and the assertions. They can easily be interwoven. So, assertions can easily follow the segment, but I also wanted more, because some segments can be very long. Borrowing from other scripting languages (e.g., bash), I allow the introduction of the \ character at the end of the line to allow lines to be continued. I realized that it would be important to visually see the start an end of a segment in the file, so I ignore leading whitespace at the beginning of continuation lines. So now I can write:
# Outbound ack:
MSH|^~\&|\
PAT_IDENTITY_X_REF_MGR_MISYS_TLS|\
@MessageHeader.source.name = "PAT_IDENTIFY_X_REF_MGR_MISYS_TLS"
ALLSCRIPTS|\
@MessageHeader.source.endpoint = "ALLSCRIPTS"
OTHER_IBM_BRIDGE_TLS|\
@MessageHeader.destination.name = "OTHER_IBM_BRIDGE_TLS"
IBM|20090224114149-0500|\
@MessageHeader.destination.endpoint = "IBM"
|ACK^A04|OpenPIXPDQ10.243.0.65.19767899354465|P|2.3.1
MSA|AA|0851077658473390286
And so forth. In this way, I now have a test case where I can start with the message in my usual form (simple text with a blank line between cases). From there I can augment the test case with assertions that I feel are important. Following that, I can also break things up, even just long lines of V2 messages to make the test files more readable.
The final piece of this was to allow long assertions to be broken up the same way messages are, and to steal the final comment in the assertion expression (comments are part of FHIRPath syntax) to use for my assertion message in my testing framework. That's also just simple string substitution as well.
You can find all of the code for this in V2toFHIR, the open-source converter my team and I created for some of our ongoing work. The two key files of interest are MessageParserTests.java and TestData.java. The method TestData.load() is where all the test input parsing magic happens. It's not really that complicated.
0 comments:
Post a Comment