• Bitcoin $ 39,800.00 (4.9025%)
  • Ethereum $ 1,199.00 (2.03734%)
 09.06.2019 в 12:31   coinnews

Тестирование ваших смарт контрактов с помощью JavaScript (включая Async / Await)

[Код для этого поста можно найти здесь:]

Разработчики умных контрактов стремятся уменьшить количество ошибок в своем коде, поскольку они могут в буквальном смысле дорого стоять. С этой целью, один из методов, которые мы используем, состоит в том, чтобы писать подробные тесты.

В этом посте покажем вам, как начать тестирование ваших умных контрактов с самого начала.

Вот краткий список принципов, которые я предлагаю принять во внимание:

Прежде всего, это зависимости, которые я использовал для создания этого урока. Если вы столкнулись с ошибкой, вы можете попробовать установить и использовать эти версии.

— node@8.5.0 
— truffle@^4.0.0
— ethereumjs-testrpc@^4.0.1

Давайте настроим проект.

mkdir smart-contract-test-example && cd» $ _» && trupple init webpack

Приведенный выше фрагмент создает каталог, изменяет его и инициализирует Truffle с помощью веб-пакета.

Теперь создайте тестовый файл FundRaise для умного контракта, который мы будет разрабатывать

touch test/fundRaise.js

Откройте файл в вашем любимом текстовом редакторе и добавьте базовую структуру теста.

const FundRaise = artifacts.require  ('./FundRaise.sol')
contract  ('FundRaise', function  () {
})

Они в первую очередь получают исходные данные. Это абстракция контракта, содержащая его первичную информацию, то есть его ABI, адрес и тому подобное.

Затем мы создаем функцию, contract (аналогичную describe (функции в Mocha, за исключением того, что Truffle добавляет некоторые функции, такие как проверка развертывания контрактов перед запуском тестов. Кстати, Truffle использует среду тестирования Mocha, а также библиотеку утверждений Chai.

Теперь давайте запустим тест этого  «скелета» 

Первый:

testrpc

Затем откройте новое окно командной строки и введите

truffle test test/fundRaise.js

Результат:

Error: Could not find artifacts for. /FundRaise.sol from any sources
at Resolver.require (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:49072:9)
at TestResolver.require (/usr/local/lib/node_modules/truffle/build/cli.bundled.js:89733:30)

Это потому, что мы еще не закодировали FundRaise умный контракт. Давайте это исправим.

touch contracts/FundRaise.sol

Затем добавьте код

pragma solidity ^0.4.17;
contract FundRaise {
}

Запустите тест снова:

 0 passing  (1ms)

Правильно. Тесты еще не написаны.

Спецификация смарт-контракта и добавление тестов

FundRaise  Умный контракт будет простой контракт. Его спецификация:

  • У него есть владелец
  • Он принимает средства
  • Он может приостановиться и приостановить сбор средств
  • Владелец договора может в любое время снять средства 

Начнем с первой спецификации — у контракта есть владелец

const FundRaise = artifacts.require  ('./FundRaise.sol')
contract  ('FundRaise', function  ([owner]) {
let fundRaise
 beforeEach  ('setup contract for each test', async function  () {
fundRaise = await FundRaise.new (owner)
})
 it  ('has an owner', async function  () {
assert.equal (await fundRaise.owner (), owner)
})
})

В приведенном выше тестовом коде мы выполнили несколько вещей.

1 — представьте, что ES2015, деструктурирующее присвоение переменной в function ([owner] первом параметре, переданном contract функции, представляет собой массив с учетными записями, полученными из testrpc. Мы берем первый и присваиваем ему переменную owner .

2- создать переменную fundRaise

3 — есть beforeEachфункция, которая будет запускаться перед каждым тестом, создавая fundRaiseкаждый раз новый экземпляр . Обратите внимание на использование async/await. Это позволяет делать более читаемый тестовый код.

4 — создать первый тест в it () функциональном блоке. Здесь мы утверждаем, что fundRaise.owner (это то, ownerчто мы передали при создании контракта.

Прежде чем запускать тесты еще раз, зайдите truffle.js и потребуйте, babel-polyfill как нам нужно, чтобы использовать async/await.

truffle.js

// Allows us to use ES6 in our migrations and tests.
require ('babel-register')
require ('babel-polyfill')
module.exports = {
networks: {
development: {
host: 'localhost',
port: 8545,
network_id: '*' // Match any network id
}
}
}

Запустите тесты еще раз, и вы найдете эту ошибку:


1 failing
1) Contract: FundRaise has an owner:
AssertionError: expected undefined to equal '0x676c48fb3979cf2e47300e8ce80a99087589650d'

Теперь пришло время написать код, который сделает первый тестовый проход. Давайте немного уточним наш умный контракт.

pragma solidity ^0.4.17;
contract FundRaise {
address public owner;
 // @dev constructor function. Sets contract owner 
function FundRaise () {
owner = msg.sender;
}
}

Запустите тест снова, то есть truffle test test/fundRaise.js :

Contract: FundRaise
✓ has an owner (41ms)
1 passing  (138ms)

Отлично! Давайте двигаться дальше и добавим следующий.

const FundRaise = artifacts.require  ('./FundRaise.sol')
 contract  ('FundRaise', function  ([owner, donor]) {
let fundRaise
 beforeEach  ('setup contract for each test', async function  () {
fundRaise = await FundRaise.new (owner)
})
 it  ('has an owner', async function  () {
assert.equal (await fundRaise.owner (), owner)
})
 it  ('is able to accept funds', async function  () {
await fundRaise.sendTransaction ({ value: 1e+18, from: donor })
 const fundRaiseAddress = await fundRaise.address
assert.equal (web3.eth.getBalance (fundRaiseAddress).toNumber (), 1e+18)
})
})

Ошибка на этот раз:

1 failing
1) Contract: FundRaise is able to accept funds:
Error: VM Exception while processing transaction: invalid opcode

Правильно, нам нужно, чтобы наш контракт получил Эфир. Давайте это исправим.

pragma solidity ^0.4.17;
contract FundRaise {
address public owner;
// @dev constructor function. Sets contract owner 
function FundRaise () {
owner = msg.sender;
}

// fallback function that allows contract to accept ETH
function () payable {}
}

И результат:

Contract: FundRaise
✓ has an owner (38ms)
✓ is able to accept funds (234ms)
2 passing  (473ms)

Красиво.  Это процесс, который проходит систематически, чтобы покрыть умные контракты тестом, написанным на JavaScript. Просто продолжайте делать это, пока все условия умного контракта не будут выполнены.

Для простоты я собираюсь ускорить процесс и добавить полный набор тестов для FundRaise контракта

и вот полный код для умного контракта:

Запустите тесты в последний раз …

Contract: FundRaise
✓ has an owner (46ms)
✓ accepts funds (193ms)
✓ is able to pause and unpause fund activity (436ms)
✓ permits owner to remove funds (653ms)
4 passing  (2s)

Замечательно!

Комментарии: