Search code, repositories, users, issues, pull requests...

Provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • Notifications

Project for Course 03 at Coursera Blockchain Specialization (The State University of New York at Buffalo)

wakqasahmed/course-03-project-blockchain-spec

Folders and files, repository files navigation, project: smart contract testing.

This project is part of the Blockchain Specialization at Coursera. The test cases has been added in this project in continuation of the project done in Course 2 (which allows bidding of items by participants and its various functions such as register bidder, declare winner etc. over blockchain).

More details can be found here:

Project Description

How to run?

Pre-requisites.

  • Ethereum Virtual Machine having truffle and git installed in it
  • Passion for Next level of World Wide Web and its bright future ;)
  • Open Ethereum Virtual Machine in VirtualBox
  • Clone this repository git clone https://github.com/wakqasahmed/course-03-project-blockchain-spec.git
  • Open terminal and run truffle develop
  • truffle compile
  • truffle migrate --reset
  • truffle test
  • Done - You should witness passing of test cases related to the Smart Contract functions such as registering bidders, placing bids and revealing winners

Technology Stack

This project uses the following technologies:

  • Solidity v0.4.17
  • Truffle IDE v4.0.4

Course Completion Certificate

This project is a public domain work, dedicated using CC0 1.0. Feel free to do whatever you want with it. (If you are a coursera student, learn but not cheat :P)

  • JavaScript 100.0%

Testing smart contracts

Last edit : , March 20, 2024

For these reasons, testing smart contracts before deploying to Mainnet is a minimum requirement for security . There are many techniques for testing contracts and evaluating code correctness; what you choose depends on your needs. Nevertheless, a test suite made up of different tools and approaches is ideal for catching both minor and major security flaws in contract code.

.css-1qbzvaj{transition-property:var(--eth-transition-property-common);transition-duration:var(--eth-transition-duration-fast);transition-timing-function:var(--eth-transition-easing-ease-out);cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;outline:2px solid transparent;outline-offset:2px;color:var(--eth-colors-primary-base);text-underline-offset:3px;position:absolute;right:100%;opacity:0;-webkit-transition:opacity 0.1s ease-in-out;transition:opacity 0.1s ease-in-out;}.css-1qbzvaj:hover,.css-1qbzvaj[data-hover]{-webkit-text-decoration:underline;text-decoration:underline;color:var(--eth-colors-primary-hover);}.css-1qbzvaj:focus-visible,.css-1qbzvaj[data-focus-visible]{box-shadow:var(--eth-shadows-none);outline:2px solid;outline-color:var(--eth-colors-primary-hover);outline-offset:2px;border-radius:var(--eth-radii-sm);}.css-1qbzvaj[data-inline-link]:visited{color:var(--eth-colors-primary-visited);}[role=group]:hover .css-1qbzvaj,[role=group][data-hover] .css-1qbzvaj,[data-group]:hover .css-1qbzvaj,[data-group][data-hover] .css-1qbzvaj,.group:hover .css-1qbzvaj,.group[data-hover] .css-1qbzvaj{opacity:1;}.css-1qbzvaj:focus,.css-1qbzvaj[data-focus]{opacity:1;} .css-1ff30mc{width:1em;height:1em;display:inline-block;line-height:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:currentColor;font-size:var(--eth-fontSizes-xl);-webkit-margin-end:var(--eth-space-1);margin-inline-end:var(--eth-space-1);} Prerequisites

What is smart contract testing.

Smart contract testing is the process of verifying that the code of a smart contract works as expected. Testing is useful for checking if a particular smart contract satisfies requirements for reliability, usability, and security.

Why is it important to test smart contracts?

As smart contracts often manage high-value financial assets, minor programming errors can and often lead to massive losses for users (opens in a new tab) . Rigorous testing can, however, help you discover defects and issues in a smart contract's code early and fix them before launching on Mainnet.

While it is possible to upgrade a contract if a bug is discovered, upgrades are complex and can result in errors (opens in a new tab) if handled improperly. Upgrading a contract further negates the principle of immutability and burdens users with additional trust assumptions. Conversely, a comprehensive plan for testing your contract mitigates smart contract security risks and reduces the need to perform complex logic upgrades after deploying.

Methods for testing smart contracts

Methods for testing Ethereum smart contracts fall under two broad categories: automated testing and manual testing . Automated testing and manual testing offer unique benefits and tradeoffs, but you can combine both to create a robust plan for analyzing your contracts.

Automated testing

Automated testing uses tools that automatically check a smart contracts code for errors in execution. The benefit of automated testing comes from using scripts (opens in a new tab) to guide the evaluation of contract functionalities. Scripted tests can be scheduled to run repeatedly with minimal human intervention, making automated testing more efficient than manual approaches to testing.

Automated testing is particularly useful when tests are repetitive and time-consuming; difficult to carry out manually; susceptible to human error; or involve evaluating critical contract functions. But automated testing tools can have drawbacks—they may miss certain bugs and produce many false positives (opens in a new tab) . Hence, pairing automated testing with manual testing for smart contracts is ideal.

Manual testing

Manual testing is human-aided and involves executing each test case in your test suite one after the other when analyzing a smart contracts correctness. This is unlike automated testing where you can simultaneously run multiple isolated tests on a contract and get a report showing all failing and passing tests.

Manual testing can be carried out by a single individual following a written test plan that covers different test scenarios. You could also have multiple individuals or groups interact with a smart contract over a specified period as part of manual testing. Testers will compare the actual behavior of the contract against the expected behavior, flagging any difference as a bug.

