'Language to describe a data structure

I'm developing a testing tool and I want to generate an easy to read description of the test cases (in Gherkin Syntax).

Here's an example of a description I want to create (sorry for the German):

Gegeben Partner NP_M_IT_VN,
und Vertrag 3bRIS_T
und der Vertrag wurde bis 17.02.2022 fortgeschrieben,
wenn ich eine Prämienreduktion mit Prämie neu CHF 300.00 erfasse,
und ich Stornobekäpnfung "Nicht erfolgreich" wähle,
und ich als nächsten Schritt "Reduktion durchführen" wähle,
dann sollte in ILAS ein GeVo mit Wirksamekeitsdatum 01.02.2022 und Grund "Reduzierung" erstellt worden sein,
wenn ich die Dokumente in OMS abwarte,
dann sollten erstellt worden sein,
und in FS/CD sollte ein Beleg mit Fälligkeitsdatum 01.02.2022 und Betrag CHF 300.00 vorhanden sein.

Tests are stored as JSON strings. The raw data for the example above is:

{
  "skip": false,
  "priority": "Blocker",
  "labels": "Reduktion",
  "assignee": "***",
  "key": "***",
  "summary": "[TEST E2E Prämienreduktion] - Hybrid, Prämienreduktion, ZM monatlich, Prämienrückstand",
  "steps": [
    {
      "schema": "Partner",
      "templateId": "NP_M_IT_VN",
      "data": {
        "Crm": {
          "PartnerNatuerlich": {
            "Geburtsdatum": "1970-01-01"
          }
        }
      }
    },
    {
      "schema": "IlasVertrag",
      "templateId": "3bRIS_T",
      "data": {
        "Produkt": {
          "Antragseinreichungsdatum": "=DATE(YEAR(TODAY()),MONTH(TODAY()),1)",
          "Unterzeichnungsdatum": "=DATE(YEAR(TODAY()),MONTH(TODAY()),1)"
        },
        "Vertragsteile": {
          "Tarif1": {
            "TarifKommentar": "Tod",
            "Beginn": "=TEXT(DATE(YEAR(TODAY()),MONTH(TODAY())-1,1),\"TT.MM.JJJJ\")"
          }
        },
        "PartnerZuordnung1": {
          "Referenz": "1"
        },
        "Beteiligungsgruppe1": {
          "PartnerNr": "21000009",
          "PartnerNr_ACC_INT": "35873466"
        },
        "Pruefung": {
          "Crm": "true"
        },
        "Verschiedenes": {
          "TestDatum": "=TEXT(DATE(YEAR(TODAY()),MONTH(TODAY())-1,0),\"TT.MM.JJJJ\")"
        }
      }
    },
    {
      "schema": "IlasFortschreibung",
      "data": {
        "Wirksamkeitstermin": "=TODAY()",
        "Pruefung": {
          "Ilas": "false",
          "FscdMinSaldo": "500.0"
        }
      }
    },
    {
      "schema": "BpmReduktion",
      "data": {
        "Art": "Prämienreduktion",
        "PraemieNeu": "300",
        "ArtDerAntragseinreichung": "Brief",
        "Stornobekaempfung": "Nicht erfolgreich",
        "NaechsterSchritt": "Reduktion durchführen"
      }
    },
    {
      "schema": "IlasPruefung",
      "data": {
        "Vertragsstand": {
          "WirksamekeitsDatum": "=DATE(YEAR(TODAY()),MONTH(TODAY()),1)",
          "Grund": "Reduzierung",
          "AnzahlPassendeVertragsstaende": "1"
        }
      }
    },
    {
      "schema": "OmsDokumenteAbwarten",
      "data": {
        "AnzahlAuftraege": "1",
        "Min2h": "true"
      }
    },
    {
      "schema": "OmsDokumentePruefung2",
      "data": {}
    },
    {
      "schema": "FscdPruefung",
      "data": {
        "Beleg1": {
          "Faelligkeitsdatum": "=DATE(YEAR(TODAY()),MONTH(TODAY()),1)",
          "Betrag": "300"
        }
      }
    }
  ]
}

For each type of test steps there is a generated Java class. My idea was to produce the description in Java. For instance, the code to describe test step 'BpmReduktion' is:

@Override
public void describe(GherkinData gherkin) throws Exception {
    
    StringBuilder sb = new StringBuilder();
    sb.append("ich eine " + getArt());
    if (getPraemieNeu() != null) {
        sb.append(" mit Prämie neu " + formatAmount("praemieNeu"));
    }
    if (getLeistungNeu() != null) {
        sb.append(" mit Leistung neu ");
        List<String> strings = new ArrayList<String>();
        for (int i = 1; i <= 2; i++) {
            String tarif = (String) getLeistungNeu().getClass().getMethod("getTarif" + i).invoke(getLeistungNeu());
            if (tarif != null) {
                strings.add(formatAmount("leistungNeu.leistung" + i) + " für " + tarif);
            }
        }
        sb.append(kommaUnd(strings));
    }
    if ((getBenutzer() != null) && (getBenutzer().getGA() != null) && getBenutzer().getGA()) {
        sb.append(" als GA");
    }
    gherkin.addWhen(sb.toString() + " erfasse");
    
    gherkin.addWhen("ich Stornobekäpnfung " + quote(getStornobekaempfung()) + " wähle");

    gherkin.addWhen("ich als nächsten Schritt " + quote(getNaechsterSchritt()) + " wähle");
}

But I feel, with this approach I'm going to end up with a lot of arbitrary, hard to maintain Java code. I'm looking for a language where the code is closer to the description being generated, like Thymeleaf, but better suited for human readable text.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source