Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Solidity test case analysis

2025-02-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "solidity test case analysis". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Overview of intelligent contract testing in Ethernet Square

As software developers, we all know that testing is a very important part of making the code work properly. The decentralized software based on blockchain is no exception, and because of the immutability of blockchain, testing is more important for blockchain software.

In general, there are two types of software testing: unit testing and integration testing. Unit testing focuses on the testing of a single function, while the goal of integration testing is to ensure that parts of the code are combined to run as expected.

Truffle is the most widely used Ethernet Square intelligent contract and DApp development framework. It provides two methods for testing Ethernet Square intelligent contracts: Solidity testing and JavaScript testing. The question is, which method should we choose?

The answer is both.

Writing test cases for smart contracts in Solidity allows us to test at the block chain level. This test case can invoke the contract method, just as the use case is deployed in a block chain. To test the internal behavior of smart contracts, we can:

Write Solidity unit tests to check the return value of the intelligent contract function and the value of the state variable

Write Solidity integration tests to check the interaction between smart contracts. These integration tests ensure that mechanisms such as inheritance or dependency injection work as expected

We also need to make sure that smart contracts show the right external behavior. To test the smart contract from outside the blockchain, we use web3.js in the JavaScript test case, just as we did when developing DApp. We need to build confidence that the DApp front end can invoke the smart contract correctly. Testing in this area belongs to integration testing.

Therefore, to put it simply, the Solidity test case is mainly used for the verification of the implementation logic within the intelligent contract, and can be used for unit testing and integration testing, while the JavaScript use case is mainly used for the verification of the external behavior of the intelligent contract, usually for integration testing.

2. Sample project of intelligent contract testing in Ethernet Square.

Suppose we have two ethernet smart contracts to test: Background and Entrypoint.

Background is an internal contract and our DApp front end does not interact with it directly. EntryPoint is a smart contract specifically for DApp interaction, and the Background contract is accessed within the EntryPoint contract.

The following is the solidity code for the Background contract:

Pragma solidity > = 0.5.0 th contract Background {uint [] private values; function storeValue (uint value) public {values.push (value);} function getValue (uint initial) public view returns (uint) {return values [initial];} function getNumberOfValues () public view returns (uint) {return values.length;}}

Above, we see that the Background contract provides three functions:

StoreValue (uint): write values

GetValue (uint): read valu

GetNumberOfValues (): gets the number of values

All three contract functions are simple, so they are also easy to unit test.

The following is the Solidity code for the EntryPoint contract:

Pragma solidity > = 0.5.0 function getBackgroundAddress import ". / Background.sol"; contract EntryPoint {address public backgroundAddress; constructor (address _ background) public {backgroundAddress = _ background;} function getBackgroundAddress () public view returns (address) {return backgroundAddress;} function storeTwoValues (uint first, uint second) public {Background (backgroundAddress) .storeValue (first); Background (backgroundAddress) .storeValue (second) } function getNumberOfValues () public view returns (uint) {return Background (backgroundAddress) .getNumberOfValues ();}}

In the constructor of the EntryPoint contract, we inject the deployment address of the Background contract and store it in a state variable backgroundAddress. The EntryPoint contract exposes three functions:

GetBackgroundAddress (): returns the deployment address of the Background contract

StoreTwoValues (uint, uint): save two values

GetNumberOfValues (): the number of values returned

Because the storeTwoValues (uint, uint) function calls a function in the Background contract twice, it is difficult to unit test this function. GetNumberOfValues () has the same problem, so these two functions are more suitable for integration testing.

3. Solidity use case of Ethernet Square Intelligent contract Test

In this section, we learn how to write Solidity unit test cases and integration test cases for smart contracts. Let's start with a simpler unit test.

Here is the code for the TestBackground test:

Pragma solidity > = 0.5.0 public import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import ".. / contracts/Background.sol"; contract TestBackground {Background public background; / / Run before every test function function beforeEach () public {background = new Background ();} / Test that it stores a value correctly function testItStoresAValue () public {uint value = 5; background.storeValue (value) Uint result = background.getValue (0); Assert.equal (result, value, "It should store the correct value");} / / Test that it gets the correct number of values function testItGetsCorrectNumberOfValues () public {background.storeValue (99); uint newSize = background.getNumberOfValues (); Assert.equal (newSize, 1, "It should increase the size") } / / Test that it stores multiple values correctly function testItStoresMultipleValues () public {for (uint8 I = 0; I

< 10; i++) { uint value = i; background.storeValue(value); uint result = background.getValue(i); Assert.equal(result, value, "It should store the correct value for multiple values"); } }} 这个单元测试的目的是确保Background合约可以: 在values数组中保存新的值 按索引返回values 在values数组中保存多个值 返回values数组的大小 下面的TestEntryPoint测试中包含了一个单元测试testItHasCorrectBackground() 用于验证EntryPoint合约的功能符合预期: pragma solidity >