Effective manual testing requires considerable resources (skill, time, money, and effort), and it is possible—due to human error—to miss certain errors while executing tests. But manual testing can also be beneficial—for example, a human tester (e.g., an auditor) may use intuition to detect edge cases that an automated testing tool would miss.

Automated testing for smart contracts

Unit testing.

Unit testing evaluates contract functions separately and checks that each component works correctly. Good unit tests should be simple, quick to run and provide a clear idea of what went wrong if tests fail.

Unit tests are useful for checking that functions return expected values and that contract storage is updated properly after function execution. Moreover, running unit tests after making changes to a contracts codebase ensures adding new logic does not introduce errors. Below are some guidelines for running effective unit tests:

Guidelines for unit testing smart contracts

1. understand your contracts business logic and workflow.

Before writing unit tests, it helps to know what functionalities a smart contract offers and how users will access and use those functions. This is particularly useful for running happy path tests (opens in a new tab) that determine if functions in a contract return the correct output for valid user inputs. We'll explain this concept using this (abridged) example of an auction contract (opens in a new tab)

This is a simple auction contract designed to receive bids during the bidding period. If the highestBid increases, the previous highest bidder receives their money; once the bidding period is over, the beneficiary calls the contract to get their money.

Unit tests for a contract like this would cover different functions a user might call when interacting with the contract. An example would be unit a test that checks if a user can place a bid while the auction is ongoing (i.e., calls to bid() succeed) or one that checks if a user can place a higher bid than the current highestBid .

Understanding a contracts operational workflow also helps with writing unit tests that check if execution meet requirements. For example, the auction contract specifies that users cannot place bids when the auction has ended (i.e., when auctionEndTime is lower than block.timestamp ). Thus, a developer might run a unit test that checks if calls to the bid() function succeed or fail when the auction is over (i.e., when auctionEndTime > block.timestamp ).

2. Evaluate all assumptions related to contract execution

It is important to document any assumptions about a contract’s execution and write unit tests to verify the validity of those assumptions. Apart from offering protection against unexpected execution, testing assertions forces you to think about operations that could break a smart contracts security model. A useful tip is to go beyond "happy user tests" and write negative tests that check if a function fails for the wrong inputs.

Many unit testing frameworks allow you to create assertions—simple statements that state what a contract can and cannot do—and run tests to see if those assertions hold under execution. A developer working on the auction contract described earlier could make the following assertions about its behavior before running negative tests:

Users cannot place bids when the auction is over or hasn't begun.

The auction contract reverts if a bid is below the acceptable threshold.

Users who fail to win the bid are credited with their funds

Note : Another way of testing assumptions is to write tests that trigger function modifiers (opens in a new tab) in a contract, especially require , assert , and if…else statements.

3. Measure code coverage

Code coverage (opens in a new tab) is a testing metric that tracks the number of branches, lines, and statements in your code executed during tests. Tests should have good code coverage, otherwise you may get "false negatives" which happen a contract passes all tests, but vulnerabilities still exist in the code. Recording high code coverage, however, gives the assurance all statements/functions in a smart contract were sufficiently tested for correctness.

4. Use well-developed testing frameworks

The quality of the tools used in running unit tests for your smart contracts is crucial. An ideal testing framework is one that's regularly maintained; provides useful features (e.g., logging and reporting capabilities); and must have been extensively used and vetted by other developers.

Unit testing frameworks for Solidity smart contracts come in different languages (mostly JavaScript, Python, and Rust). See some of the guides below for information on how to start running unit tests with different testing frameworks:

  • Running unit tests with Brownie (opens in a new tab)
  • Running unit tests with Foundry (opens in a new tab)
  • Running unit tests with Waffle (opens in a new tab)
  • Running unit tests with Remix (opens in a new tab)
  • Running unit tests with Ape (opens in a new tab)
  • Running unit tests with Hardhat (opens in a new tab)

Integration testing

While unit testing debugs contract functions in isolation, integration tests evaluate the components of a smart contract as a whole. Integration testing can detect issues arising from cross-contract calls or interactions between different functions in the same smart contract. For example, integration tests can help check if things like inheritance (opens in a new tab) and dependency injection work properly.

The forked blockchain will behave similarly to Mainnet and have accounts with associated states and balances. But it only acts as a sandboxed local development environment, meaning you won't need real ETH for transactions, for example, nor will your changes affect the real Ethereum protocol.

Property-based testing

Property-based testing is the process of checking that a smart contract satisfies some defined property. Properties assert facts about a contract’s behavior that are expected to remain true in different scenarios—an example of a smart contract property could be "Arithmetic operations in the contract never overflow or underflow."

Static analysis and dynamic analysis are two common techniques for executing property-based testing, and both can verify that the code for a program (a smart contract in this case) satisfies some predefined property. Some property-based testing tools come with predefined rules about expected contract properties and check the code against those rules, while others allow you to create custom properties for a smart contract.

Static analysis

A static analyzer takes as input the source code of a smart contract and outputs results declaring whether a contract satisfies a property or not. Unlike dynamic analysis, static analysis doesn't involve executing a contract to analyze it for correctness. Static analysis instead reasons about all the possible paths that a smart contract could take during execution (i.e., by examining the structure of the source code to determine what it would mean for the contracts operation at runtime).

Linting (opens in a new tab) and static testing (opens in a new tab) are common methods for running static analysis on contracts. Both require analyzing low-level representations of a contracts execution such as abstract syntax trees (opens in a new tab) and control flow graphs (opens in a new tab) output by the compiler.

In most cases, static analysis is useful for detecting safety issues like use of unsafe constructs, syntax errors, or violations of coding standards in a contracts code. However, static analyzers are known to be generally unsound at detecting deeper vulnerabilities, and may produce excessive false positives.

Dynamic analysis

Dynamic analysis generates symbolic inputs (e.g., in symbolic execution (opens in a new tab) ) or concrete inputs (e.g., in fuzzing (opens in a new tab) ) to a smart contracts functions to see if any execution trace(s) violates specific properties. This form of property-based testing differs from unit tests in that test cases cover multiple scenarios and a program handles the generation of test cases.

Fuzzing (opens in a new tab) is an example of a dynamic analysis technique for verifying arbitrary properties in smart contracts. A fuzzer invokes functions in a target contract with random or malformed variations of a defined input value. If the smart contract enters an error state (e.g., one where an assertion fails), the problem is flagged and inputs that drive execution toward the vulnerable path are produced in a report.

Fuzzing is useful for evaluating a smart contracts input validation mechanism since improper handling of unexpected inputs might result in unintended execution and produce dangerous effects. This form of property-based testing can be ideal for many reasons:

Writing test cases to cover many scenarios is difficult. A property test only requires that you define a behavior and a range of data to test the behavior with—the program automatically generates test cases based on the defined property.

Your test suite may not sufficiently cover all possible paths within the program. Even with 100% coverage, it is possible to miss out on edge cases.

Unit tests prove a contract executes correctly for sample data, but whether the contract executes correctly for inputs outside the sample remains unknown. Property tests execute a target contract with multiple variations of a given input value to find execution traces that cause assertion failures. Thus, a property test provides more guarantees that a contract executes correctly for a broad class of input data.

Guidelines for running property-based testing for smart contracts

Running property-based testing typically starts with defining a property (e.g., absence of integer overflows (opens in a new tab) ) or collection of properties that you want to verify in a smart contract. You may also need to define a range of values within which the program can generate data for transaction inputs when writing property tests.

Once configured properly, the property testing tool will execute your smart contracts functions with randomly generated inputs. If there are any assertion violations, you should get a report with concrete input data that violates the property under evaluation. See some of the guides below to get started with running property-based testing with different tools:

  • Static analysis of smart contracts with Slither (opens in a new tab)
  • Property-based testing with Brownie (opens in a new tab)
  • Fuzzing contracts with Foundry (opens in a new tab)
  • Fuzzing contracts with Echidna (opens in a new tab)
  • Symbolic execution of smart contracts with Manticore (opens in a new tab)
  • Symbolic execution of smart contracts with Mythril (opens in a new tab)

Manual testing for smart contracts

Manual testing of smart contracts often comes later in the development cycle after running automated tests. This form of testing evaluates the smart contract as one fully integrated product to see if it performs as specified in the technical requirements.

Testing contracts on a local blockchain

While automated testing performed in a local development environment can provide useful debugging information, you'll want to know how your smart contract behaves in a production environment. However, deploying to the main Ethereum chain incurs gas fees—not to mention that you or your users can lose real money if your smart contract still has bugs.

Testing your contract on a local blockchain (also known as a development network ) is a recommended alternative to testing on Mainnet. A local blockchain is a copy of the Ethereum blockchain running locally on your computer which simulates the behavior of Ethereum's execution layer. As such, you can program transactions to interact with a contract without incurring significant overhead.

Running contracts on a local blockchain could be useful as a form of manual integration testing. Smart contracts are highly composable , allowing you to integrate with existing protocols—but you'll still need to ensure that such complex on-chain interactions produce the correct results.

More on development networks.

Testing contracts on testnets

A test network or testnet works exactly like Ethereum Mainnet, except that it uses Ether (ETH) with no real-world value. Deploying your contract on a testnet means anyone can interact with it (e.g., via the dapp's frontend) without putting funds at risk.

This form of manual testing is useful for evaluating the end-to-end flow of your application from a user’s point of view. Here, beta testers can also perform trial runs and report any issues with the contract’s business logic and overall functionality.

Deploying on a testnet after testing on a local blockchain is ideal since the former is closer to the behavior of the Ethereum Virtual Machine. Therefore, it is common for many Ethereum-native projects to deploy dapps on testnets to evaluate a smart contracts operation under real-world conditions.

More on Ethereum testnets.

Testing vs. formal verification

While testing helps confirm that a contract returns the expected results for some data inputs, it cannot conclusively prove the same for inputs not used during tests. Testing a smart contract, therefore, cannot guarantee "functional correctness" (i.e., it cannot show that a program behaves as required for all sets of input values).

Formal verification is an approach to assessing the correctness of software by checking whether a formal model of the program matches the formal specification. A formal model is an abstract mathematical representation of a program, while a formal specification defines a program's properties (i.e., logical assertions about the program's execution).

Because properties are written in mathematical terms, it becomes possible to verify that a formal (mathematical) model of the system satisfies a specification using logical rules of inference. Thus, formal verification tools are said to produce ‘mathematical proof’ of a system’s correctness.

Unlike testing, formal verification can be used to verify a smart contracts execution satisfies a formal specification for all executions (i.e., it has no bugs) without needing to execute it with sample data. Not only does this reduce time spent on running dozens of unit tests, but it is also more effective at catching hidden vulnerabilities. That said, formal verification techniques lie on a spectrum depending on their difficulty of implementation and usefulness.

More on formal verification for smart contracts.

Testing vs audits and bug bounties

As mentioned, rigorous testing can rarely guarantee the absence of bugs in a contract; formal verification approaches can provide stronger assurances of correctness but are currently difficult to use and incur considerable costs.

