アルゴリズムとかオーダーとか

仕事で勉強したことなどをまとめてます

Truffleで簡単なContractの作成からテストまで

Truffleを用いたContractの作成〜単体テストの実行までの流れをまとめます。
今回ははメッセージを誰でも保存、閲覧できるだけの簡単なContractを作成して、また簡単なテストを書いて実行してみます。

Truffleのインストールについては過去の記事をご覧ください。
y-nakajo.hatenablog.com



1. Truffleのプロジェクトを作成

> mkdir simple-storage
> cd simple-storage
> truffle init

2. Contractの作成

> truffle create contract SimpleStorage

で作成されたcontracts/SimpleStorage.solに以下の内容をコピペ

pragma solidity ^0.4.4;

contract SimpleStorage {

  string public storedMsg; // メッセージを保持

  function SimpleStorage() public {
    // constructor
  }

  // メッセージを保存します。
  function set(string _message) public {
    storedMsg = _message;
  }
}

# constractorにpublicとかつけないといけないのがめんどくさい。solidityのバージョン指定して雛形作ったりできないのかなぁ。

3. 新しく作ったSimpleStorageをデプロイするためのmigrationの作成

> truffle create migration DeploySimpleStorage

で生成された./migrations/数字_deploy_simple_storage.jsに以下の内容をコピペ

var SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function(deployer) {
  // Use deployer to state migration tasks.
  deployer.deploy(SimpleStorage);
};

ここまでは以前の記事でも触れたないようです。ここからさらに単体テストを作成していきます。
truffleではJavaScriptとSolidityでそれぞれテストを書けるのですが今回はJavaScriptで記述します。

4. SimpleStorageの単体テストを作成

> truffle create test SimpleStorageTest

で生成された./test/simple_storage_test.jsに以下の内容をコピペ

var SimpleStorage = artifacts.require("SimpleStorage");

contract('SimpleStorageTest', function(accounts) {
  it("should assert true", function(done) {
    var simple_storage_test = SimpleStorage.deployed();
    assert.isTrue(true);
    done();
  });

  it("SimpleStorage should be return last message.", function() {
    // 3回メッセージを書き込んで、最後に取れるのは最後のメッセージなのか確認するテスト
    var strage;
    return SimpleStorage.deployed().then(function(instance) {
      strage = instance;
      return strage.set("test1", {from: accounts[0]});
    }).then(function () {
      return strage.set("test2", {from: accounts[0]});
    }).then(function () {
      return strage.set("test3", {from: accounts[0]});
    }).then(function () {
      return strage.storedMsg({from: accounts[0]});
    }).then(function(message) {
      return assert.equal(message, "test3", "get third String is test3");
    });
  });
});

5. 単体テストを実行

> truffle test
Using network 'test'.



  Contract: SimpleStorageTest
    ✓ should assert true
    ✓ SimpleStorage should be return last message. (184ms)


  2 passing (209ms)

以上です。

Truffleではテストを実行する時はdevelopで実行されるのと同じようなノードを起動してその上でテストします。なので、テスト実行のために他のノードを準備する必要はありません。
また、Truffleで使われているテストフレームワークMochaというものだそうです。ドキュメントが結構独特で、なかなか読みにくい。。。(assertionのところとか)

テストを書いていた時にちょっとハマったところは、基本的にContractのメソッド呼び出しはPromissでラップされて非同期で実行されます。(Contractの状態を変更するメソッドをcallするにはtransactionを投げる必要があるから)なので、MochaのAsynchronous-codeの説明にある通り、callback functionのなかでdoneを呼び出すとエラーになります。
(ここに気づかずに少しハマってしまった。。。)