在Java集成測試中運行Pantheon節點
嘗試為Java以太坊應用程序編寫集成測試時,您可能遇到的第一個問題是,您需要一個運行節點來連接以發送事務。解決此問題的一個選擇是在後台手動運行節點,但如果要在CI管道中運行測試,並且迫使代碼庫的所有貢獻者手動運行節點,這將變得難以管理。幸運的是,這是一個更好的方法
先決條件
- 一個正在運行的Docker守護進程
- 了解Junit
- 要測試的代碼。本教程不會顯式顯示此代碼,但您可以在GitHub上找到基於此社區中其他教程的示例。
使用Testcontainers運行節點
Testcontainers是一個有用的庫,允許您在測試代碼中以編程方式啟動Docker容器,並且有幾個Ethereum客戶端將現成的Docker容器上載到Dockerhub,這使得此任務更容易。
在本指南中,我將介紹如何在集成測試期間啟動和關閉Pantheon節點,這樣您就不必手動啟動節點或在CI管道中啟動節點
包括Testcontainers庫
我們通過maven central獲取Testcontainers庫依賴項,因此要包含庫,請將以下依賴項添加到pom.xml(或Gradle中的等效項):
org.testcontainers
testcontainers
1.12.0
test
啟動萬神殿
在所有測試執行之前,而不是在每次測試之前,啟動Pantheon一次更好,更高效。為了實現這種行為,我們實例化了一個GenericContainer
帶有@ClassRule
JUnit注釋的靜態注釋。
在項目測試文件夾中創建一個新類,並將下面的代碼添加到它:
ClassRule
@ClassRule
public static final GenericContainer pantheonContainer =
new GenericContainer("pegasyseng/pantheon:1.1.3")
.withExposedPorts(8545, 8546)
.withCommand(
"--miner-enabled",
"--miner-coinbase=0xfe3b557e8fb62b89f4916b721be55ceb828dbd73",
"--rpc-http-enabled",
"--rpc-ws-enabled",
"--network=dev")
.waitingFor(Wait.forHttp("/liveness").forStatusCode(200).forPort(8545));
}
在運行任何測試之前,GenericContainer
會實例化a,並將docker鏡像名稱作為參數。我們在這個實例中使用了Pantheon的1.1.3版本,並且我們使用該withExposedPorts(..)
方法公開HTTP和websocket RPC的標準默認埠。
我們設置了一些運行時命令參數,這些參數以適合測試以下內容的方式配置節點:
--miner-enabled
:啟用挖礦,以便我們在測試中發送的事務包含在塊中。--miner-coinbase
:將coinbase設置為您擁有私鑰的帳戶。啟用挖礦時必須執行此操作。在這裡,我們將帳戶設置為眾所周知的Pantheon開發帳戶,在開發模式下自動載入以太坊。--rpc-http-enabled
:啟用HTTP RPC端點,以便Web3j可以連接。--rpc-ws-enabled
:啟用websocket RPC端點。如果您只測試HTTP,則不需要這樣做。--network=dev
:將網路類型設置為dev
。這將啟動一個私有開發節點,具有預定義的配置,可以更輕鬆地挖礦CPU使用率。
有關所有可用Pantheon命令的完整列表,請閱讀官方文檔。
等待萬神殿開始
在完全運行我們的測試之前,我們必須等待Pantheon開始。Pantheon自動配置了活動端點,因此testcontainers會自動輪詢/liveness
埠上的端點,8545
直到它返回200響應。然後我們可以確信Pantheon正在運行。
使用Web3j連接Pantheon容器
萬神殿現在應該正常運行localhost
。您現在可以連接到測試類中的Pantheon節點,並執行以太坊操作,例如使用Web3j發送事務:
final Integer port = pantheonContainer.getMappedPort(8545);
Web3j web3j = Web3j.build(new HttpService(
"http://localhost:" + port), 500, Async.defaultExecutorService());
Credentials credentials = Credentials.create("0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63");
映射埠
我們在創建容器時公開了默認的JSON RPC埠8545,但沒有將它映射到localhost上的同一埠。自動選擇隨機可用埠,這是有益的,因為它消除了埠未在測試機器上打開的可能性(例如,如果您並行運行測試,則可能會發生這種情況)。
要獲取映射的埠號,請調用getMappedPort(..)
容器上的方法。我們可以在構造Web3j連接URL時使用這些埠。
輪詢間隔
默認情況下,Web3j每隔10秒輪詢連接的以太坊客戶端,以獲取最新挖礦的塊並檢查是否已發出事件等操作。我們的Pantheon測試網路通常比每10秒創建塊更快,因此減少Web3j中的輪詢間隔應該會提高測試的速度。我們可以將輪詢間隔傳遞給Web3j.build
靜態方法,在上面,我們將間隔配置為500ms。
測試憑證
在我們的私人開發網路中發送交易仍然需要天然氣,因此我們必須能夠訪問具有正餘額的帳戶,並且開發網路的某些帳戶預先載入了比您需要的更多的測試以太坊這裡記錄了這些帳戶的私鑰,這使得生成Credentials
在測試中使用的對象變得容易。
停止萬神殿/ Web3j
當我們使用@ClassRule
注釋時,停止Pantheon容器會在測試類執行結束時自動處理。最好在每次測試後關閉web3j實例:
@After
public void shutdownWeb3j() {
web3j.shutdown();
}
摘要
使用Testcontainers庫啟動Pantheon節點是確保您的測試可以訪問以太坊節點的便捷方法。這使得在持續集成管道中運行測試變得不那麼艱難,並且還意味著其他第三方貢獻者可以更輕鬆地在本地計算機上運行測試。
您可以在java-web3j-pantheon-testing項目中找到一個示例測試類,演示本教程中GitHub中描述的代碼