Still, you can further increase the possibility of catching contract vulnerabilities by getting an independent code review. Smart contract audits (opens in a new tab) and bug bounties (opens in a new tab) are two ways of getting others to analyze your contracts.

Audits are performed by auditors experienced at finding cases of security flaws and poor development practices in smart contracts. An audit will usually include testing (and possibly formal verification) as well as a manual review of the entire codebase.

Conversely, a bug bounty program usually involves offering a financial reward to an individual (commonly described as whitehat hackers (opens in a new tab) ) that discovers a vulnerability in a smart contract and discloses it to developers. Bug bounties are similar to audits since it involves asking others to help find defects in smart contracts.

The major difference is that bug bounty programs are open to the wider developer/hacker community and attract a broad class of ethical hackers and independent security professionals with unique skills and experience. This may be an advantage over smart contract audits that mainly rely on teams who may possess limited or narrow expertise.

Testing tools and libraries

Unit testing tools.

solidity-coverage (opens in a new tab) - Code coverage tool for smart contracts written in Solidity.

Waffle (opens in a new tab) - Framework for advanced smart contract development and testing (based on ethers.js) .

Remix Tests (opens in a new tab) - Tool for testing Solidity smart contracts. Works underneath Remix IDE "Solidity Unit Testing" plugin which is used to write and run test cases for a contract.

OpenZeppelin Test Helpers (opens in a new tab) - Assertion library for Ethereum smart contract testing. Make sure your contracts behave as expected!

Brownie unit testing framework (opens in a new tab) - Brownie utilizes Pytest, a feature-rich test framework that lets you write small tests with minimal code, scales well for large projects, and is highly extendable.

Foundry Tests (opens in a new tab) - Foundry offers Forge, a fast and flexible Ethereum testing framework capable of executing simple unit tests, gas optimization checks, and contract fuzzing.

Hardhat Tests (opens in a new tab) - Framework for testing smart contracts based on ethers.js, Mocha, and Chai.

ApeWorx (opens in a new tab) - Python-based development and testing framework for smart contracts targeting the Ethereum Virtual Machine.

Property-based testing tools

Static analysis tools.

Slither (opens in a new tab) - Python-based Solidity static analysis framework for finding vulnerabilities, enhancing code comprehension, and writing custom analyses for smart contracts.

Ethlint (opens in a new tab) - Linter for enforcing style and security best practices for the Solidity smart contract programming language.

Cyfrin Aderyn (opens in a new tab) - Rust-based static analyzer specifically designed for Web3 smart contract security and development.

Dynamic analysis tools

Echidna (opens in a new tab) - Fast contract fuzzer for detecting vulnerabilities in smart contracts through property-based testing.

Diligence Fuzzing (opens in a new tab) - Automated fuzzing tool useful for detecting property violations in smart contract code.

Manticore (opens in a new tab) - Dynamic symbolic execution framework for analyzing EVM bytecode.

Mythril (opens in a new tab) - EVM bytecode assessment tool for detecting contract vulnerabilities using taint analysis, concolic analysis, and control flow checking.

Diligence Scribble (opens in a new tab) - Scribble is a specification language and runtime verification tool that allows you to annotate smart contracts with properties that allow you to automatically test the contracts with tools such as Diligence Fuzzing or MythX.

Related tutorials

  • An overview and comparison of different testing products _
  • How to use Echidna to test smart contracts
  • How to use Manticore to find smart contract bugs
  • How to use Slither to find smart contract bugs
  • How to mock Solidity contracts for testing
  • How to run unit tests in Solidity using Foundry (opens in a new tab)

Further reading

  • An in-depth guide to testing Ethereum smart contracts (opens in a new tab)
  • How to test ethereum smart contracts (opens in a new tab)
  • MolochDAO's unit testing guide for developers (opens in a new tab)
  • How to test smart contracts like a rockstar (opens in a new tab)

Was this article helpful?

Advisory boards aren’t only for executives. Join the LogRocket Content Advisory Board today →

LogRocket blog logo

  • Product Management
  • Solve User-Reported Issues
  • Find Issues Faster
  • Optimize Conversion and Adoption
  • Start Monitoring for Free

The complete guide to blockchain testing

programming assignment smart contract testing

Organizations all over the world are turning to blockchain technology to improve data storage, security, and management. This has resulted in the need to ensure that applications built on the blockchain network are thoroughly tested.

programming assignment smart contract testing

In this article, we will discuss what blockchain testing is all about, including the benefits and drawbacks, the types of blockchain testing, the phases, and some useful tools. We will also create and test a smart contract using some of the recommended testing tools.

What is blockchain testing?

Blockchain testing is the systematic evaluation of the blockchain’s various functional components (e.g., smart contracts). Unlike traditional software testing, blockchain testing involves several components such as blocks, mining, transactions, wallets, and so on, all of which require special tools to test.

Blockchain testing aids in the development of various quality stages, ranging from system performance to the security of the blockchain application.

According to Santu Maity, Enterprise Architect at IBM, the best approach for blockchain testing encompasses the entire environment. This includes blockchain-based applications, both mobile and web, that interact with the blockchain system’s functional component, like an API, smart contracts, and nodes.

Benefits of blockchain testing

Blockchain testing ensures that all entities involved in a blockchain network have been properly validated for operation. As a result, it provides organizations with a secure and functional infrastructure.

Blockchain testing aids in the delivery of quality products, thereby improving user experience. It also eliminates flaws in a decentralized system where money is involved in order to prevent financial damage.

Challenges of blockchain testing

One of the most significant challenges is a lack of testing tools. Currently, there are few testing tools available for each blockchain framework; therefore, using the wrong tool can cause problems.

