COBOL2002 使用の手引 操作編


2.2.7 プログラムの単体テスト

テストデバッガには,主,副プログラムシミュレーション機能,ファイルシミュレーション機能,DCシミュレーション機能などの単体テスト機能があります。単体テスト機能を使用すると,プログラムやファイルなどの実行環境が整わない段階でも,作成したプログラムを単体でテストできます。

テストデバッガでは,プログラムの単体テストをするために,次のシミュレーションをする機能があります。

〈この項の構成〉

(1) 主プログラムシミュレーション

SIMULATE MAINコマンドで,ソース要素を呼び出す主プログラムをシミュレーションします。ソース要素に渡す引数に,TDコマンドで値を設定するなどの操作ができます。呼び出されるソース要素は,プログラム定義です。

SIMULATE MAINコマンドの詳細については,「5.4 TDコマンドの詳細」の「5.4.19 SIMULATE MAIN(主プログラムシミュレーションの設定)」を参照してください。

主プログラムシミュレーションをする手順を次に示します。

  1. -SimMainコンパイラオプションを指定して,プログラムをコンパイルする。

  2. テストデバッガを起動する。

  3. テストデバッグ対象のソース要素を開始するときに必要な設定をSIMULATE MAINコマンドで設定する。テストデバッグ対象のソース要素に渡す引数に値の設定ができる。

  4. プログラムを実行して,テストデバッグの操作を開始する。

注意事項

SIMULATE MAINコマンドで入口名を指定したとき,テストデバッグ対象プログラム中にSIMULATE MAINコマンドで指定したプログラム名と同じ名前の別のプログラムがある場合,別のプログラムにも同じ入口名が指定されたENTRY文が必要です。同じ入口名を持つENTRY文がない場合は,エラーメッセージを出力して,主プログラムシミュレーションは設定されません。

主プログラムシミュレーションを設定する場合は,同じ名前を持ち,主プログラムシミュレーションの対象としないプログラムを次のどちらかの方法でデバッグ対象から外してください。

  1. 主プログラムシミュレーションの対象としないプログラムは-TDInfコンパイラオプションを付けないでコンパイルしてください。

  2. 主プログラムシミュレーションの対象としないプログラムが属する共用ライブラリを,-Libraryオプションで指定しないでください。

主プログラムシミュレーションの使用例を次に示します。

使用例1

プログラムSUB01の開始時に,データ名PARAM01・PARAM02に値を設定します。

