问题
当我运行truffle test
的时候,有点惊讶地发现测试过程里并不需要启动ganache-cli命令行程序。翻看了truffleframework的文档也是含糊其辞,倒是处处暗示必须使用Ganache或者Truffle Develop
作为测试的运行时。
所以我开始动手做试验。
试验
先去测试文件xxContractTest.js中使用console.log(accounts)
打印输出accounts。重复运行测试后,结果始终是一致,如下:
[ '0x627306090abaB3A6e1400e9345bC60c78a8BEf57',
'0xf17f52151EbEF6C7334FAD080c5704D77216b732',
'0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef',
'0x821aEa9a577a9b44299B9c15c88cf3087F3b5544',
'0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2',
'0x2932b7A2355D6fecc4b5c0B6BD44cC31df247a2e',
'0x2191eF87E392377ec08E7c08Eb105Ef5448eCED5',
'0x0F4F2Ac550A1b4e2280d04c21cEa7EBD822934b5',
'0x6330A553Fc93768F612722BB8c2eC78aC90B3bbc',
'0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE' ]
而且测试中打印出了运行时的网络始终是test,如下:
$ truffle test
Using network 'test'
我对这个网络比较困惑,原因是该项目的配置文件truffle.js
并没有声明名称为test的网络。所以我需要更多的信息,通过帮助命令./node_modules/.bin/truffle help test
,得知了一下可选参数:
Usage: truffle test [] [--compile-all] [--network ] [--verbose-rpc] [--show-events]
Description: Run JavaScript and Solidity tests
Options:
Name of the test file to be run. Can include path information if the file does not exist in the
current directory.
--compile-all
Compile all contracts instead of intelligently choosing which contracts need to be compiled.
--network
Specify the network to use, using artifacts specific to that network. Network name must exist
in the configuration.
--verbose-rpc
Log communication between Truffle and the Ethereum client.
--show-events
Log all contract events.
其中--network
引起了我的注意。我开始试验不同网络,比如:truffle test --network develop
,结果有点意外:
Using network 'develop'.
Contract: xxContract
[ '0x627306090abaB3A6e1400e9345bC60c78a8BEf57',
'0xf17f52151EbEF6C7334FAD080c5704D77216b732',
'0xC5fdf4076b8F3A5357c5E395ab970B5B54098Fef',
'0x821aEa9a577a9b44299B9c15c88cf3087F3b5544',
'0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2',
'0x2932b7A2355D6fecc4b5c0B6BD44cC31df247a2e',
'0x2191eF87E392377ec08E7c08Eb105Ef5448eCED5',
'0x0F4F2Ac550A1b4e2280d04c21cEa7EBD822934b5',
'0x6330A553Fc93768F612722BB8c2eC78aC90B3bbc',
'0x5AEDA56215b167893e80B4fE645BA6d5Bab767DE' ]
前后对比,不难发现,两次输出的账户是一致的。我稍微思考了一下,觉得是这可能是truffle test
的fallback机制,因为配置文件truffle.js
确实没有任何设置develop的网络。
供开发测试用的是local网络,配置如下,所以我重新针对该网络运行测试。
local: {
host: '127.0.0.1',
port: 8545,
network_id: '*'
}
$ truffle test --network local
此时运行出错,错误是连接不上Ethereum Client,这是符合期望的行为。
Could not connect to your Ethereum client with the following parameters:
- host > 127.0.0.1
- port > 8545
- network_id > *
Please check that your Ethereum client:
- is running
- is accepting RPC connections (i.e., "--rpc" option is used in geth)
- is accessible over the network
- is properly configured in your Truffle configuration file (truffle-config.js)
Truffle v5.0.5 (core: 5.0.5)
Node v10.15.3
那么,究竟Truffle test的fallback机制是怎样的呢?我们需要去源码中寻找答案。
解释
Truffle的命令组织,结构比较简单,可以快速定位到文件,如:trufflesuite/truffle/packages/truffle-core/lib/commands/test.js。其fallback机制集中在run方法中。
if (config.networks[config.network]) {
Environment.detect(config, environmentCallback);
} else {
var ipcOptions = {
network: "test"
};
var ganacheOptions = {
host: "127.0.0.1",
port: 7545,
network_id: 4447,
mnemonic:
"candy maple cake sugar pudding cream honey rich smooth crumble sweet treat",
gasLimit: config.gas,
noVMErrorsOnRPCResponse: true
};
Develop.connectOrStart(ipcOptions, ganacheOptions, function(
started,
disconnect
) {
ipcDisconnect = disconnect;
Environment.develop(config, ganacheOptions, environmentCallback);
});
}
});
Develop.connectOrStart(...)
方法其实和执行truffle develop
是相同的操作。所以不难知道,truffle test
是通过truffle develop
启动新的节点,然后设置了一系列可用的accounts。
为了进一步验证材料,可以验证下助记词candy maple cake sugar pudding cream honey rich smooth crumble sweet treat
是否会产生上述的十个账号地址。
验证的方式很简单,拷贝助记词黏贴到在线bip39网站里,选择ETH-Ethereum作为Coin,然后观察输出的地址,确认确实符合期望。
2019-04-02