「さくっ」とテストデータを作るための段取り
1. はじめに
この記事は、開発工程でテストデータを作らないといけない方向けの情報です。
コマンドを使って、さくっとテストデータを作ります。
-
【利用者像】:
- アプリケーション開発の局面で、とにかくテストデータが必要な方
- 実務経験1年未満のエンジニア大多数。要員育成が必要なチームリーダーの方
-
【利用シーン】:
- テスト工程(ITa/ITb)
-
【前提】:
- 正常系・準正常系・異常系の違いがわかっている方が望ましい
2. 出来上がるもの
テスト実施のためのテストデータを作成します。
「たくさん」とは、~10万件レベル、「盛りだくさん」100万件以上とします。(盛りだくさんは、本記事では対象としていません)
対象データ:
- CSV、TXT、SQL、JSON、XML
- YAML、TOML
3. 作り方
3.1. データ作成計画を策定する
テスト仕様書をインプットに、テストの実施条件・期待値から、どういうテストデータが必要なのかを考えます。
計画の際の原則は以下。
- 外部仕様書からテストデータのバリエーションを検討すること
- 仕様書に書かれていないあいまいなことは開発者の課題とし、申し入れをすること(特に、データの相関性、準正常系・異常系の考慮もれが比較的多い)
- テストデータはすべて準備してからテストに取り掛かること
- テストデータは再利用を考慮すること
3.2. テストデータを作る
(1) 【基本編】数値データを作る(可変長・固定長)
$ seq 100
$ seq 10 100
$ seq -s " " -w 050
$ seq -s " " -w 010 100
(2) 【基本編】数値データを作る(乱数:重複あり)
$ for i in {0..10000}; do echo $(($RANDOM % 10000)) ; done
(3) 【基本編】数値データを作る(乱数:重複なし)
$ shuf -i 1-10000 -n 10000
(4) 【基本編】固定長の文字列データを作る
$ cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -10000
:
VrRdKkEI6hVF5Cq9
$ cat /dev/urandom | tr -dc 'A-Z' | fold -w 16 | head -10000
:
DGORYBFCPNJKSJEG
(5)【基本編】UUIDデータをたくさん作る
$ for i in `seq 50000`; do echo `uuidgen`; done | sort | uniq
:
3e25ab69-525a-469e-a8a0-1f16dc061b17
(6) 【基本編】複数カラムのデータをたくさん作る
BEGIN {
maxNumber=100000; # 10万件
srand();
printf("#seq, uid, point\n"); # CSVヘッダ
for(i=1; i<=maxNumber; i++){
printf("%d,u%08d,%d\n", # CSVボディ
i,
i,
substr(rand(), 3) );
}
}
$ awk -f hogehoge.awk
#seq, uid, point
1,u00000001,973385
2,u00000002,295117
:
100000,u00100000,695035
(7)【基本編】エディタ機能でテストデータを編集する
CSVファイルなどの編集はエディタで微調整することが多いかと思います。
VisualStudioCode で使えるプラグインを紹介します。
■ VisualStudioCode: vscode-random(MIT licene)
■ VisualStudioCode: rainbow-csv(MIT licene)
(8)【基本編】JSON データを大量につくる
いくつかツールはありますが、ここではDummy JSONを使って、テストデータを作成します。
まず、インプットファイルを作成し、次にDummy JSONを実行し、JSON ファイルを生成します。
[
{{#repeat 5}}
{
"uid": {{@index}},
"name": "{{firstName}} {{lastName}}",
"email": "{{email}}"
}
{{/repeat}}
]
$ dummyjson sample-json.txt > test.json
$ cat test.json
------
[
{
"uid": 0,
"name": "Liza Charley",
"email": "liza.charley@unilogic.name"
},
{
"uid": 1,
"name": "Austin Tuck",
"email": "austin.tuck@triosys.club"
},
{
"uid": 2,
"name": "Rolf Pettey",
"email": "rolf.pettey@qualcore.org"
},
{
"uid": 3,
"name": "Alexa Raymond",
"email": "alexa.raymond@acousticom.net"
},
{
"uid": 4,
"name": "Chloe Miers",
"email": "chloe.miers@creatonix.biz"
}
]
Dummy JSON(MIT License)
他にもWebサービスでも作成することが可能です。
Next JSON Generator
(9)【基本編】JSON データからCSVデータに変換する
jq を使って JSON から CSV に変換します。
$ dummyjson sample-json.txt | jq -r '.[]|[.uid,.name,.email]|@csv'
------
0,"Shea Webster","shea.webster@fastfreight.xyz"
1,"Mitch Cumbie","mitch.cumbie@pancast.info"
2,"Lyle Sprowl","lyle.sprowl@quadtek.name"
3,"Yuri Seal","yuri.seal@dynaroc.org"
4,"Rufus Gamble","rufus.gamble@conixco.name"
$ dummyjson sample-json.txt | jq -r '["uid","name","email"],
(.[]|[.uid,.name,.email])|@csv'
------
"uid","name","email"
0,"Warren Gamble","warren.gamble@bellgate.net"
1,"Lyn Pendergast","lyn.pendergast@hassifix.name"
2,"Drew Furlough","drew.furlough@bellgate.org"
3,"Olivia Sager","olivia.sager@truext.gov"
4,"Alexa Jensen","alexa.jensen@solexis.me"
$ dummyjson sample-json.txt | jq -r ".[]|[.uid,.name,.email]|@tsv"
------
0 Jetta Pleiman jetta.pleiman@westercom.me
1 Stephen Young stephen.young@celmax.com
2 Gavin Magby gavin.magby@celmax.org
3 Michael Leath michael.leath@seelogic.net
4 Craig Zobel craig.zobel@omnitouch.name
(10)【基本編】JSON データからXMLデータに変換する
json2xml を使って XML を生成します。
まず、事前に json2xml を組み込みます。
$ pip3 install json2xml
$ pip3 list | grep json2xml
json2xml 3.20.0
今回は1~5件までランダムな件数のXMLファイルを作成します。3つのステップでXML ファイルに変換します。
- a. JSONからXML変換用のpython ソースの準備
- b. インプットファイルからJSON ファイルを生成
- c. JSONファイルからXML ファイルに変換
a. JSONからXML変換用のpython ソースの準備
from json2xml import json2xml
from json2xml.utils import readfromurl, readfromstring, readfromjson
data = readfromjson("test2.json")
print(json2xml.Json2xml(data).to_xml())
b. インプットファイルからJSON ファイルを生成
これまでと同じようにインプットファイル(sample2-json.txt)からJSONファイルを生成します。
[
{{#repeat min=1 max=5}}
{
"uid": {{add @index 1}},
"name": "{{firstName}} {{lastName}}",
"email": "{{email}}"
}
{{/repeat}}
]
c. JSONファイルからXML ファイルに変換
そのあとXMLファイルに変換します。
$ python3 json2xml.py
------
<?xml version="1.0" ?>
<all>
<item type="dict">
<uid type="int">1</uid>
<name type="str">Marcus Pettey</name>
<email type="str">marcus.pettey@keysoft.edu</email>
</item>
<item type="dict">
<uid type="int">2</uid>
<name type="str">Craig Jensen</name>
<email type="str">craig.jensen@coolinga.net</email>
</item>
<item type="dict">
<uid type="int">3</uid>
<name type="str">Alexis Freeman</name>
<email type="str">alexis.freeman@forecore.gov</email>
</item>
</all>
(11)【基本編】JSON データからYAMLデータに変換する
json2yaml を使いましょう。
python-json2yaml (Apache License)
$ dummyjson sample2-json.txt | json2yaml
- uid: 1
name: Lynetta Bourquin
email: lynetta.bourquin@multilingua.org
- uid: 2
name: Rosie Tindel
email: rosie.tindel@opticast.info
【参考】: 他に変換用のツールとして、yjやXML, yaml, tomlを扱う参照用ツールとして jq(JSON用)xq(XML用), yq(YAML用), tomlq(TOML) があります。用途やケースによって、使い分けが必要ですが、ご参考までに紹介しておきます。
yj (Apache License)
python-yq, toml, xq (Apache License)
(12)【基本編】0バイトのデータを作る・0件のデータを作る
テストの時やシステム間連携時の本番環境の動作の初期動作時のお約束事として、初期データのファイルを作る場合があるかと思います。
$ touch testfile.csv
$ echo "#id,date, shopid, termid, itemname, price" > testfile.csv
$ echo "#eof" >> testfile.csv
(13)【基本編】「準正常系」「異常系」のテストデータを作る
$ sed s/,/:/ testfile_origin.csv > testfile.csv
$ sed '3{; :a; s/,/:/5; t; N; ba;}' testfile_origin.csv > testfile.csv
$ sed s/,/:/g testfile_origin.csv > testfile.csv
(14)【基本編】1GiBのテキストデータを作る
base64 /dev/urandom | head -c 1024M > testfile.csv
(15)【基本編】1GiBのバイナリデータを作る
dd if=/dev/zero of=testfile.bin bs=1M count=1024
dd if=/dev/urandom of=testfile.bin bs=1M count=1024
(16)【応用編】SQL構造にあわせて、テストデータを作る
-
PostgreSQL の場合、generate_seriesを使い、インサート文をつくりましょう
generate_series -
SQL a5mkMK2が使える場合は、ダミーデータ作成機能を使いましょう
a5mk2 テスト用ダミーデータ作成
3.3. テストデータをチェックする
(1)【基本編】重複データがないか検出する(テキストデータ)
cat double.txt
apple
apple
orange
$ uniq -c -d double.txt
2 apple # 重複
$ echo $? # リターンは0
0
$ cat uniq.txt
apple
orange
lemon
$ uniq -c -d uniq.txt # 重複データないと何も出力せず
$ echo $? # リターンは0
0
(2) 【基本編】改行コードが正しいかチェックする(テキストデータ)
$ cat -e ファイル名
LF$ # LFのみの場合 $ ← Unix/Linux系はLFに統一しておく方がベター
CR^M # CRのみの場合 ^M
CRLF^M$ # CRLFのみの場合 ^M$
-----------------------------------
以下は改行データを作成する場合の実行例
$ echo -en "LF\xA" > testdata.csv
$ echo -en "CR\xD" >> testdata.csv
$ echo -en "CRLF\xD\xA" >> testdata.csv
$ od -tx1c testdata.csv
0000000 4c 46 0a 43 52 0d 43 52 4c 46 0d 0a
L F \n C R \r C R L F \r \n
(3) 【基本編】文字コードをチェックする(テキストデータ)
$ file ファイル名
JIS.txt: ASCII text, with escape sequences
ShiftJIS.txt: Non-ISO extended-ASCII text, with CRLF line terminators
UTF8BOM.txt: UTF-8 Unicode (with BOM) text, with CRLF line terminators
UTF8noBOM.txt: UTF-8 Unicode text, with CRLF line terminators
$ nkf --guess *txt
JIS.txt: ISO-2022-JP (LF)
ShiftJIS.txt: Shift_JIS (CRLF)
UTF8BOM.txt: UTF-8 (BOM) (CRLF)
UTF8noBOM.txt: UTF-8 (CRLF)
- Windows 環境でテストデータを作っているとBOMつきで保存してしまい、Linux上でバイナリーデータとして扱われる場合があります。ファイルに保存するとき、注意しましょう。
- 文字コードあたりと改行コードもあわせて、チェックしておきましょう。
- nkf(ネットワーク漢字フィルター) は、通常のクラウドサービスの標準設定では導入されていません。現場で助かるケースがあるので、apt-get install nkf で導入しましょう。
(4) 【基本編】テストデータを比較する(テキストデータ)
$ diff --rc ファイル名1 ファイル名2
diff -rc testdata1.csv testfile2.csv
*** testdata1.csv 2022-06-15 04:44:51.054067000 +0000
--- testfile2.csv 2022-06-15 04:45:53.320013800 +0000
***************
*** 1,6 ****
1,2,3,4,5,6
1,2,3,4,5,6
! 1,2,3,4,5,6 ←どの行が違うか(ファイル名1)
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
--- 1,6 ----
1,2,3,4,5,6
1,2,3,4,5,6
! 1,2,3,4,5:6 ←どの行が違うか(ファイル名2)
1,2,3,4,5,6
1,2,3,4,5,6
1,2,3,4,5,6
$ cmp -b testdata1.csv testfile2.csv
testdata1.csv testfile2.csv differ: byte 34, line 3 is 54 , 72 :
# 1バイト単位にどこの位置の何が違うかを表示
(5) 【基本編】テストデータを比較する(画像データ)
ImageMagick のcompare コマンドを使って、想定どおりのテストデータが出来ているかを
確認します。
$ compare 入力ファイル名1 入力ファイル名2 出力ファイル(比較結果)
例)
$ compare sample.jpg sample.png sample-diff.png
少しでも違いのある箇所は赤く示されています。
【sample-diff.png】
3.4. テスト時のオペレーションを記録する
複数人開発で同時にデータベースを触りながら、テストデータを作るようになると、開発の現場で問題になる場合があります。日ごろからオペレーションの際の記録はとっておくようにしましょう。
(1)【基本編】テスト時のオペレーションログを残す(コマンド実行の場合)
$ script -a dataimport-op`date +"%Y%m%d"`.log
# 操作を行う (例 : ls -al /usr/local/src)
#
exit # スクリプトを抜ける
Script done, file is dataimport-op20220615.log
(1)【基本編】テスト時のスナップショットを残す(GUI・WUI操作の場合)
-
Windows の場合は、「ctrl」+「Windowキー」+「s」でスナップショットがとれます。
pbrush や Excel 等にはりつけてファイルに記録しましょう。
https://support.microsoft.com/ja-jp/windows/windows-のキーボード-ショートカット-dcc61a57-8ff0-cffe-9796-cb9706c75eec -
Mac の場合は、「shift」「command」「3」の 3 つのキーを同時に長押しします。しばらくするとファイルに保存されます。
https://support.apple.com/ja-jp/HT201361
(2)【基本編】データベースの内容・ログファイルを出力する
個人で実施している場合は特に意識しないかもしれませんが、複数人で開発する場合は、
データベースの更新内容やログファイルを必ず残しましょう。
- テスト実施前: 実施条件
- テスト実施後: 何が更新されたか、何を出力されているか
(3)【基本編】ミリ秒単位で記録をとる
後工程になればなるほど、性能問題が発生したときの対処が難しくなります。
はやい工程の段階から、記録を残して処理時間やレスポンス時間を求めるようにしましょう。
以下は シェルの場合です。
$ export TZ=JST-9 # タイムゾーンによる出力補正
$ date +"%Y/%m/%d %T.%N"
2022/06/15 00:18:21.454898075
$ date +"%Y/%m/%d %T.%6N"
2022/06/15 00:18:40.574924
$ date +"%Y/%m/%d %T.%3N"
2022/06/15 00:19:13.522
(4)【基本編】テストデータを整理し、報告する
作ったテストデータは、プロジェクトのフォルダに配置します。
決して、テストデータやエビデンスは、個人持ちしないようにしましょう。
期日通りにできていない(できそうにない)場合は、速やかに報告しましょう。
(5)【基本編】テストエビデンスを整理し、報告する
テストデータ作成後、テストデータ作成者が、そのままテスト実施者になることもあります。
テスト項目を消化する際には、エビデンスを記録し、報告しましょう。
- 条件
- 環境条件
- 初期設定条件
- テストデータ
- テスト項目に沿ったテストデータ
- (必要に応じて)テスト仕様書へもフィードバック - エビデンス
- 画面のスクリーンショット
- コマンドオペレーション
- 帳票
- レシート
- 出力ファイル
- 出力メール
- ログファイル(業務・監査・システム)
- データベースの更新結果
- パフォーマンスログ
- 報告内容
- テスト進捗(デイリー)
- テスト仕様書の結果
- インシデント
- 問い合わせ内容
4. まとめ
最近はインターネットサービス上にテストデータ作成サービスがあり、「なんで回りくどい」と感じた方もいるかと思います。便利なものがない、個人利用では使えるものが使えない最低限のマシン環境下で、業務をこなすことを想定し、シンプルなLinuxベースで実現できれば、と思い、記事を書いてみました。WSL2 が出たおかげで、本当のWindowsと本当のLinuxを、ストレスなく使いこなせるようになってきましたね。今後は android, ipad, Macとの融合に期待。
あまりまとまっていませんが、本日はここまで、とします。
5. 参考
この記事は、以下の曲を聴きながら、作成しました。
- get back(the beatles)
- telegram sam(t.rex)
- satisfaction(the rolling stones)
- my sharona(the knack)
- synchronicity I(the police)
- smoke on the water(deep purple)
- back in black(ac/dc)
- purple haze(jimi hendrix)
- rock and roll(led zepperin)
- sailing(rod stewart)
ここまで読んでいただいた方、ありがとうございます。
では、また
Discussion