= 0.5.0 Ensure that dependency injection working correctly function testItHasCorrectBackground import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import ".. / contracts/Background.sol"; import ".. / contracts/EntryPoint.sol"; contract TestEntryPoint {/ / Ensure that dependency injection working correctly function testItHasCorrectBackground () public {Background backgroundTest = new Background (); EntryPoint entryPoint = new EntryPoint (address (backgroundTest)); address expected = address (backgroundTest) Address target = entryPoint.getBackgroundAddress (); Assert.equal (target, expected, "It should set the correct background");}}

This function tests dependency injection. As mentioned earlier, other functions in the EntryPoint contract need to interact with the Background contract, so we have no way to test these functions separately and need to be verified in the integration test. Here is the code for the integration test:

Pragma solidity > = 0.5.0 BackgroundTest public backgroundTest; EntryPoint public entryPoint; import "truffle/Assert.sol"; import "truffle/DeployedAddresses.sol"; import ".. / contracts/Background.sol"; import ".. / contracts/EntryPoint.sol"; contract TestIntegrationEntryPoint {BackgroundTest public backgroundTest; EntryPoint public entryPoint; / / Run before every test function function beforeEach () public {backgroundTest = new BackgroundTest (); entryPoint = new EntryPoint (address (backgroundTest)) } / / Check that storeTwoValues () works correctly. / / EntryPoint contract should call background.storeValue () / / so we use our mock extension BackgroundTest contract to / / check that the integration workds function testItStoresTwoValues () public {uint value1 = 5; uint value2 = 20; entryPoint.storeTwoValues (value1, value2); uint result1 = backgroundTest.values (0); uint result2 = backgroundTest.values (1); Assert.equal (result1, value1, "Value 1 should be correct") Assert.equal (result2, value2, "Value 2 should be correct");} / Check that entry point calls our mock extension correctly / / indicating that the integration between contracts is working function testItCallsGetNumberOfValuesFromBackground () public {uint result = entryPoint.getNumberOfValues (); Assert.equal (result, 999, "It should call getNumberOfValues");}} / / Extended from Background because values is private in actual Background// but we're not testing background in this unit testcontract BackgroundTest is Background {uint [] public values Function storeValue (uint value) public {values.push (value);} function getNumberOfValues () public view returns (uint) {return 999;}}

We can see that TestIntegrationEntryPoint uses an extension of Background, the BackgroundTest defined on line 43, as our mock contract, which allows our test case to check that EntryPoint has called the correct function of the contract deployed at the backgroundAddress address.

4. JavaScript use case for intelligent contract testing in Ethernet Square

We write integration tests in JavaScript to ensure that the external behavior of the contract meets the expected requirements, so that we have the information to develop DApp based on these smart contracts.

Here is our JavaScript test file entryPoint.test.js:

Const EntryPoint = artifacts.require (". / EntryPoint.sol"); require ('chai') .use (require (' chai-as-promised')). Should (); contract ("EntryPoint", accounts = > {describe ("Storing Values", () = > {it ("Stores correctly", async () = > {const entryPoint = await EntryPoint.deployed (); let numberOfValues = await entryPoint.getNumberOfValues ()) NumberOfValues.toString () .should.equal ("0"); await entryPoint.storeTwoValues (2heli4); numberOfValues = await entryPoint.getNumberOfValues (); numberOfValues.toString () .should.equal ("2");})

Using the functions in the EntryPoint contract, the JavaScript test ensures that we can pass the values outside the chunk chain into the smart contract using the transaction, which is achieved by calling the contract's storeTwoValues (uint,uint) function (line 15).

5. Ethernet Square Intelligent contract testing tutorial Section

When it comes to testing smart contracts, it can be said that the more, the better, and you should cover as many possible execution paths as possible to return the expected results. Truffle provides two methods: block chain layer Solidity unit test and integration test, and DApp level JavaScript integration test. In actual work, we need to comprehensively use these two testing methods according to the code implementation of the intelligent contract to ensure that the intelligent contract runs as expected.

This is the end of "solidity Test case Analysis". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report