Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoin Coreのテストコードの実行方法

既存のコードの追加・改修の際に、動作を保証するテストコードがあり、自動テストできる環境があるのは重要で、Bitcoin Coreにももちろんテストコードと自動テストの仕組みがある。

Bitcoin Coreには単体テストと、リグレッション及びインテグレーションテスト用のテストコードがそれぞれ存在する。

単体テストの実行

テストコードはconfigureオプションで無効化していない限り、自動的にコンパイルされる。

実行対象のテストコードは、以下のMakefileに記載されている↓

(他にもウォレットやsecp256k1などのテストが各フォルダにある。)

テストの実行は簡単で make checkを実行すればC++で書かれたテストが実行される。もしくは、コンパイルされたsrc/test/test_bitcoinを実行してもいい。

$ ./src/test/test_bitcoin    
Running 258 test cases...

*** No errors detected

bitcoin-qtの場合はsrc/qt/test/test_bitcoin-qtを実行する。

個別のテストの実行

↑では全テストコードが実行されるので、個別に実行したい場合は、↓のように--run_testオプションで対象のテストを指定して、src/test/test_bitcoinを使って実行する。

$ ./src/test/test_bitcoin --run_test=script_tests --log_level=all

↑はsrc/test/script_tests.cpp のテスト実行。--log_levelオプションでログをコンソールに出力することもできる。

指定可能なオプションは--helpオプションを指定してtest_bitcoinを実行すれば確認できる。

テストコードの追加

単体テストのコードはboostのテストフレームワークを使って書かれてるので、テストコードを追加する際もそれを使用する。

既存のファイルにテストコードを追加する場合は、既存のテストファイルのBOOST_AUTO_TEST_CASE関数内に追加するか、BOOST_AUTO_TEST_CASE関数を追加して実装する。

新規にテストコードのファイルを追加する場合は、そのファイルを↑のMakefile.test.includeに追記する。
基本的にはソースファイルやクラス毎に1つテストファイルを作成することになっており、テストファイルの命名規則<source_filename>_tests.cpp

bitcoin-qtのテストはsrc/qt/test/以下に追加)

リグレッション及びインテグレーションテストの実行

このテストは↓のセットで構成される。

  • functional
    RPCやP2Pインターフェースを介して動作するbitcoind及びbitcoin-qtの機能をテストするコード。
  • util
    Bitcoinのユーティリティのテストコードで、現在の対象はbitcoin-txのみ。

functionalテストの実行

各テストの実行は、それぞれpythonのテストファイルを直接実行すればいい。

$ test/functional/segwit.py 
2017-08-10 06:51:43.129000 TestFramework (INFO): Initializing test directory /tmp/test92n84pq5
2017-08-10 06:51:45.901000 TestFramework (INFO): Verify sigops are counted in GBT with pre-BIP141 rules before the fork
2017-08-10 06:51:50.062000 TestFramework (INFO): Verify default node can't accept any witness format txs before fork
...

もしくは、test_runner.pyの引数に実行対象のテストファイルを指定する方法もある。

$ test/functional/test_runner.py segwit.py net.py
Temporary test directory at /tmp/bitcoin_test_runner_20170810_155359
............
net.py passed, Duration: 6 s
..................................
segwit.py passed, Duration: 24 s

TEST      | STATUS    | DURATION

net.py    | ✓ Passed  | 6 s
segwit.py | ✓ Passed  | 24 s

ALL       | ✓ Passed  | 30 s (accumulated) 
Runtime: 24 s

全テストケースを実行する場合は、テストファイルを指定せずに、test_runner.pyを実行する。

テストコードに記載されているログは、デフォルトではコンソールには出力されず全てtest_framework.logというログファイルに記載され、テスト実行用の一時フォルダ内に格納される。 コンソールに出力する場合は-lオプションを指定。

またPythonで書かれ、実行されているので、任意の場所に↓を入れて、デバッガをアタッチすることも可能。

import pdb; pdb.set_trace()

テストを追加する場合は、↓を参考にする。

https://github.com/bitcoin/bitcoin/blob/master/test/functional/README.md

utilテストの実行

↓のbitcoin-util-test.pyを実行する。-vはverboseオプションで各テストのログが出力される。

$ test/util/bitcoin-util-test.py -v
2017-08-10 15:45:50,726 - INFO - PASSED: Creates a blank v1 transaction
2017-08-10 15:45:50,731 - INFO - PASSED: Creates a blank v1 transaction (output in json)
2017-08-10 15:45:50,735 - INFO - PASSED: Creates a blank transaction when nothing is piped into bitcoin-tx
...