Another issue in the blockchain ecosystem is a lack of professional expertise. Because blockchain technology is still relatively new in the tech world, it has not seen widespread adoption among software developers.

Yet another challenge is testing strategy. Blockchain testing necessitates a thorough knowledge and understanding of how blockchain works.

programming assignment smart contract testing

Over 200k developers use LogRocket to create better digital experiences

programming assignment smart contract testing

The security of the blockchain network can also be difficult. Blockchain applications are now being used in a variety of economic sectors. As a result, data security is critical for preventing nefarious activities.

The inability to provide an adequate performance and load testing provides little or no knowledge on the performance of blockchain applications under certain conditions.

Types of blockchain testing

The following is a comprehensive list of the types of testing one can perform on a blockchain:

  • Functional testing determines the effectiveness of various functional components of the blockchain system
  • Node testing aids in the independent testing of each node on the network to ensure a problem-free connection
  • Performance testing identifies system flow restrictions and recommends an optimal solution
  • API testing contributes to a clear interaction between applications in the blockchain network by ensuring that requests and responses between these applications are properly operated

Phases of blockchain testing

Initiation phase.

The initiation phase is the first stage of testing a blockchain system. Here, the testers become acquainted with the system’s lifecycle by analyzing and comprehending its functionality, allowing them to gain a better understanding of all components involved. A detailed map is generated that includes all of the system components and subcomponents, as well as all of the interfaces, to provide a good understanding of how the system works overall.

Design phase

In the design phase, the key components of the system that must be tested are identified, and a well detailed test strategy tailored to the blockchain system is developed. This test strategy describes the system’s test cases and test environment specifications.

Planning phase

During this phase, it is decided how each type of test will be performed, with an estimate of how many tests will be performed at each level and to what extent.

If the system is not available, alternative testing strategies must be devised. Setting up a private blockchain for testing is an alternative test strategy. API testing, functional testing, performance testing, security testing, and so on are examples of these tests.

Result phase

This is the final phase, which includes a report on the overall test performed in the system. System performance, low level check, and validation of blocks, transactions, and smart contracts are the fundamental exercises that must be executed during this phase.

Blockchain testing tools

Ethereum tester.

Ethereum Tester is an Ethereum testing tool that includes Web3 Integration, API, and Smart Contracts. This allows development teams to recreate a production-like Ethereum blockchain.

An open source testing library, it is simple to implement and has manageable API support for a variety of testing requirements.

This tool is primarily used to locally test Ethereum contracts. It generates a blockchain simulation that allows anyone to test multiple accounts.

Exonum TestKit

Exonum Test K it specializes in testing the activity of the entire service of the blockchain application. We can use the tool to perform API testing and transaction execution without having to worry about network operations or consensus algorithms.

Corda testing tool

Corda is an open source, distributed ledger platform based on blockchain technology. Contract testing, integration testing, flow testing, and load testing are all made easier with the built in testing tool.

Truffle is a blockchain testing tool with features that go beyond basic testing, such as working with Chai and Mocha. It is a well known name among Ethereum developers for identifying amazing testing features, such as automated contract testing.

The Populus framework includes Ethereum’s testing functionality, which is well integrated as a set of properties focused toward contract deployment testing. These frameworks are mostly built around the pytest framework, allowing for its very simple implementation.

Testing a smart contract

Now let’s move on to the tutorial section of the article. Here, we will develop and test a sample smart contract with Truffle now that you’ve grasped the basics of blockchain testing.

In this example, we will create a car tracking system for an auto shop. We will cover the following:

  • Setting up the development environment
  • Creating a Truffle project
  • Writing the smart contract

Compiling the smart contract

Migrating the smart contract.

  • Testing the smart contract

Setting up the environment

To work with Truffle, you’ll need to have the following software installed on your computer:

Run the following command in your terminal once they’ve been installed successfully:

The command above will install Truffle globally on your computer. Type “truffle version” in the terminal to see if Truffle is installed correctly.

Create a new Truffle project

Create a new project directory with the following:

Migrate into your new project directory like so:

Then, initialize Truffle:

The above command will generate the following directory structure for Truffle:

contracts/ , which contains the smart contract source codes, written in Solidity. Inside this directory there’s an important contract called Migrations.sol .

migrations/ . Deployment of smart contracts is managed with the migration system. It is used to monitor changes in the smart contract.

test/ is where test codes and files for the smart contracts are kept. Tests can written in either Solidity or JavaScript.

truffle-config.js is the Truffle configuration file where you can define your deployment network for deploying your smart contracts.

Creating a smart contract

In the contracts/ directory, create a new file called Auto.sol and add the following:

pragma solidity ^0.8.9; indicates the minimum version of Solidity required. The pragma command means “additional information that only the compiler cares about”, while the caret symbol (^) means “the version indicated or higher.”

When writing Solidity, data types like array and strings must be declared. Solidity provides a special data type called address, which is also an Ethereum address stored as 20 byte values. This address can be used to send and receive Ether.

