やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

SQLite3ドットコマンド(.testcase .check)

 単体テストする。

成果物

.help

.testcase NAME           Begin redirecting output to 'testcase-out.txt'
.check GLOB              Fail if output since .testcase does not match

CLI

 .testcase.checkはセット。

成功

sqlite3 :memory: \
".testcase test_name_0" \
"select 'A'='A';" \
".check 1"
  • .testcase以降のSQLステートメントtest_name_0という名前のテストである
  • .check 1は直前の出力結果が1であるかどうかを確かめる

 画面には以下のように出力される。

testcase-100 ok

 以下のようなファイルが勝手に作られる。要らないのだが……。

cat testcase-out.txt
1

失敗

sqlite3 :memory: \
".testcase test_name_0" \
"select 'A'='B';" \
".check 1"

 画面には以下のように出力される。

testcase-test_name_0 FAILED
 Expected: [1]
      Got: [0
]
  • 期待値は1
  • 取得値は0

 以下のようなファイルが勝手に作られる。要らないのだが……。

cat testcase-out.txt
0

SQLファイル作成して実行

 テーブル作成用SQLファイルを作る。

echo "create table T(C text);
insert into T values('A');
insert into T values('B');" > 0_create.sql

0_create.sql

create table T(C text);
insert into T values('A');
insert into T values('B');

 テスト用SQLファイルを作る。

echo ".testcase count_all
select count(*) from T;
.check 2" > 0_test.sql

0_test.sql

.testcase count_all
select count(*) from T;
.check 2

 テーブルを作ってテストを実行する。

sqlite3 :memory: \
".read 0_create.sql" \
".read 0_test.sql"

 テスト結果が表示される。

testcase-count_all ok

 testcase-out.txtファイルが作成される。

cat testcase-out.txt
2

複数行で複数列あるとき

 基本は同じ。出力されるテキストデータと期待値を一致させればいいだけ。

 テーブル作成用SQLファイルを作る。

echo "create table users(
  id integer primary key,
  name text not null,
  class text not null
);
insert into users(name,class) values('Yamada','A');
insert into users(name,class) values('Suzuki','B');
insert into users(name,class) values('Tanaka','A');
" > 1_create.sql

1_create.sql

create table users(
  id integer primary key,
  name text not null,
  class text not null
);
insert into users(name,class) values('Yamada','A');
insert into users(name,class) values('Suzuki','B');
insert into users(name,class) values('Tanaka','A');

 テスト用SQLファイルを作る。

echo ".testcase users_of_class_A
select * from users where class='A';
.check \"1|Yamada|A\n3|Tanaka|A\n\"
" > 1_test.sql

1_test.sql

.testcase users_of_class_A
select * from users where class='A';
.check "1|Yamada|A\n3|Tanaka|A\n\"

 ポイントは.checkの以下。

  • 期待値をダブルクォートする ""
  • 改行コードを\nで示す

1_test.sql

.testcase users_of_class_A
select * from users where class='A';
.check "1|Yamada|A\n3|Tanaka|A\n"

 テーブルを作ってテストを実行する。

sqlite3 :memory: \
".read 1_create.sql" \
".read 1_test.sql"

 テスト結果が表示される。

testcase-users_of_class_A ok

 testcase-out.txtファイルが作成される。

cat testcase-out.txt
1|Yamada|A
3|Tanaka|A

出力形式に注意

 たとえば.separator "|"がデフォルトだが、.separator "\t"など変更されてしまうと列間の|\tになってしまう。同様に、.headers on.mode columnなどされると出力形式が変わってしまうので注意。

 .checkの前に出力形式を明示しておくと安全。

.separator "\"
.headers off
.mode list
.nullvalue ""

 テストSQLファイル作成シェルコマンドは以下のようになる。

echo "
.separator '\'
.headers off
.mode list
.nullvalue ''

.testcase users_of_class_A
select * from users where class='A';
.check \"1|Yamada|A\n3|Tanaka|A\n\"
" > 1_test.sql

 テストケース名を付けずに実行すると引数一覧がみれる。

sqlite3 :memory: .testctrl

 以下コマンドでも同様。

sqlite3 :memory: ".testctrl --help"

 結果は以下。

Available test-controls:
  .testctrl always BOOLEAN
  .testctrl assert BOOLEAN
  .testctrl byteorder 
  .testctrl imposter SCHEMA ON/OFF ROOTPAGE
  .testctrl internal_functions BOOLEAN
  .testctrl localtime_fault BOOLEAN
  .testctrl never_corrupt BOOLEAN
  .testctrl optimizations DISABLE-MASK
  .testctrl pending_byte OFFSET  
  .testctrl prng_reset 
  .testctrl prng_restore 
  .testctrl prng_save 
  .testctrl reserve BYTES-OF-RESERVE

 だが、それらの使い方や意味がわからない。説明なし。ヘルプ。

assert

 真偽値によって合否判定するのか? と思ったが謎。

 trueはエラー。

sqlite3 :memory: ".testctrl assert true"
ERROR: Not a boolean value: "true". Assuming "no".
0

 「noと仮定する」というのでyes/noを使うのか?

sqlite3 :memory: ".testctrl assert no"
0

 だがyesにしても出力は同じ0。は?

sqlite3 :memory: ".testctrl assert yes"
0

 0, 1も同様。

sqlite3 :memory: ".testctrl assert 1"
0
sqlite3 :memory: ".testctrl assert 0"
0

 なにこれ。説明求む。ググっても情報なし。

 ソースコードを少し見てみたがわからん。sqlite3_test_control関数の所在が不明。どこにある? 何する?

 もはやコナミコマンド並の裏コマンド的な何か。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux

前回まで