AI for QA with Python and ZOAU for the Seasoned Professional
July 15, 2026 Posted By: John Hogan 3 min read
I've recently started to use AI in my day-to-day work. Initially being a 'seasoned professional' - or just someone who has been working with mainframes for 45 years - I thought I'd skip the whole AI thing and keep doing what I've been doing. That certainly would have been a mistake. Additionally, if during my first use of AI I had only focused on the errors and what it did not do correctly, that would have been an even worse mistake. Over a very short period, AI has changed the way I work and I'm able to contribute at a higher level.
The QA Task
One of the teams I work with needed some additional help with QA and I know I had some good test cases buried in a PDSE with over 2000 members and a history going back to 1991. I figured that this PDSE might be a treasure trove of examples and all I had to do was look through all the members to find the cases that fit the requirements. The requirements were as follows:
- Find all the members in the PDSE that meet the requirements for my QA test and copy those members into another existing PDSE
- Add some JCL statements in front of the members in the new PDSE to set up the QA test
- Finally, submit and monitor the QA jobs
Traditional aka Seasoned Pro Method
I could have used multiple 3.14 ISPF searches, created lists of potential members, looked at each one to decide if it met my testing criteria, copied qualifying members to another PDSE, added the required JCL, and then submitted and monitored all the jobs myself — but that would have taken me all week. Instead, I decided to use AI to help me write Python programs using ZOAU to automate the whole process. After a few iterations — where I learned I needed to describe my requirements more precisely and make sure the AI was targeting the most recent ZOAU release — I had three programs that got the job done. I've uploaded those Python/ZOAU programs to my GitHub for anyone interested.
The Python/ZOAU Programs
Script 1: pds_keyword_scan.py - Member Selection
This script does the heavy lifting of scanning every member of the input PDSE for the criteria that qualify it as a useful test case. A member has to satisfy two conditions simultaneously: a two-keyword sequence where the first keyword appears before the second (either on the same line or within two lines of it), and a specific program name on a non-comment EXEC statement anywhere in the member. Members that pass both tests are written to the output PDSE under their original name. The prompt was simply a plain-English description of the requirements, and out of 2000+ members I found more than 100 that were a good match.
Script 2: pds_prepend_header.py - Adding the JCL Job Cards
Once I had the qualifying members collected, this script reads each one and builds a new version by prepending a five-line JCL job card and appending a delimiter record at the bottom. The job name is constructed from a configurable prefix plus a zero-padded three-digit sequence number, so the output members come out named JOB001, JOB002, and so on. A JCL comment on the second header line carries the original member name for traceability. All output records are written at exactly 80 bytes, space-padded, with no newlines — consistent with z/OS FB conventions. Initially the Python code was producing lines with embedded newline characters. I had to instruct the AI to produce proper z/OS fixed 80-byte records instead.
Script 3: pds_submit_j_members.py - Submit and Monitor
The final script reads all members whose names begin with J - exactly what script 2 produced - and submits each one as a batch job. It then waits for each job to complete using the ZOAU Job.wait() and Job.refresh() API calls, writes the condition code, member name, and JES job number to STDOUT, and if any job ends with CC greater than zero, captures the complete spool output to a USS file for review. The final summary clearly separates the jobs that passed at CC=0 from those that need attention.
Working with AI and Python/ZOAU
I learned a couple of lessons along the way. One thing I had to let go of was wanting to save the code in EBCDIC rather than UTF-8. I spent quite a bit of time trying to save it in EBCDIC and removing UTF-8 characters that would not translate correctly, only to realize my Python default on z/OS was UTF-8 and keeping it in UTF-8 was much easier than defining encoding in the program. I use z/OS Unix System Services files to store the Python/ZOAU code with the EDIT UTF-8 option in ISPF.
I also ran into a situation where an older release of the ZOAU Python interfaces for job submission and status checking was being used by my AI. I had to instruct it to use the newer ZOAU and ask it to remember that for future projects. Even with these minor glitches, using AI was much faster than trying to do it manually or coding it myself.
Overall, I think generative AI in the workplace will allow me to contribute to the teams I work on at a higher level - leveraging my many years of z/OS experience while leaning on AI to help me navigate through some of the newer tools available on z/OS. The task that would have taken me all week was done in a fraction of the time, and the programs are reusable for the next round of QA. So, you can teach a 'seasoned professional' new tricks, as long as they have an open mind.
The three Python/ZOAU scripts are available at https://github.com/Johnh-21CS/Python-ZOAU-for-QA. The environment setup requires ZOAU_HOME, PYTHONPATH, and LIBPATH to be set correctly in USS, and the target output PDSE must be pre-allocated with RECFM=FB,LRECL=80 before running any of the scripts. These were tested on z/OS 2.5 with ZOAU 1.3.