Within the contract Purchase{ scope, we define a public variable called borrower with an address type and a length of 20 , which is an array of Ethereum addresses. Always remember to add a semicolon (;) at the end of every statement, to avoid an error.

Now let’s create a function that allows users to make a borrow request. Below the variable declaration, add the following:

According to the code above, the function accepts an integer ( uint ) parameter carId and is expected to return an integer as the output. The require() statement is used to ensure that the carId is within the buyer array’s range. Because arrays in Solidity are indexed from zero, the carId value must be between zero and 19.

If the carId is within the range, the address from which the call was made is added to our buyer array, which is denoted by msg.sender . We then return the carId that was passed.

Next we write a function that get all the buyers, like so:

We return the buyer as a type address[20] memory which contains the variable’s data location. view in the function declaration indicates that the function will not change the state of the contract.

Following that, we must compile our Solidity code so that the Ethereum Virtual Machine (EVM) can understand it.

Open the terminal in your project’s root directory and type the following command:

The above command will compile all smart contracts in the contracts folder and as well as create a build directory that contains a contracts folder with artifacts .

Artifacts are .json files that serve as a JavaScript wrapper for interacting with the corresponding smart contracts.

Now that the contract has been successfully compiled, it’s time to migrate it to the blockchain.

A migration is a deployment script that is used to change the state of your application’s contracts, moving them from one state to the next.

To deploy the smart contract over the blockchain, we will first create the migration configuration file. This is a JavaScript file that handles deployment of the smart contracts on the blockchain.

However, in order to deploy the smart contracts with migrations, we must first gain access to their artifacts, which were generated as a result of the Truffle compile command. Inside the migration directory is a default migration file 1_initial_migration.js that handles deployment of the Migration.sol file.

Lets create our own migration configuration file, 2_deploy_contract.js , with the following:

The artifacts.require() method is used to specify the smart contract to use for interacting with the blockchain. Because a source file may contain multiple contracts, we specified the name of the contract definition rather than the name of the .sol file. In this case we use Purchase rather than Auto .

The migrations are then exported as a function with a parameter (deployer). The object deployer is responsible for staging deployments. Next, we deploy PurchaseContract .

Next, we will be using another blockchain testing tool called Ganache to provide an interface to deploy our smart contracts and carry out tests. You can either download or use the command line npm i -g ganache-cli .

If you are using Ubuntu OS, you might find it difficult to run the Ganache application. Simply right-click on the application file, go to properties, then to permissions and tick allow executing file as program. Then re-run the application.

I will be using the Ganache GUI for this tutorial. Run the application and select quickstart . The following image will be displayed on the screen:

ganache quickstart

Now let’s migrate our smart contract:

After a successful migration, you will see the following:

Now go back to your Ganache application:

ganache migration

You will notice the current block, which was previously zero, is now four. Also, the first address started with 100 Ether, now it has 99.99 Ether. This is due to the transaction costs of migration.

We have successfully created and deployed our smart contract on our local blockchain. Now we can test our smart contract to make sure it does what it is supposed to.

There are two methods of testing smart contracts in Truffle. The first is by using Solidity and the second is by using JavaScript. For this tutorial, we will be using the JavaScript method.

In the test directory, create a new file purchase.test.js and write the following:

First, we use the artifacts.require() method to import our Purchase contract. Then we declare a contract and pass in our Purchase instance as the first argument, followed by a callback function as the second.

The parameter for the callback function is accounts . The accounts provides the network’s available accounts. We use before to ensure that the purchased car with ID 4 is assigned to the first account.

We then run a test to see which address purchased the car with ID 4 . To compare the actual value ( buyer ) and the expected value ( expectedBuyer ), we use the assert.equal method. If the test fails, the error message is printed to the console.

Finally, we check to see if it returns all of the buyers’ addresses. Then we check to see if the address with UD 4 is among the returned buyer addresses.

Now we test our contract by running the following command:

If the test passes, you should see a similar result below:

As blockchain adoption grows, the need to deliver high quality products cannot be met without investing in blockchain and blockchain testing expertise.

Blockchain testing ensures that all components in the system are working properly and that all applications are interacting with it in a trustworthy manner.

Join organizations like Bitso and Coinsquare who use LogRocket to proactively monitor their Web3 apps

LogRocket Dashboard Free Trial Banner

LogRocket is like a DVR for web and mobile apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web and mobile apps — Start monitoring for free .

Share this:

  • Click to share on Twitter (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Facebook (Opens in new window)
  • #blockchain

programming assignment smart contract testing

Stop guessing about your digital experience with LogRocket

Recent posts:.

Using Aws Lambda And Aws Cloudfront To Optimize Image Handling

Using AWS Lambda and CloudFront to optimize image handling

Leverage services like AWS Lambda, CloudFront, and S3 to handle images more effectively, optimizing performance and providing a better UX.

programming assignment smart contract testing

Building web-based terminal components with Termino.js

Explore Termino.js, an open source library for integrating web-based terminals into applications, in this introduction article.

programming assignment smart contract testing

How to build a custom GPT: Step-by-step tutorial

Let’s see why and how to build custom GPTs — personalized versions of ChatGPT that act as custom chatbots to serve a specific purpose.

programming assignment smart contract testing

Jest adoption guide: Overview, examples, and alternatives

Jest is feature-rich testing framework that comes with several in-built features that make it powerful and easy to use.

programming assignment smart contract testing

Leave a Reply Cancel reply

Smart Contract Testing: Challenges and Opportunities

Ieee account.

  • Change Username/Password
  • Update Address

Purchase Details

  • Payment Options
  • Order History
  • View Purchased Documents

Profile Information

  • Communications Preferences
  • Profession and Education
  • Technical Interests
  • US & Canada: +1 800 678 4333
  • Worldwide: +1 732 981 0060
  • Contact & Support
  • About IEEE Xplore
  • Accessibility
  • Terms of Use
  • Nondiscrimination Policy
  • Privacy & Opting Out of Cookies

A not-for-profit organization, IEEE is the world's largest technical professional organization dedicated to advancing technology for the benefit of humanity. © Copyright 2024 IEEE - All rights reserved. Use of this web site signifies your agreement to the terms and conditions.

DEV Community

DEV Community

Nazeeh Vahora

Posted on Aug 4, 2021

Testing Solidity Smart Contracts

In the previous blog , we discussed deploying our Smart Contract to the Rinkeby Test Network and interacting with it from our front end.

I decided to write this article on tests as a bonus. You should write these tests before writing the Smart Contract and integrating with the front end.

One way of testing our Contract is interacting with it manually and testing every scenario. In this, one needs to consider every scenario and test the Contract in that case. Remembering every edge case could be tedious. Also forgetting a single edge case could break our Contract.

This is not a preferred way of testing. Instead, we should write tests for our Smart Contracts. Writing tests will check our Smart Contract in every possible scenario and ensures our Contract behaves expectedly. If any of the test cases fail, we can fix that edge case during production only. Thus, writing tests for Smart Contracts is necessary.

So, let's write tests for our Lottery Contract .

Note: To Follow along, refer to this repo .

Navigate to the lottery-contract directory we created in the previous blog and create an empty directory named test . Inside the test directory, create an empty Lottery.test.js file.

For writing tests, we need to add a dependency to our project. For that run the following command in your root directory.

We have all pre-requisites for writing tests. Now, head on to the Lottery.test.js file and paste the following code.

ganache-cli is a fast and customizable blockchain emulator that allows us to make calls to the blockchain without the overheads of running an actual Ethereum node. This will help us in performing our tests instantaneously.

For creating an instance of web3 , we have used the provider from ganache as we will be deploying our Contract to the ganache local network for testing. Apart from web3 , we have required assert (a native javascript library) and interface along with the bytecode from our compiled Contract .

Now, paste the following code.

We have declared two variables namely accounts and lottery that will store our accounts and lottery instance respectively.

After that, we have declared the beforeEach() function which will execute before every test case. In this function, we are fetching the accounts from the web3 instance and storing them in the accounts variable. After that, we have deployed the local instance of our Contract using web3 and stored it in the lottery variable.

Now, let's write our first test.

Above we have defined describe() function. It allows us to gather our tests into separate groupings within the same file, even multiple nested levels.

In the first argument of our describe() function, we have passed the name of our test-suite i.e. 'Lottery Contract'. Inside our describe() function, we have declared an it() function, inside which we have written our test. This test will ensure that our Contract gets deployed successfully.

The first argument of the it() function will accept the name of our test and the second argument will accept the function which runs our test. In this function, we have written assert.ok() which ensures that the value passed inside this function is not null.

We have written our first test. Now, let's run our test. For that navigate to the root directory and run the following command in the terminal.

You should see the following output in your terminal.

image.png

The tick in front of the test name indicates that our test has successfully passed. Congratulations! You have written your first test.

Now let's write tests for other scenarios as well.

For that paste the code from below inside the describe() function.

This test will check whether our Lottery allows users to enter the Lottery. For that, we are initially entering the lottery by calling the lottery.methods.enter() method. Following that, we are fetching the players of the lottery by calling the lottery.methods.getPlayers() method. Our players variable will be an array containing the addresses of all the players of the contract.

Now, we have called the assert.strictEqual() method which ensures that both the arguments passed to it are strictly equal. This test will ensure that we can enter our Lottery successfully.

Similarly, we'll check for multiple accounts to enter our lottery. For that paste the code from below.

In this test, we are entering the lottery from multiple accounts and after that, we are ensuring that each player can enter the lottery or not by calling the assert.strictEqual() method.

After this, we'll write a test to ensure that users can't enter with ethers less than the required amount to enter the lottery. For that, paste the code below.

This test will make sure that the test fails when a user tries to enter with ethers less than the required amount and pass the test when the user is unable to enter the lottery.

Following this, we will write a test that tests that only the manager could able to pick a winner. For that, paste the below code.

Remember in our beforeEach() function, we have deployed the contract using accounts[0] . Thus, the address of our manager is the address stored at accounts[0] . As a result, our test should fail if we try to pick a winner from an account other than accounts[0] .

This test will ensure that only our manager is allowed to pick a winner.

At last comes our final test, which ensures that ethers are sent to the winner of the Contract.

For that, paste the below test.

This test ensures that lottery ethers are sent to the winner of the lottery on picking up the winner by the manager of the contract.

We have successfully written all the necessary tests. Now let's run these tests. For that, navigate to the root directory and run the yarn test command.

You should see the following output in the terminal.

image.png

Congratulations! You have successfully written tests for your Smart Contract. These tests provide security that your Contract won't break out. Now we can be more reliable on your Smart Contracts and can be 100% sure that our Smart Contract will not misbehave.

Connect with me on twitter .

Top comments (1)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

dhaiwat10 profile image

World class article as always

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

sh20raj profile image

React Hooks 🎣 - One Shot

Sh Raj - Apr 8

annoh_karlgusta profile image

7 Practical Applications of JavaScript + Tips

Karl Esi - Apr 11

iankcode profile image

Creating a custom logger in Node JS using Winston

Ian Kamau - Apr 11

jroycodes profile image

New Beginnings

Jonathan R. Mugisha - Apr 10

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

IMAGES

  1. Smart Contract Programming Tutorial for Blockchain Developers

    programming assignment smart contract testing

  2. Smart Contract Management: How It Works & Why You Need It

    programming assignment smart contract testing

  3. Top 5 Programming Languages to Build Smart Contracts

    programming assignment smart contract testing

  4. The process of smart contracts verification.

    programming assignment smart contract testing

  5. Writing smart contracts with Solidity

    programming assignment smart contract testing

  6. Smart Contract Oracles

    programming assignment smart contract testing

VIDEO

  1. Software Testing (IIITB) assignment 1 #nptel #assignment

  2. Smart Contracts Explained for Beginners

  3. week 5 NPTEL assignment Smart Grid for basic to advanced technologies

  4. Software Testing (IIITB) Week 8 Assignment Answers

  5. Software Testing NPTEL Week 3 Assignment Solution #music #nptel

  6. Software Testing (IIITB) Week 7 Assignment Answers

COMMENTS

  1. wakqasahmed/course-03-project-blockchain-spec

    Project: Smart Contract Testing This project is part of the Blockchain Specialization at Coursera. The test cases has been added in this project in continuation of the project done in Course 2 (which allows bidding of items by participants and its various functions such as register bidder, declare winner etc. over blockchain).

  2. Create and test smart contracts using Python

    Note. We use only the setup_method that is executed before each test. In order to execute some code after each test, use the teardown_method.The same goes for the module level with teardown_module function. 6. Testing smart contracts implementation. Let's start our testing journey by creating a test confirming that the accounts created in the setup method take their roles in our smart contract:

  3. The Ultimate Guide to Test Your Smart Contract

    2. How to write the tests and execute them in a test network. Let's start right away with the testing. I've prepared a sample "notes" contract which contains some general functions that I ...

  4. Testing smart contracts

    Manual testing for smart contracts. Manual testing of smart contracts often comes later in the development cycle after running automated tests. This form of testing evaluates the smart contract as one fully integrated product to see if it performs as specified in the technical requirements. Testing contracts on a local blockchain

  5. How to Test Ethereum Smart Contracts

    The smart contracts. Figure 2: Background.sol. Above, we see our Background contract. It exposes three functions: storeValue(uint), getValue(uint), and getNumberOfValues(). All these functions have simple instructions, so they're easy to unit test. Figure 3: EntryPoint.sol. This is our EntryPoint contract. An address for our Background ...

  6. The complete guide to blockchain testing

    Blockchain testing is the systematic evaluation of the blockchain's various functional components (e.g., smart contracts). Unlike traditional software testing, blockchain testing involves several components such as blocks, mining, transactions, wallets, and so on, all of which require special tools to test.

  7. Mastering Smart Contract Testing: A Comprehensive Guide to Hardhat

    Testing smart contracts is a crucial aspect of the development process to ensure that the contracts function correctly and are error-free. Hardhat is a development environment for Ethereum applications that offers various tools and libraries to facilitate smart contract testing. Here are the benefits of testing smart contracts with Hardhat:

  8. PDF 1 Testing Smart Contracts Gets Smarter

    testing approach for smart contract testing. Mutation testing is known as the strongest technique for test design. There are several mutation operators designed for different pro-gramming languages. In this paper, our goal is to propose ... the implementation of a smart contract in Solidity program-ming language. Studying the bugs in smart ...

  9. PDF Testing Smart Contracts: Which Technique Performs Best?

    Aim: This paper conducts an empirical evaluation of testing techniques for smart contracts. The testing techniques we evaluated are: (1) Blackbox fuzzing, (2) Adaptive fuzzing, (3) Coverage-guided fuzzing with an SMT solver and (4) Genetic algorithm.

  10. Writing and Testing a Smart Contract With Hardhat and Ethers.js

    The contracts folder will host our smart contract, the test folder our test and hardhat.config.ts the generated configuration from hardhat — for which we need to make sure that the solidity version defined here matches the specified version of our contract. Writing the smart contract. Imagine that you have been failing to save your coins ...

  11. Testing Smart Contracts

    Solidity is the programming language used for smart contracts run on Ethereum, the dominant blockchain. Naturally, you would use it for testing the internal attributes of Solidity smart contracts. JavaScript is used to test your contract's external behavior. Before writing tests, you'll want to consider your contract's purpose and business logic.

  12. Coursera smart contract Week 4 Final Programming Assignment ...

    Link :https://drive.google.com/drive/folders/14nFpm0TKycmJvTSI9gYt-Y01IWkU5pLN?usp=sharing

  13. Smart Contracts

    This second course of the Blockchain specialization will help you design, code, deploy and execute a smart contract - the computational ... Enroll for free.

  14. Decentralized Applications (Dapps)

    This third course of the Blockchain specialization prepares you to design and develop end-to-end decentralized applications (Dapps) - which provide anyone with access to the blockchain's features and services. You will use Truffle IDE, smart contracts, a simple web client and a MetaMask client. You will learn about the architecture of a ...

  15. Testing Smart Contracts using Foundry

    Once installed, you can create a new directory for your smart contract tests and initialize Foundry by running the following commands: mkdir my-contract-tests. cd my-contract-tests. foundry init ...

  16. Smart Contract Testing: Challenges and Opportunities

    Blockchain technologies have found important and concrete applications in the real world. Active solutions leverage Smart Contracts for the management of cryptocurrencies, sensitive data, and other valuable assets. One of the core objectives of blockchain-oriented software engineering (BOSE) is ensuring that Smart Contracts receive adequate pre-release testing to guarantee the deployment of ...

  17. Testing Solidity Smart Contracts

    This is not a preferred way of testing. Instead, we should write tests for our Smart Contracts. Writing tests will check our Smart Contract in every possible scenario and ensures our Contract behaves expectedly. If any of the test cases fail, we can fix that edge case during production only. Thus, writing tests for Smart Contracts is necessary.

  18. Testing the Solidity Smart Contract, step-by-step

    We should test that the manager, can call the selectWinner function. First we read the current balance of the contract and assign it to the balance variable. We then call the selectWinner function with the address of the manager. We finally assert, that the contract balance is '0'. The last test should look like this: