How to deal with external data formats? #GivenWhenThenWithStyle

The next challenge in the Given-When-Then series is a common problem in situations when developing APIs or modules that connect to external systems.

How can I deal with hard to read example data (e.g. Guids, JSON Messages, URLs, …)?

Scenarios that suffer from this problem are usually driven by developers, and in rare cases by business users familiar with a technical message format (for example, SWIFT or the ISO 20022 standard). To make things more interesting, let’s use the business-driven case. Note that many Given/When/Then tools allow you to specify a parameter on multiple lines by enclosing it in three quote marks on both ends, and the following sample uses this trick to make the scenario slightly easier to format on a narrow screen:

Scenario: transactions in payment accepted

Given an account EE382200221020145685 has balance of 100.00 EUR
When the system receives the payment message
  """
  <?xml version="1.0" encoding="utf-8"?>
  <Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.03" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <CstmrCdtTrfInitn>
      <GrpHdr>
        <MsgId>MSGID000002</MsgId>
        <CreDtTm>2020-07-28T10:33:56</CreDtTm>
        <NbOfTxs>1</NbOfTxs>
        <CtrlSum>22.00</CtrlSum>
        <InitgPty>
          <Nm>Tom Nook</Nm>
        </InitgPty>
      </GrpHdr>
      <PmtInf>
        <PmtInfId>PaymentInformationId</PmtInfId>
        <PmtMtd>TRF</PmtMtd>
        <NbOfTxs>1</NbOfTxs>
        <CtrlSum>22.00</CtrlSum>
        <PmtTpInf>
          <SvcLvl>
            <Cd>SEPA</Cd>
          </SvcLvl>
        </PmtTpInf>
        <ReqdExctnDt>2020-07-28</ReqdExctnDt>
        <Dbtr>
          <Nm>Tom Nook</Nm>
        </Dbtr>
        <DbtrAcct>
          <Id>
            <IBAN>AT611904300234573201</IBAN>
          </Id>
        </DbtrAcct>
        <DbtrAgt>
          <FinInstnId>
            <BIC>ABAGATWWXXX</BIC>
          </FinInstnId>
        </DbtrAgt>
        <ChrgBr>SLEV</ChrgBr>
        <CdtTrfTxInf>
          <PmtId>
            <EndToEndId>E2E-ID-1</EndToEndId>
          </PmtId>
          <Amt>
            <InstdAmt Ccy="EUR">22.00</InstdAmt>
          </Amt>
          <CdtrAgt>
            <FinInstnId>
              <BIC>HABAEE2X</BIC>
            </FinInstnId>
          </CdtrAgt>
          <Cdtr>
            <Nm>Beneficiary1</Nm>
          </Cdtr>
          <CdtrAcct>
            <Id>
              <IBAN>EE382200221020145685</IBAN>
            </Id>
          </CdtrAcct>
          <RmtInf>
            <Ustrd>RemittanceInformation1</Ustrd>
          </RmtInf>
        </CdtTrfTxInf>
      </PmtInf>
    </CstmrCdtTrfInitn>
  </Document>
  """
Then the account EE382200221020145685 balance should be 122.00 EUR
And the payment status report generated should be
  """
  <?xml version="1.0" encoding="UTF-8"?>
  <Document>
    <CstmrPmtStsRpt>
      <GrpHdr>
        <MsgId>STAT20200728103356001</MsgId>
        <CreDtTm>2020-07-28T10:33:56</CreDtTm>
      </GrpHdr>
      <OrgnlGrpInfAndSts>
        <OrgnlMsgId>MSGID000002</OrgnlMsgId>
        <OrgnlMsgNmId>pain.001</OrgnlMsgNmId>
        <GrpSts>ACTC</GrpSts>
      </OrgnlGrpInfAndSts>
     </CstmrPmtStsRpt>
  </Document> 
  """

Now this is obviously horrible to read and maintain, but remember that business users working in SEPA processing are intimately familiar with this format, so they will happily provide examples or discuss individual fields with developers. If you really want to understand the individual fields in this message, check out the ISO 20022 message definitions (look for payments initiation), or perhaps one of the ISO 20022 payments guides published by local banks – here is an example from ABN AMRO.

There are several issues we need to address with specifications of this type:

1) Regardless of the format being business-readable or not, the verbosity of this structure makes it very difficult to understand what’s actually happening. And this is just a single scenario, showing an accepted message with a single payment (the group status GrpSts value ACTC means accepted fully). We want to show examples with multiple payments in the same message (multiple CdtTrfTxInf blocks, and NbOfTxs and CtrlSum updated to reflect the whole group), combined with examples for response statuses PART (accepted partially) or RJCT (rejected).

2) The messages have fields that change automatically, such as generated identifiers and timestamps, which might cause problems for repeated test runs (identifiers might be rejected as duplicates, or timestamps might become too old in a few months and get rejected as invalid).

3) The tests are too broad and brittle. They are testing too many things, such as field mappings in payment request and response, customer balance updates, conditions for message acceptance or rejection and so on. The tests might start failing for too many reasons, and it will be difficult to pinpoint problems.

Your challenge for the next two weeks is to propose ways to clean up this mess, while keeping solid test coverage, and being able to introduce further examples easily. This challenge round will last two weeks. Send your proposals by Monday 10th August, or perhaps post a short blog post or article on your web site and just submit the link to that.

We would also love to get your feedback on the whole Given-When-Then with Style challenge series so far. Please take a few minutes to fill in a very short feedback form.

Stay up to date with all the tips and tricks and follow SpecFlow on Twitter or LinkedIn.

PS: … and don’t forget to share the challenge with your friends and team members by clicking on one of the social icons below 👇