Testing COBOL
COBOL Check lets you write unit tests in a COBOL-like DSL; it merges tests into a copy of the program and runs it (works with GnuCOBOL locally and on z/OS).
33.1 Levels of testing
Unit (paragraph/program) COBOL Check (Open Mainframe Project), IBM zUnit (IBM Developer for z/OS / IBM Test Accelerator for Z), Rocket Visual COBOL unit testing (MFUnit)
Test JCL streams, CICS test regions, Galasa (open-source integration test framework for z/OS)
Compare outputs of old and new versions (diff; SuperC/ISRSUPC on z/OS); record/replay tools
Repeatable batch runs with production-like volumes
33.2 COBOL Check
COBOL Check lets you write unit tests in a COBOL-like DSL; it merges tests into a copy of the program and runs it (works with GnuCOBOL locally and on z/OS).
Run it with the cobolcheck launcher (e.g., cobolcheck -p TAXCALC), which generates the test program, compiles it, and reports pass/fail. MOCK PARAGRAPH name ... END-MOCK (also for SECTIONs and CALLs) replaces dependencies such as I/O or rate lookups with test behavior.
TestSuite "Tax calculation paragraph 2200-CALC-TAX"
TestCase "Standard rate applies below threshold"
MOVE 1000.00 TO WS-GROSS
MOVE "S" TO WS-TAX-CODE
PERFORM 2200-CALC-TAX
EXPECT WS-TAX TO BE 215.00
TestCase "Exempt customers pay no tax"
MOVE 1000.00 TO WS-GROSS
MOVE "E" TO WS-TAX-CODE
PERFORM 2200-CALC-TAX
EXPECT WS-TAX TO BE 033.3 Designing testable COBOL
Keep business rules in small paragraphs or subprograms with clear inputs/outputs, and isolate I/O in dedicated paragraphs (8000-READ-..., 8100-WRITE-...) so tests can mock them.
Put magic numbers in 88-levels and tables; test boundary values (zero, maximum PICTURE value, negative, empty file, single record, duplicate keys).
Run unit tests automatically in the CI pipeline (Chapter 41).
🧪 Part III Exercises
Split your Part II customer report into a main program and two subprograms (validation and formatting); compile once statically and once with dynamic loading.
Demonstrate the difference between BY REFERENCE, BY CONTENT, and BY VALUE with a subprogram that modifies all three parameters.
Write a nested program structure with a GLOBAL error-count field and a COMMON logging routine called from two sibling programs.
Implement recursive Fibonacci and Towers of Hanoi with RECURSIVE and LOCAL-STORAGE; print the moves for 4 disks.
Create an address copybook and use COPY ... REPLACING to build billing, shipping, and mailing address groups in one record.
Introduce a deliberate subscript-out-of-range bug and a non-numeric data bug; detect them with GnuCOBOL -debug (and, if you have z/OS access, SSRANGE and NUMCHECK).
Generate JSON for an array of three customers (a table with OCCURS) and inspect how COBOL names map to JSON keys; customize the names with NAME OF.
Write an XML PARSE program (IBM or Visual COBOL) that totals the <amount> elements of an invoice document.
Write a user-defined function VALID-ISBN that returns 1 or 0 for a 13-digit ISBN check digit, and call it from a test driver.
Install COBOL Check and write at least five test cases (including one mock) for the tax calculation paragraph of exercise 1.