我が身を守る「テストコード」

C言語でプログラムを開発する場合(C言語に限った話ではないのだが)、テストコードは自身を守ることにつながる。テストコードは、将来に発生するエンバグを未然に発見したり、ほかのプラットフォームに移植する際に互換性を保証してくれたりする力強い味方である。

例えば、機能追加や機能変更などに対応するためにコードの書き換えを行ったとき、既存のコードと挙動が変わってしまうことがある。網羅性の高いテストコードがあれば、変更後にテストを実行し、その変更に問題があることがわかる。テストコードがないと、いつこの問題が発覚するかわからず、将来に爆弾を託すことになる。

また、「IntelからARMプラットフォームにソフトウェアを移植する」「WindowsからLinuxへ移植するなど、移植先で本当に正しく動いているかどうかを確認できる点も、質の高いテストコードを持っているかどうかで負担が大きく変わってくる。

開発が進んで手がつけられなくなる前に、テストコードを書くことに手を出すのは悪くない選択肢だ。

まずはスクリプトで試す

テストコードの書き方はいろいろあって、需要に応じて適切な技術を採用する必要がある。会社がすでに定めているテストコードフレームワークもあるだろうし、オープンソースのテストフレームワークを使っていることあるだろう。

ここでは、最も簡単な方法として、開発したコマンドをスクリプトで実行して動作の可否を判断する方法を取り上げる。今のWindowsはスクリプトとしてPowerShell 7が推奨されている。これはWindows 10にはデフォルトではインストールされていないので、使っていないならWingetを使ってインストールしておこう。

PowerShell 7のインストール方法

winget install PowerShell

または、次のページから手動でパッケージをダウンロードしてインストールしてもよい。

  • PowerShell/PowerShell: PowerShell for every system!

    PowerShell/PowerShell: PowerShell for every system!

PowerShell 7は自動的に環境変数Pathに追加されるが、追加されていなければ「%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\」を環境変数Pathに追加しておこう。Windows TerminalやVisual Studio Codeを再起動すれば環境変数Pathの変更が反映され、pwshというコマンドが使えるようになるはずだ。

PowerShellスクリプトでテストコードを書く

フレームワークを使ったテストコードはいずれとりあげるとして、ここではスクリプトでテストコードを作成するサンプルを取り上げる。テストコードといっても難しいことはなく、プログラムを実行してその結果が正しいか正しくないかを判断するだけだ。

本連載では、csv2tsv.exeという、CSVファイルをTSVデータへ変換するプログラムを開発した。であれば、次のようにcsv2tsv.exeを実行して、その結果が正しいかどうか判断するシンプルなスクリプトを書けばよいだけだ(PowerShellスクリプト)。

test001.ps1

$f = New-TemporaryFile

.\csv2tsv.exe .\data\data.csv > $f

C:\Windows\System32\fc.exe .\data\data.tsv $f > $null

if ($?) {
    echo 'テスト001: 成功'
}
else {
    echo 'テスト001: 失敗'
}

Remove-Item $f

ここでは、あらかじめ2つのデータファイルを用意している。data.csvとdata.tsvだ。data.csvが変換前のCSVファイル、data.tsvが変換後のTSVファイルだ。

data.csv

13101,"1""0""0",,100 0000 
"13101","""102""",,102  0072
13101,"1""02",,102 0082  
13101,"101""""",, 10 10032
13101,"""""101",, 101 0047 
,13101,@,"1""0""0",
,"13101","""102""",@
,13101,"1""02",
@,13101,"101""""",
,13101,"""""101",

data.tsv

13101   1"0"0       100 0000 
13101   "102"       102  0072
13101   1"02        102 0082  
13101   101""        10 10032
13101   ""101        101 0047 
    13101   @   1"0"0   
    13101   "102"   @
    13101   1"02    
@   13101   101""   
    13101   ""101   

csv2tsv.exe data.csvを実行して、その結果がdata.tsvとまったく同じなら、「プログラムは正しく動作している、そう判断するスクリプトを書いた」というわけだ。次のようにスクリプトを実行すると、このコードは正しく動作していることがわかる。

テストコードの実行例

PS C:\Users\daichi\Documents\vscode-csv2tsv> cat .\tests\test001.ps1
$f = New-TemporaryFile

.\csv2tsv.exe .\data\data.csv > $f

C:\Windows\System32\fc.exe .\data\data.tsv $f > $null

if ($?) {
    echo 'テスト001: 成功'
}
else {
    echo 'テスト001: 失敗'
}

Remove-Item $f
PS C:\Users\daichi\Documents\vscode-csv2tsv> .\tests\test001.ps1
テスト001: 成功
PS C:\Users\daichi\Documents\vscode-csv2tsv>

テストスクリプトとテストデータを含めた、ビルド後のファイルの配置は次のようになっている。

ファイル配置

PS C:\Users\daichi\Documents\vscode-csv2tsv> tree
.
├── csv2tsv.exe
├── data
│   ├── data.csv
│   └── data.tsv
├── LICENSE
├── main.c
├── main.h
├── main.o
├── Makefile
├── tests
│   └── test001.ps1
├── util_csv.c
├── util_csv.o
├── util_file.c
└── util_file.o

2 directories, 13 files
PS C:\Users\daichi\Documents\vscode-csv2tsv>

本連載はPowerShellの連載ではないので、PowerShellの詳細は取り上げない。興味がある方は「PowerShell Core入門 - 基本コマンドの使い方」などを参考にしてもらえればと思う。