1. Setup und "Hallo, Welt!"

TODO

2. Schnick-Schnack-Schnuck

Entfällt demnächst Wir wollen zunächst ein ganz rudimentäres Kommandozeilen-Programm schreiben, mit dem man gegen den Computer Schnick-Schnack-Schnuck spielen kann.

2.1. Iteration 1

Wir wollen ein minimal nützliches Programm erstellen. Das könnte z.Bsp. folgende Funktionen haben:

  • Der Benutzer gibt Stein, Schere oder Papier in der Kommandozeile ein

  • Der Computer wählt eine hart-kodierte Antwort aus, z.Bsp. wählt er stets Schere.

  • Das Programm gibt den Sieger der Runde auf dem Bildschirm aus.

3. Der Mehrwertsteuer-Rechner

Wir wollen ein Programm schreiben, welches zu einem Betrag den Nettobetrag ermittelt, also den Betrag zuzüglich der aktuell in Deutschland geltenden Mehrwersteuer von 19%.

Ziel dieser Übung ist es, den Aufbau eines COBOL-Programms Programmaufbau kennenzulernen und erste Erfahrungen mit dem Testframework zu machen.

Gehen wir Schritt-für-Schritt vor:

Zunächst stellen wir sicher, dass wir in unserem Ausgangsverzeichnis sind:

pwd
/vagrant/cobol

Nun wechseln wir ins Verzeichnis mehrwertsteuer:

cd mehrwertsteuer

In diesem Verzeichnis finden wir diverse Artefakte:

.
├── run-ut.sh             (1)
├── src
│   └── MWST.cbl          (2)
└── test
    ├── MWSTT.CBL         (3)
    ├── resources
    │   └── MWSTC
1 Mit diesem Skript können wir unsere Testfälle ausführen.
2 Im src-Ordner befindet sich der Programmrumpf MWST.cbl, der später die Programmlogik enthalten wird.
3 Im Verzeichnis test liegen unsere Testfälle für das Programm MWST.cbl.

Öffnen wir nun die Datei test/MWSTT.cbl mit einem beliebigen Text-Editor. Diese Datei enthält alle unsere Testfälle und wir nennen sie unsere Testsuite. Entsprechend beginnen wir die Datei mit folgender Zeile:

           TESTSUITE 'Testfälle für den Mehrwertsteuer-Rechner'

Die Testsuite enthält COBOL-Code, das Schlüsselwort TESTSUITE beginnt also auf Spalte 12. Wer sich bisher noch nicht über das Format einer COBOL-Datei informiert hat, sollte das nachholen.

Schreiben wir dazu zunächst einen Testfall. Wie sähe der einfachste Testfall für den Mehrwertsteuer-Rechner aus? Nun, der einfachste Fall ist:

Nettobetrag(0€) = 0€

Mit Hilfe von cobol-unit-test können wir das in COBOL so formulieren:

           TESTSUITE 'Testfälle für den Mehrwertsteuer-Rechner'

           TESTCASE '0EUR zzgl. 19% MWST sind 0EUR' (1)
           MOVE 0 TO NETTO-BETRAG                   (2)
           PERFORM CALCULATE-MWST                   (3)
           EXPECT BRUTTO-BETRAG TO BE NUMERIC ZERO  (4)
1 Wir geben unserem aktuellen Testfall eine passende Beschreibung
2 Die Eingabedaten für unseren Testfall werden gesetzt
3 Aufruf der Mehrwersteuer-Berechnung
4 Überprüfung des Ergebnis

Gut, nun haben wir schon einen ersten Testfall. Schauen wir uns jetzt den vorbereiteten Programmrumpf MWST.cbl im src-Verzeichnis an:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MWST.
       ENVIRONMENT DIVISION.
       DATA DIVISION.

       WORKING-STORAGE SECTION.
        01  NETTO-BETRAG           PIC 999V99.
        01  BRUTTO-BETRAG          PIC 999.99.
        01  MWST                   PIC V999 VALUE .19.

       PROCEDURE DIVISION.
        GOBACK
           .

       END PROGRAM MWST.

Nun führen wir einmal den Testfall aus und gucken was passiert. Es könnte ja sein, dass das Programm tatsächlich schon genug macht, um unseren Testfall zu bestehen:

. run-ut.sh
==================================================
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT
/vagrant/cobol/mehrwertsteuer/test/TESTPRG.cbl:25: error: 'CALCULATE-MWST' is not defined
Compile nicht erfolgreich!
/vagrant/cobol-unit-test/run-ut: line 53: /vagrant/cobol/mehrwertsteuer/target/TESTPRG: No such file or directory

Ok, schade, das reicht scheinbar noch nicht. Aber es ist ja logisch, denn im Testfall rufen wir ja die SECTION CALCULATE-MWST auf:

           TESTSUITE 'Testfälle für den Mehrwertsteuer-Rechner'

           TESTCASE '0EUR zzgl. 19% MwSt sind 0EUR'
           MOVE 0 TO NETTO-BETRAG
           PERFORM CALCULATE-MWST (1)
           EXPECT BRUTTO-BETRAG TO BE NUMERIC ZERO
1 Hier wird die SECTION CALCULATE-MWST aufgerufen - welche es noch gar nicht gibt.

Implementieren wir nun die fehlende SECTION und rufen sie auf:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MWST.
       ENVIRONMENT DIVISION.
       DATA DIVISION.

       WORKING-STORAGE SECTION.
        01  NETTO-BETRAG           PIC 999V99.
        01  BRUTTO-BETRAG          PIC 999.99.
        01  MWST                   PIC V999 VALUE .19.

       PROCEDURE DIVISION.
        PERFORM CALCULATE-MWST (1)
        GOBACK
           .
       CALCULATE-MWST SECTION. (2)
      *    Noch nicht implementiert  (3)
           .
       1000Z.
           EXIT.

       END PROGRAM MWST.
1 Hier wird die SECTION CALCULATE-MWST aufgerufen
2 An dieser Stelle beginnt die SECTION CALCULATE-MWST
3 Hier käme nun die Implementierung.

Reicht das vielleicht schon, um den ersten Testfall zu bestehen? Probieren wir es aus:

. run-ut.sh
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT

TEST SUITE:
UNIT TESTS MWST.CBL

     PASS:   1. 0EUR zzgl 19% MwSt sind 0EUR

  1 TEST CASES WERE EXECUTED
  1 PASSED
  0 FAILED

Gut, wir haben noch keine spezielle Logik für die Mehrwertsteuerberechnung geschrieben, aber der erste Testfall ist bereits in Ordnung. Schreiben wir also den nächsten: 100€ zzgl. 19% MwSt sollen 119€ sein:

           TESTSUITE 'Testfälle für den Mehrwertsteuer-Rechner'

           TESTCASE '0EUR zzgl. 19% MwSt sind 0EUR' (1)
           MOVE 0 TO NETTO-BETRAG
           PERFORM CALCULATE-MwSt
           EXPECT BRUTTO-BETRAG TO BE NUMERIC ZERO

           TESTCASE '100EUR zzgl 19% MwSt sind 119EUR' (2)
           MOVE 100 TO NETTO-BETRAG
           PERFORM CALCULATE-MwSt
           EXPECT BRUTTO-BETRAG TO BE NUMERIC 119
1 Den alten Testfall lassen wir stehen, damit wir sicher sein können, dass er auch weiterhin funktioniert, wenn wir Änderungen am Programm vornehmen.
2 Unser neuer Testfall für 100€.

Führen wir die Testfälle jetzt aus, bekommen wir folgendes Ergebnis:

. run-ut.sh
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT

TEST SUITE:
Testfälle für den Mehrwertsteuer-Rechner

     PASS:   1. 0EUR zzgl 19% MwSt sind 0EUR
**** FAIL:   2. 100EUR zzgl 19% MwSt sind 119EUR
    EXPECTED 0000011900+, WAS 0000000000+

  2 TEST CASES WERE EXECUTED
  1 PASSED
  1 FAILED

Klar. Jetzt kommen wir nicht mehr drum herum und müssen uns mit der Mehrwertsteuer-Logik auseinander setzen. Wir wollen also die Formel Bruttobetrag = Nettobetrag * (1 + MwSt) anwenden. Mit dem COMPUTE-Befehl geht das in COBOL wunderbar einfach:

COMPUTE BRUTTO-BETRAG = NETTO-BETRAG * (1 + MWST)

Das Programm sieht dann aktuell so aus:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MWST.
       ENVIRONMENT DIVISION.
       DATA DIVISION.

       WORKING-STORAGE SECTION.
        01  NETTO-BETRAG           PIC 999V99.
        01  BRUTTO-BETRAG          PIC 999.99.
        01  MWST                   PIC V999 VALUE .19.

       PROCEDURE DIVISION.
           PERFORM CALCULATE-MWST
           GOBACK
           .
       CALCULATE-MWST SECTION.
           COMPUTE BRUTTO-BETRAG
                 = NETTO-BETRAG * (1 + MWST)
           .
           EXIT.

       END PROGRAM MWST.

Überprüfen wir unsere Implementierung nun, indem wir die Testfälle ausführen:

. run-ut.sh
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT

TEST SUITE:
Testfälle für den Mehrwertsteuer-Rechner

     PASS:   1. 0EUR zzgl 19% MwSt sind 0EUR
     PASS:   2. 100EUR zzgl 19% MwSt sind 119EUR

  2 TEST CASES WERE EXECUTED
  2 PASSED
  0 FAILED

Scheint funktioniert zu haben. Sind wir jetzt fertig? Schauen wir uns mal an, was der Bruttobetrag von 1,99€ wäre. Laut unser Formel wäre 1,99€ * (1 + 0,19)= 2,3681€. Kaufmännisch gerundet ergibt das 2,37€. Schreiben wir einen Testfall dafür:

      *    Die anderen Testfälle werden aus Platzgründen hier ausgelassen
           TESTCASE '1,99EUR zzgl 19% MwSt sind 2,37EUR'
           MOVE 1.99 TO NETTO-BETRAG
           PERFORM CALCULATE-MWST
           EXPECT BRUTTO-BETRAG TO BE NUMERIC 2.37

Lassen wir unsere Testsuite nun laufen, erhalten wir:

. run-ut.sh
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT

TEST SUITE:
Testfälle für den Mehrwertsteuer-Rechner

     PASS:   1. 0EUR zzgl 19% MwSt sind 0EUR
     PASS:   2. 100EUR zzgl 19% MwSt sind 119EUR
**** FAIL:   3. 1,99EUR zzgl 19% MwSt sind 2,37EUR
    EXPECTED 0000000237+, WAS 0000000236+ (1)

  3 TEST CASES WERE EXECUTED
  2 PASSED
  1 FAILED
1 Erwartetes Ergebnis und tatsächliches Ergebnis unterscheiden sich um 1 Cent.

Wir müssen dem Compiler also noch sagen, dass er das berechnete Ergebnis kaufmännisch runden soll:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MWST.
       ENVIRONMENT DIVISION.
       DATA DIVISION.

       WORKING-STORAGE SECTION.
        01  NETTO-BETRAG           PIC 999V99.
        01  BRUTTO-BETRAG          PIC 999.99.
        01  MWST                   PIC V999 VALUE .19.

       PROCEDURE DIVISION.
           PERFORM CALCULATE-MWST
           GOBACK
           .
       CALCULATE-MWST SECTION.
           COMPUTE BRUTTO-BETRAG ROUNDED (1)
                 = NETTO-BETRAG * (1 + MWST)
           .
           EXIT.

       END PROGRAM MWST.
1 Der COMPUTE-Befehl erlaubt es bei allen Zielfeldern den Rundungsmodus anzugeben.

Mit dieser kleinen Änderung können wir unsere Testsuite nochmals ausführen:

. run-ut.sh
Running: /vagrant/cobol-unit-test/run-ut MWSTC MWST MWSTT

TEST SUITE:
Testfälle für den Mehrwertsteuer-Rechner

     PASS:   1. 0EUR zzgl 19% MwSt sind 0EUR
     PASS:   2. 100EUR zzgl 19% MwSt sind 119EUR
     PASS:   3. 1,99EUR zzgl 19% MwSt sind 2,37EUR

  3 TEST CASES WERE EXECUTED
  3 PASSED
  0 FAILED

Damit ist unser kleines Beispielprogramm nun vollständig implementiert.