SIMULATE MAIN( #PROG( SUB01 ) ) 
  ASSIGN DATA( PARAM01 ) VALUE( 1 ) 
  ASSIGN DATA( PARAM02 ) VALUE(100) 
ENDSIMULATE  
GO   *>プログラムの実行を開始する。
使用例2

ENTRY文 'ENTRYSUB'からプログラムの実行を開始します。

SIMULATE  MAIN( #PROG( SUB02 ) 'ENTRYSUB' ) 
  ASSIGN DATA( PARAM01 ) VALUE( 2 ) 
ENDSIMULATE
GO   *>プログラムの実行を開始する。

(2) 副プログラムシミュレーション

SIMULATE SUBコマンドで,テストデバッグ対象のソース要素が呼び出す副プログラムのインタフェースをTDコマンドでシミュレーションします。副プログラムに渡される引数の値を表示して確認したり,副プログラムが値を返す引数に値を設定したりできます。シミュレーションする副プログラムのソース要素は,プログラム定義です。

SIMULATE SUBコマンドの詳細については,「5.4 TDコマンドの詳細」の「5.4.20 SIMULATE SUB(副プログラムシミュレーションの設定)」を参照してください。

副プログラムシミュレーションをする手順を次に示します。

  1. 呼び出す副プログラムがない場合は,次のコンパイラオプションを指定してコンパイルする。

    ・-SimSubコンパイラオプションで呼び出すプログラム名を指定する。

    ・一意名指定のCALL文によって副プログラムを呼び出す場合は,-SimIdentコンパイラオプションおよび-DynamicLinkコンパイラオプションを指定する。

  2. テストデバッガを起動する。

  3. 副プログラムがする処理をSIMULATE SUBコマンドで設定する。副プログラムが,引数やRETURNINGで返すデータ項目に値の設定ができる。

  4. プログラムを実行して,テストデバッグの操作を開始する。

呼び出す副プログラムのソース要素がある場合は,-SimSubコンパイラオプションを指定してコンパイルする必要はありません。存在する副プログラムの処理を,SIMULATE SUBコマンドの設定によって,TDコマンドの処理に置き換えて実行させることができます。

CALL文の引数とRETURNINGのデータ項目は,記号名を割り当ててシミュレーションの手続きで参照できます。複数のCALL文で異なるデータ名の引数やRETURNINGが指定されている場合でも,記号名を割り当てることで,同一の名称によって,シミュレーションの手続きで参照できます。

副プログラムシミュレーションの実行回数を,カウンタ変数によってカウントし,参照できます。

注意事項
  • 再帰属性の付いたプログラムが自プログラムを呼び出している場合,そのプログラム中に中断している状態で,自プログラムに対しての副プログラムシミュレーションは設定できません。

  • SIMULATE SUBコマンドのTDコマンド群中に書かれたASSIGN DATAコマンドによって,特殊レジスタRETURN-CODEに設定した値は,シミュレーション対象の副プログラムにRETURNING指定がない場合だけ,副プログラムを呼び出すプログラムのRETURN-CODEに戻されます。

  • ソース要素がある副プログラムにシミュレーションを設定しても,呼び出すプログラムと副プログラムの間の引数および返却項目に矛盾があると,COBOLプログラムが異常終了します。異常終了を避けるためには,環境変数CBLPRMCHKWを設定してください。

副プログラムシミュレーションの使用例を次に示します。

使用例1

プログラムPROG1をシミュレーションします。

引数X,Yに記号名A,Bを対応させます。

COBOLプログラム
  • データ定義

 01 X  PIC X(10).
 01 Y.
     02 Y1  PIC X(10).
     02 Y2  PIC X(10).
 01 RTN.
     02 R-NAME.
        03 N-DATA  PIC X(10).
呼び出し文
 CALL  'PROG1'  USING  X,Y  RETURNING  RTN.
  • TDコマンド

  SIMULATE SUB( #PROGRAM(PROG1) )  USING(A,B)  RETURNING(R)
    DEFINE
      01 A
      01 B
        02 B1
        02 B2
      01 R
        02 R1 
          03 R11
    ENDDEFINE
    IF CONDITION(A=1) 
      ASSIGN DATA( B1 )  VALUE('APPLE') 
      ASSIGN DATA( B2 )  VALUE ('PANDA') 
      ASSIGN DATA( R11 )  VALUE ('NORMAL') 
    ELSE
      DISPLAY  DATA ( A )
      ASSIGN DATA( R11 )  VALUE ('ABNORMAL') 
    ENDIF
  ENDSIMULATE

(3) ファイルシミュレーション

SIMULATE FILEコマンドで,プログラムから入出力するファイルがないときに,入出力文によるインタフェースをシミュレーションできます。

SIMULATE FILEコマンドの詳細については,「5.4 TDコマンドの詳細」の「5.4.21 SIMULATE FILE(ファイルシミュレーションの設定)」を参照してください。

(a) ファイル入出力文のシミュレーション

入力文のシミュレーションでは,ファイルのレコード領域への値の設定ができます。出力文のシミュレーションでは,レコード領域の内容を表示できます。また,入出力文で,擬似的に入出力条件を発生させることができます。

ファイルシミュレーションは,ファイル結合子とオープンモード(INPUT,OUTPUT,I-O,EXTEND)の単位に,シミュレーションでする手続きを指定します。さらに,入出力文ごとに手続きを指定できます。

ファイルシミュレーションの実行回数を,カウンタ変数によってカウントし,参照できます。

注意事項
  • ファイルシミュレーションは,実体ファイルが割り当てられているときでも指定できます。シミュレーションの手続きが実行されると,実体ファイルへのアクセスは行われません。

  • INTOの指定があるREAD文は,シミュレーションの手続きの実行後に,READ文によるデータが転記されます。レコード領域に代入した値が書き換えられるため,注意が必要です。

  • SORT文,MERGE文のUSING指定,GIVING指定で指定するファイルは,READ文,WRITE文としてシミュレーション対象となります。ただし,USING指定に指定されたファイルはGO ENDコマンドを指定しないかぎりシミュレーションが終わりません。

  • ファイルシミュレーションは,シミュレーションを設定したあとのOPEN文で開始します。ファイルをOPENしたあとにファイルシミュレーションを指定した場合は,ファイルがCLOSEされたあと,再度,OPEN文が実行されたときにシミュレーションは開始します。

  • ファイルシミュレーションの設定と,ファイル名とオープンモードが合致するOPEN文で,ファイルシミュレーションは開始します。EXTERNAL句指定のあるファイルでは,同じシミュレーション手続きが実行されます。EXTERNAL句指定がないファイルでは,ファイルごとに別のシミュレーション手続きが実行されます。

  • シミュレーションが設定されているファイルに対して,再度シミュレーションを設定した場合は,設定されていたTDコマンド群を置き換えます。このとき,カウンタ変数およびREPEAT回数は初期値に戻ります。

  • EXTERNAL句指定のファイルのシミュレーションでは,OPEN文と入出力文が記述された翻訳単位の両方を-TDInfコンパイラオプションでコンパイルします。OPEN文または入出力文のどちらか記述された翻訳単位が-TDInfコンパイラオプションでコンパイルされていないときは,シミュレーションをしません。

使用例1

カウンタ変数を使用して,カウンタ変数の値ごとにレコードの値を設定できます。

SET QUALIFICATION( #PROG( 社員/社員 ) )
 SIMULATE FILE( 給与ファイル ) OPENMODE( IO ) COUNTER(CNT)
   IF CONDITION(CNT = 1) 
      ASSIGN DATA(基本給) VALUE(100000)
   ENDIF
   IF CONDITION(CNT=2) 
      ASSIGN DATA(基本給) VALUE(101000)
   ENDIF
   IF CONDITION(CNT=3) 
      ASSIGN DATA(基本給) VALUE(104000)
   ENDIF
 ENDSIMULATE

同じレコードの値を連続して設定する場合は,反復回数指定を使用できます。

使用例2

繰り返し指定を使用して,同じレコードの値を連続して設定できます。

 SET QUALIFICATION( #PROG( 社員/社員 ) )
 SIMULATE FILE( 給与ファイル ) OPENMODE(IO)
   REPEAT  TIMES(2)
      ASSIGN DATA(基本給) VALUE(100000)
   ENDREPEAT
   REPEAT 
      ASSIGN DATA(基本給) VALUE(101000)
   ENDREPEAT
   REPEAT  TIMES(3)
      ASSIGN DATA(基本給) VALUE(104000)
   ENDREPEAT
 ENDSIMULATE

繰り返し指定(REPEAT)は,指定された反復回数(TIMES)の回数分を入出力文に対して実行します。指定した反復回数分の実行が終了すると,次の繰り返し指定に移ります。

  • 反復回数を省略した場合は,TIMES(1)が仮定されます。

  • 繰り返し指定が終了しても,まだ,入出力文が現れた場合は,最後の繰り返し指定が実行されます。

OPEN文のオープンモードがI-Oの場合の入出力文は,複数あります。この場合は入出力文単位にレコード値を設定できる入出力文選択指定を使用すると便利です。

使用例3

入出力文を指定します。

 SET QUALIFICATION( #PROG( 社員/社員 ) )
 SIMULATE FILE( 給与ファイル )  
     OPENMODE(IO)
   SELECT ACTION(DELETE)
      REPEAT TIMES(2)
        DISPLAY DATA(名前)
      ENDREPEAT
   ENDSELECT
   SELECT ACTION(READ)
      REPEAT
        ASSIGN DATA(基本給) VALUE(104000)
      ENDREPEAT
      REPEAT TIMES(3)
        ASSIGN DATA(基本給) VALUE(108000)
    ENDREPEAT
 ENDSELECT
 ENDSIMULATE

文種別単位に処理を繰り返すことができます。文種別指定はSELECTを使用して指定します。

  • SELECT指定のない入出力文で制御が渡った場合,この入出力文に対してはコマンドが実行されません。例えば上の例のようにシミュレーション手続きを実行した場合,START文の文種別指定がないのでシミュレーションが実行されないでCOBOLプログラムが続行します。

  • 各文種別単位に反復回数がなくなったときは,使用例2のように最後のREPEATを繰り返します。

  • 同じSELECT指定が現れた場合は,繰り返し(REPEAT)が設定順に追加されます。

(b) 入出力条件のシミュレーション

ファイルシミュレーションの手続き中で,次の入出力条件を擬似的に発生させることができます。

表2‒3 シミュレーション対象入出力条件

コマンド

シミュレーション対象入出力条件

入出力文

GO END

ファイル終了条件

(END OF FILE)

READ

GO EOP

ページ終了条件

(END OF PAGE)

WRITE

GO INVALID

無効キー条件

(INVALID KEY)

READ,WRITE,REWRITE,

START,DELETE

GO ERROR

入出力誤り

READ,WRITE,REWRITE,

START,DELETE

(c) 論理誤りチェックと入出力状態の値

ファイルシミュレーションの手続きで,入出力状態の値(FILE STATUS句で指定されたデータ名の値)に任意の値を設定できます。次の場合は,入出力状態の値にテストデバッガが値を設定します。この場合も,ASSIGN DATAコマンドによって値を変更できます。

ファイルの入出力処理の論理誤りをチェックして,エラーがあった場合,シミュレーションは実行しません。シミュレーション対象ファイルに入出力状態の値(FILE STATUS句で指定されたデータ名の値)の指定があるときは,シミュレーションの終了状態によって「表2‒4 論理誤りチェック条件」の値を入出力状態の値に設定します。

また,シミュレーション手続きによって「表2‒3 シミュレーション対象入出力条件」で示したコマンドが実行されたときは,「表2‒5 論理誤りチェック以外の設定条件」で示した値が設定されます。

シミュレーション手続きで指定がない場合は,「表2‒6 成功完了の設定条件」の成功完了時の入出力状態の値が設定されます。

表2‒4 論理誤りチェック条件

入出力状態の値

内容

41

開かれているファイル結合子に対してOPEN文を実行しようとした。

46

GO ENDコマンド実行後に再度READ文を実行しようとした。

47

入力モード(INPUT)や入出力モード(I-O)で開かれていないファイル結合子に対してREAD文やSTART文を実行しようとした。

48

正しいオープンモードでは開かれていないファイル結合子に対してWRITE文を実行しようとした。順アクセス法の場合,ファイル結合子が出力モード(OUTPUT)や拡張モード(EXTEND)で開かれていない。動的アクセス法や乱アクセス法の場合,ファイル結合子が出力モード(OUTPUT)や入出力モード(I-O)で開かれていない。

49

入出力モード(I-O)で開かれていないファイル結合子に対してREWRITE文やDELETE文を実行しようとした。

表2‒5 論理誤りチェック以外の設定条件

入出力状態の値

内容

10

GO ENDコマンド実行による終了。

23

GO INVALIDコマンド実行による終了(相対ファイル,索引ファイル)。

34

GO INVALIDコマンド実行による終了(順ファイル)。

90

GO ERRORコマンド実行による終了。または,論理誤りが発生した。

表2‒6 成功完了の設定条件

入出力状態の値

内容

00

正常終了。一般のコマンド(入出力状態の値を設定するコマンドは除く)で終了。

07

REEL/UNITのCLOSE文を実行した(CLOSE処理を行わない。OPEN状態を残す)(順ファイル)

注意事項

入出力状態の値は,ファイルシミュレーションが開始されたとき,00に初期化されます。

(4) 記号名

記号名は,次のシミュレーションでデータ項目の名前を置き換えるときに使用します。

記号名で置き換えるデータ項目が集団項目の場合は,DEFINEオペランドによって,基本項目をレベル番号と構造定義で指定できます。基本項目を参照しないなど,必要がないときは,DEFINEオペランドの指定は不要です。

レベル番号の指定については,「5.4 TDコマンドの詳細」の「5.4.26 レベル番号(記号名構造指定)」を参照してください。

注意事項
  • 記号名の構造定義は参照が必要な部分までを記述すればよく,原始プログラムのデータ項目の残りのレベル番号は,指定しなくてもかまいません。ただし,途中の引数,レコード記述項を省略して定義することはできません。

  • 記号名の指定を省略した場合,データ値の表示や,エラーが発生したときのメッセージ中に記号名を表示できません。このため記号名の代わりに「*****」と表示します。記号名の表示が必要なときは,記号名を記述してください。

(例)

A1までが記号名に対応し,A11以降が無視されます。

  • COBOLプログラム

    ・データ定義

    01 A. 
       02 A1.
          03 A11 PIC X(10).
          03 A12 PIC X(10).
       02 A2.
  • ・呼び出し文

    CALL 'SUB1' USING A.
  • TDコマンド

    SIMULATE SUB(#PROGRAM(SUB1)) USING(P)
      DEFINE
        01 P          *>  Aに対応する。
          02 P1       *>  A1に対応する。
      ENDDEFINE
        :
    ENDSIMULATE
  • 記号名の定義は,01から始まらなければなりません。構造が原始プログラムと合っていれば,レベル番号を一致させる必要はありません。

(例)

P1はA1に対応づけられます。

  • COBOLプログラム

    ・データ定義

    01 A.
       02 A1.
          03 A11 PIC X(10).
          03 A12 PIC X(10).
       02 A2 PIC X(10).
  • ・呼び出し文

    CALL 'SUB2' USING A.
  • TDコマンド

    SIMULATE SUB(#PROGRAM(SUB2)) USING(P)
      DEFINE
        01 P          *>  Aに対応する。
          04 P1       *>  A1に対応する。
      ENDDEFINE
        :
    ENDSIMULATE
  • データ項目の数より記号名の数が多いとき,対応するデータ項目のない記号名を使用したTDコマンドは実行できません。

(例)

P2に対応するデータ項目の定義がありません。

  • COBOLプログラム

    ・データ定義

    01 A.
       02 A1 PIC X(10).
  • ・呼び出し文

CALL 'SUB3' USING A.
  • TDコマンド

    SIMULATE SUB(#PROGRAM(SUB3)) USING(P)
      DEFINE
       01 P             *>  Aに対応する。
         02 P1          *>  A1に対応する。
         02 P2          *>  対応するデータ項目がない。
      ENDDEFINE
       :
     DISPLAY DATA(P)     *> 実行される。
     DISPLAY DATA(P1)    *> 実行される。
     DISPLAY DATA(P2)    *> 実行できない。
       :
    ENDSIMULATE
  • 記号名を対応づけるデータ項目にTYPE句またはSAME AS句が指定されているときは,記号名の構造定義には,TYPE句またはSAME AS句によって展開された構造による指定をします。

(例)

P3はA1に,P4はA2に対応づけられます。

  • COBOLプログラム

・データ定義

    01 TYPE1 IS TYPEDEF.
      02 A1  PIC X(1).
      02 A2  PIC X(1).
  
    01 U1.
      02 PRM1  PIC X(1).
      02 PRM2  TYPE TO TYPE1.

・呼び出し文

    CALL 'SUB4' USING U1.
  • TDコマンド

    SIMULATE SUB(#PROGRAM(SUB4)) USING(P)
    DEFINE
    01 P             *>  U1に対応する。
      02 P1          *>  PRM1に対応する。
      02 P2          *>  PRM2(TYPE1)に対応する。
        03 P3        *>  A1に対応する。
        03 P4        *>  A2に対応する。
    ENDDEFINE
 :
ENDSIMULATE
使用例1

副プログラムシミュレーションの引数に記号名を設定します。

COBOLプログラム
  • データ定義

01 X.
  02 X1 OCCURS 5.
    03 X11 PIC X(2).
  02 X2 PIC X(2).
01 Y  PIC 9.
01 RTN.
  02 R OCCURS 5 PIC X(10).
  • 呼び出し文

CALL  'PROG1'  USING  X,X11(2),Y   RETURNING  R(1).
 
  • TDコマンド

SIMULATE SUB(#PROGRAM(PROG1)) USING(A,B,C)  RETURNING(R)
  DEFINE
     01 A               *>  Xに対応する。
      02 A1             *>  X1に対応する。
       03 A11           *>  X11に対応する。
      02 A2             *>  X2に対応する。
  ENDDEFINE
  IF CONDITION( C=1 ) 
    ASSIGN DATA(A11(1)) VALUE('OK')
    ASSIGN DATA(R) VALUE('normal')
  ELSE
    ASSIGN DATA(B) VALUE('NG')
    ASSIGN DATA(R) VALUE('abnormal')
  ENDIF
ENDSIMULATE
使用例2

ファイルシミュレーションのレコードに記号名を設定します。

  • COBOLプログラム

 FD 給与ファイル DATA RECORD IS 形式1.
 01 形式1.
  02 社員コード PIC X(9).
  02 氏名.
   03 名字  PIC N(10).
   03 名前  PIC N(10).
 01 形式2.
  02 契約コード.
   03 種別 PIC X(9).
   03 コード PIC X(40).
 01 形式3 PIC X(49).
  • TDコマンド

 SIMULATE FILE(給与ファイル)  OPENMODE(IO)  RECORD(A,B,C)
   DEFINE 
     01 A
      02 A1
      02 A2
       03 A21
       03 A22  
     01 B
      02 B1
       03 B11
       03 B12
   ENDDEFINE
      :
 ENDSIMULATE 
使用例3

ファイルシミュレーションのレコードに記号名を設定します。

  • COBOLプログラム

 FD 給与ファイル.
 01 形式1.
  02 社員コード PIC 9(8).
  02 氏名.
    03 名字 PIC X(30).
    03 名前 PIC X(30).
 01 形式2.
  02 契約コード.
    03 種別 PIC 99.
    03 コード PIC 9(4).
 01 形式3 PIC X(80).
 01 形式4 PIC X.
  • TDコマンド

 SIMULATE FILE(給与ファイル) OPENMODE(IO) RECORD(A,B,C)
    DISPLAY DATA(B)
   :
 ENDSIMULATE

RECORD指定で対応づけをします。上の例の場合,形式1がA,形式2がB,形式3がCに対応します。対応づけた記号化名称をコマンド中でデータの代わりに使用できます。

  • B指定だけを省略するなど,途中の省略はできません。後ろは省略できます。

  • レコードが構造定義のとき,構造内を参照するためにDEFINE〜ENDDEFINEを使用して記号名を定義できます。

(5) DCシミュレーション

SIMULATE DCコマンドによって,次のDC文をシミュレーションします。DC文を使用したOpenTP1のインタフェースをシミュレーションすることもできます。SIMULATE DCコマンドの詳細については,「5.4 TDコマンドの詳細」の「5.4.24 SIMULATE DC(DCシミュレーションの設定)」を参照してください。

対象とするDC文の種別と通信記述名を指定して,シミュレーションで実行する手続きをTDコマンドで記述します。手続きでは,メッセージファイル領域の参照,値の設定ができます。また,状態コード(STATUS KEY句で指定したデータ項目)に対して,値を設定できます。

DCシミュレーションの実行回数を,カウンタ変数によってカウントし,参照することもできます。

注意事項

DCシミュレーションは,プログラムの実行開始前でも実行中でも指定できます。DCシミュレーション手続き設定後のDC文からシミュレーションが実行されます。

使用例1

DISABLE文のシミュレーションをします。

SIMULATE DC( DISABLE )  CDNAME(CD1)
  ASSIGN DATA( STATUS-KEY ) VALUE( 1 )
ENDSIMULATE
使用例2

COMMIT文のシミュレーションをします。

SIMULATE  DC( COMMIT )
  ASSIGN DATA( STATUS-KEY ) VALUE( 2 )
ENDSIMULATE