Cadence Testing Framework
The Cadence testing framework provides a convenient way to write tests for Cadence programs in Cadence.
This functionality is provided by the built-in Test contract.
The testing framework can only be used off-chain, e.g. by using the Flow CLI.
Tests must be written in the form of a Cadence script.
A test script may contain testing functions that starts with the test prefix,
a setup function that always runs before the tests,
a tearDown function that always runs at the end of all test cases,
a beforeEach function that runs before each test case,
and an afterEach function that runs after each test case.
All the above four functions are optional.
_34// A `setup` function that always runs before the rest of the test cases._34// Can be used to initialize things that would be used across the test cases._34// e.g: initialling a blockchain backend, initializing a contract, etc._34access(all) fun setup() {_34}_34_34// The `beforeEach` function runs before each test case. Can be used to perform_34// some state cleanup before each test case, among other things._34access(all) fun beforeEach() {_34}_34_34// The `afterEach` function runs after each test case.  Can be used to perform_34// some state cleanup after each test case, among other things._34access(all) fun afterEach() {_34}_34_34// Valid test functions start with the 'test' prefix._34access(all) fun testSomething() {_34}_34_34access(all) fun testAnotherThing() {_34}_34_34access(all) fun testMoreThings() {_34}_34_34// Test functions cannot have any arguments or return values._34access(all) fun testInvalidSignature(message: String): Bool {_34}_34_34// A `tearDown` function that always runs at the end of all test cases._34// e.g: Can be used to stop the blockchain back-end used for tests, etc. or any cleanup._34access(all) fun tearDown() {_34}
Test Standard Library
The testing framework can be used by importing the built-in Test contract:
_10import Test
Assertions
Test.assert
_10fun assert(_ condition: Bool, message: String)
Fails a test-case if the given condition is false, and reports a message which explains why the condition is false.
The message argument is optional.
_10import Test_10_10access(all) fun testExample() {_10    Test.assert(2 == 2)_10    Test.assert([1, 2, 3].length == 0, message: "Array length is not 0")_10}
Test.fail
_10fun fail(message: String)
Immediately fails a test-case, with a message explaining the reason to fail the test.
The message argument is optional.
_10import Test_10_10access(all) fun testExample() {_10    let array = [1, 2, 3]_10_10    if array.length != 0 {_10        Test.fail(message: "Array length is not 0")_10    }_10}
Test.expect
_10fun expect(_ value: AnyStruct, _ matcher: Matcher)
The expect function tests a value against a matcher (see matchers section), and fails the test if it's not a match.
_10import Test_10_10access(all) fun testExample() {_10    let array = [1, 2, 3]_10_10    Test.expect(array.length, Test.equal(3))_10}
Test.assertEqual
_10fun assertEqual(_ expected: AnyStruct, _ actual: AnyStruct)
The assertEqual function fails the test-case if the given values are not equal, and
reports a message which explains how the two values differ.
_36import Test_36_36access(all) struct Foo {_36    access(all) let answer: Int_36_36    init(answer: Int) {_36        self.answer = answer_36    }_36}_36_36access(all) fun testExample() {_36    Test.assertEqual("this string", "this string")_36    Test.assertEqual(21, 21)_36    Test.assertEqual(true, true)_36    Test.assertEqual([1, 2, 3], [1, 2, 3])_36    Test.assertEqual(_36        {1: true, 2: false, 3: true},_36        {1: true, 2: false, 3: true}_36    )_36_36    let address1 = Address(0xf8d6e0586b0a20c7)_36    let address2 = Address(0xf8d6e0586b0a20c7)_36    Test.assertEqual(address1, address2)_36_36    let foo1 = Foo(answer: 42)_36    let foo2 = Foo(answer: 42)_36_36    Test.assertEqual(foo1, foo2)_36_36    let number1: Int64 = 100_36    let number2: UInt64 = 100_36    // Note that the two values need to have exactly the same type,_36    // and not just value, otherwise the assertion fails:_36    // assertion failed: not equal: expected: 100, actual: 100_36    Test.assertEqual(number1, number2)_36}
Test.expectFailure
_10fun expectFailure(_ functionWrapper: ((): Void), errorMessageSubstring: String)
The expectFailure function wraps a function call in a closure, and expects it to fail with
an error message that contains the given error message portion.
_24import Test_24_24access(all) struct Foo {_24    access(self) let answer: UInt8_24_24    init(answer: UInt8) {_24        self.answer = answer_24    }_24_24    access(all) fun correctAnswer(_ input: UInt8): Bool {_24        if self.answer != input {_24            panic("wrong answer!")_24        }_24        return true_24    }_24}_24_24access(all) fun testExample() {_24    let foo = Foo(answer: 42)_24_24    Test.expectFailure(fun(): Void {_24        foo.correctAnswer(43)_24    }, errorMessageSubstring: "wrong answer!")_24}
Matchers
A matcher is an object that consists of a test function and associated utility functionality.
_26access(all) struct Matcher {_26_26    access(all) let test: fun(AnyStruct): Bool_26_26    access(all) init(test: fun(AnyStruct): Bool) {_26        self.test = test_26    }_26_26    /// Combine this matcher with the given matcher._26    /// Returns a new matcher that succeeds if this and the given matcher succeed._26    ///_26    access(all) fun and(_ other: Matcher): Matcher {_26        return Matcher(test: fun (value: AnyStruct): Bool {_26            return self.test(value) && other.test(value)_26        })_26    }_26_26    /// Combine this matcher with the given matcher._26    /// Returns a new matcher that succeeds if this or the given matcher succeeds._26    ///_26    access(all) fun or(_ other: Matcher): Matcher {_26        return Matcher(test: fun (value: AnyStruct): Bool {_26            return self.test(value) || other.test(value)_26        })_26    }_26}
The test function defines the evaluation criteria for a value, and returns a boolean indicating whether the value
conforms to the test criteria defined in the function.
The and and or functions can be used to combine this matcher with another matcher to produce a new matcher with
multiple testing criteria.
The and method returns a new matcher that succeeds if both this and the given matcher are succeeded.
The or method returns a new matcher that succeeds if at-least this or the given matcher is succeeded.
A matcher that accepts a generic-typed test function can be constructed using the newMatcher function.
_10fun newMatcher<T: AnyStruct>(_ test: fun(T): Bool): Test.Matcher
The type parameter T is bound to AnyStruct type. It is also optional.
For example, a matcher that checks whether a given integer value is negative can be defined as follows:
_31import Test_31_31access(all) fun testExample() {_31    let isNegative = Test.newMatcher(fun (_ value: Int): Bool {_31        return value < 0_31    })_31_31    Test.expect(-15, isNegative)_31    // Alternatively, we can use `Test.assert` and the matcher's `test` function._31    Test.assert(isNegative.test(-15), message: "number is not negative")_31}_31_31access(all) fun testCustomMatcherUntyped() {_31    let matcher = Test.newMatcher(fun (_ value: AnyStruct): Bool {_31        if !value.getType().isSubtype(of: Type<Int>()) {_31            return false_31        }_31_31        return (value as! Int) > 5_31    })_31_31    Test.expect(8, matcher)_31}_31_31access(all) fun testCustomMatcherTyped() {_31    let matcher = Test.newMatcher<Int>(fun (_ value: Int): Bool {_31        return value == 7_31    })_31_31    Test.expect(7, matcher)_31}
The Test contract provides some built-in matcher functions for convenience.
Test.equal
_10fun equal(_ value: AnyStruct): Matcher
The equal function returns a matcher that succeeds if the tested value is equal to the given value.
Accepts an AnyStruct value.
_10import Test_10_10access(all) fun testExample() {_10    let array = [1, 2, 3]_10_10    Test.expect([1, 2, 3], Test.equal(array))_10}
Test.beGreaterThan
_10fun beGreaterThan(_ value: Number): Matcher
The beGreaterThan function returns a matcher that succeeds if the tested value is a number and
greater than the given number.
_10import Test_10_10access(all) fun testExample() {_10    let str = "Hello, there"_10_10    Test.expect(str.length, Test.beGreaterThan(5))_10}
Test.beLessThan
_10fun beLessThan(_ value: Number): Matcher
The beLessThan function returns a matcher that succeeds if the tested value is a number and
less than the given number.
_10import Test_10_10access(all) fun testExample() {_10    let str = "Hello, there"_10_10    Test.expect(str.length, Test.beLessThan(15))_10}
Test.beNil
_10fun beNil(): Matcher
The beNil function returns a new matcher that checks if the given test value is nil.
_10import Test_10_10access(all) fun testExample() {_10    let message: String? = nil_10_10    Test.expect(message, Test.beNil())_10}
Test.beEmpty
_10fun beEmpty(): Matcher
The beEmpty function returns a matcher that succeeds if the tested value is an array or dictionary,
and the tested value contains no elements.
_11import Test_11_11access(all) fun testExample() {_11    let array: [String] = []_11_11    Test.expect(array, Test.beEmpty())_11_11    let dictionary: {String: String} = {}_11_11    Test.expect(dictionary, Test.beEmpty())_11}
Test.haveElementCount
_10fun haveElementCount(_ count: Int): Matcher
The haveElementCount function returns a matcher that succeeds if the tested value is an array or dictionary,
and has the given number of elements.
_11import Test_11_11access(all) fun testExample() {_11    let array: [String] = ["one", "two", "three"]_11_11    Test.expect(array, Test.haveElementCount(3))_11_11    let dictionary: {String: Int} = {"one": 1, "two": 2, "three": 3}_11_11    Test.expect(dictionary, Test.haveElementCount(3))_11}
Test.contain
_10fun contain(_ element: AnyStruct): Matcher
The contain function returns a matcher that succeeds if the tested value is an array that contains
a value that is equal to the given value, or the tested value is a dictionary
that contains an entry where the key is equal to the given value.
_10access(all) fun testExample() {_10    let array: [String] = ["one", "two", "three"]_10_10    Test.expect(array, Test.contain("one"))_10_10    let dictionary: {String: Int} = {"one": 1, "two": 2, "three": 3}_10_10    Test.expect(dictionary, Test.contain("two"))_10}
Test.beSucceeded
_10fun beSucceeded(): Matcher
The beSucceeded function returns a new matcher that checks if the given test value is either
a ScriptResult or TransactionResult and the ResultStatus is succeeded.
Returns false in any other case.
_12import Test_12_12access(all) fun testExample() {_12    let blockchain = Test.newEmulatorBlockchain()_12    let result = blockchain.executeScript(_12        "access(all) fun main(): Int {  return 2 + 3 }",_12        []_12    )_12_12    Test.expect(result, Test.beSucceeded())_12    Test.assertEqual(5, result.returnValue! as! Int)_12}
Test.beFailed
_10fun beFailed(): Matcher
The beFailed function returns a new matcher that checks if the given test value is either
a ScriptResult or TransactionResult and the ResultStatus is failed.
Returns false in any other case.
_17import Test_17_17access(all) fun testExample() {_17    let blockchain = Test.newEmulatorBlockchain()_17    let account = blockchain.createAccount()_17_17    let tx = Test.Transaction(_17        code: "transaction { execute{ panic(\"some error\") } }",_17        authorizers: [],_17        signers: [account],_17        arguments: [],_17    )_17_17    let result = blockchain.executeTransaction(tx)_17_17    Test.expect(result, Test.beFailed())_17}
Matcher combinators
The built-in matchers, as well as custom matchers, can be combined with the three available combinators:
- not,
- or,
- and
in order to create more elaborate matchers and increase re-usability.
not
_10fun not(_ matcher: Matcher): Matcher
The not function returns a new matcher that negates the test of the given matcher.
_14import Test_14_14access(all) fun testExample() {_14    let isEven = Test.newMatcher<Int>(fun (_ value: Int): Bool {_14        return value % 2 == 0_14    })_14_14    Test.expect(8, isEven)_14    Test.expect(7, Test.not(isEven))_14_14    let isNotEmpty = Test.not(Test.beEmpty())_14_14    Test.expect([1, 2, 3], isNotEmpty)_14}
or
_10fun or(_ other: Matcher): Matcher
The Matcher.or function combines this matcher with the given matcher.
Returns a new matcher that succeeds if this or the given matcher succeed.
If this matcher succeeds, then the other matcher would not be tested.
_10import Test_10_10access(all) fun testExample() {_10    let one = Test.equal(1)_10    let two = Test.equal(2)_10_10    let oneOrTwo = one.or(two)_10_10    Test.expect(2, oneOrTwo)_10}
and
_10fun and(_ other: Matcher): Matcher
The Matcher.and function combines this matcher with the given matcher.
Returns a new matcher that succeeds if this and the given matcher succeed.
_14import Test_14_14access(all) fun testExample() {_14    let sevenOrMore = Test.newMatcher<Int>(fun (_ value: Int): Bool {_14        return value >= 7_14    })_14    let lessThanTen = Test.newMatcher<Int>(fun (_ value: Int): Bool {_14        return value <= 10_14    })_14_14    let betweenSevenAndTen = sevenOrMore.and(lessThanTen)_14_14    Test.expect(8, betweenSevenAndTen)_14}
Blockchain
A blockchain is an environment to which transactions can be submitted to, and against which scripts can be run. It imitates the behavior of a real network, for testing.
_133/// Blockchain emulates a real network._133///_133access(all) struct Blockchain {_133_133    access(all) let backend: AnyStruct{BlockchainBackend}_133_133    init(backend: AnyStruct{BlockchainBackend}) {_133        self.backend = backend_133    }_133_133    /// Executes a script and returns the script return value and the status._133    /// `returnValue` field of the result will be `nil` if the script failed._133    ///_133    access(all) fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult {_133        return self.backend.executeScript(script, arguments)_133    }_133_133    /// Creates a signer account by submitting an account creation transaction._133    /// The transaction is paid by the service account._133    /// The returned account can be used to sign and authorize transactions._133    ///_133    access(all) fun createAccount(): Account {_133        return self.backend.createAccount()_133    }_133_133    /// Add a transaction to the current block._133    ///_133    access(all) fun addTransaction(_ tx: Transaction) {_133        self.backend.addTransaction(tx)_133    }_133_133    /// Executes the next transaction in the block, if any._133    /// Returns the result of the transaction, or nil if no transaction was scheduled._133    ///_133    access(all) fun executeNextTransaction(): TransactionResult? {_133        return self.backend.executeNextTransaction()_133    }_133_133    /// Commit the current block._133    /// Committing will fail if there are un-executed transactions in the block._133    ///_133    access(all) fun commitBlock() {_133        self.backend.commitBlock()_133    }_133_133    /// Executes a given transaction and commits the current block._133    ///_133    access(all) fun executeTransaction(_ tx: Transaction): TransactionResult {_133        self.addTransaction(tx)_133        let txResult = self.executeNextTransaction()!_133        self.commitBlock()_133        return txResult_133    }_133_133    /// Executes a given set of transactions and commits the current block._133    ///_133    access(all) fun executeTransactions(_ transactions: [Transaction]): [TransactionResult] {_133        for tx in transactions {_133            self.addTransaction(tx)_133        }_133_133        var results: [TransactionResult] = []_133        for tx in transactions {_133            let txResult = self.executeNextTransaction()!_133            results.append(txResult)_133        }_133_133        self.commitBlock()_133        return results_133    }_133_133    /// Deploys a given contract, and initializes it with the arguments._133    ///_133    access(all) fun deployContract(_133        name: String,_133        code: String,_133        account: Account,_133        arguments: [AnyStruct]_133    ): Error? {_133        return self.backend.deployContract(_133            name: name,_133            code: code,_133            account: account,_133            arguments: arguments_133        )_133    }_133_133    /// Set the configuration to be used by the blockchain._133    /// Overrides any existing configuration._133    ///_133    access(all) fun useConfiguration(_ configuration: Configuration) {_133        self.backend.useConfiguration(configuration)_133    }_133_133    /// Returns all the logs from the blockchain, up to the calling point._133    ///_133    access(all) fun logs(): [String] {_133        return self.backend.logs()_133    }_133_133    /// Returns the service account of the blockchain. Can be used to sign_133    /// transactions with this account._133    ///_133    access(all) fun serviceAccount(): Account {_133        return self.backend.serviceAccount()_133    }_133_133    /// Returns all events emitted from the blockchain._133    ///_133    access(all) fun events(): [AnyStruct] {_133        return self.backend.events(nil)_133    }_133_133    /// Returns all events emitted from the blockchain,_133    /// filtered by type._133    ///_133    access(all) fun eventsOfType(_ type: Type): [AnyStruct] {_133        return self.backend.events(type)_133    }_133_133    /// Resets the state of the blockchain to the given height._133    ///_133    access(all) fun reset(to height: UInt64) {_133        self.backend.reset(to: height)_133    }_133_133    /// Moves the time of the blockchain by the given delta,_133    /// which should be passed in the form of seconds._133    ///_133    access(all) fun moveTime(by delta: Fix64) {_133        self.backend.moveTime(by: delta)_133    }_133}
The BlockchainBackend provides the actual functionality of the blockchain.
_33/// BlockchainBackend is the interface to be implemented by the backend providers._33///_33access(all) struct interface BlockchainBackend {_33_33    access(all) fun executeScript(_ script: String, _ arguments: [AnyStruct]): ScriptResult_33_33    access(all) fun createAccount(): Account_33_33    access(all) fun addTransaction(_ tx: Transaction)_33_33    access(all) fun executeNextTransaction(): TransactionResult?_33_33    access(all) fun commitBlock()_33_33    access(all) fun deployContract(_33        name: String,_33        code: String,_33        account: Account,_33        arguments: [AnyStruct]_33    ): Error?_33_33    access(all) fun useConfiguration(_ configuration: Configuration)_33_33    access(all) fun logs(): [String]_33_33    access(all) fun serviceAccount(): Account_33_33    access(all) fun events(_ type: Type?): [AnyStruct]_33_33    access(all) fun reset(to height: UInt64)_33_33    access(all) fun moveTime(by delta: Fix64)_33}
Creating a blockchain
A new blockchain instance can be created using the Test.newEmulatorBlockchain method.
It returns a Blockchain which is backed by a new Flow Emulator instance.
_10import Test_10_10access(all) let blockchain = Test.newEmulatorBlockchain()
Creating accounts
It may be necessary to create accounts during tests for various reasons, such as for deploying contracts, signing transactions, etc.
An account can be created using the createAccount function.
_10import Test_10_10access(all) let blockchain = Test.newEmulatorBlockchain()_10access(all) let account = blockchain.createAccount()_10_10access(all) fun testExample() {_10    log(account.address)_10}
Running the above command, from the command-line, we would get:
_10flow test tests/test_sample_usage.cdc_103:31PM DBG LOG: 0x01cf0e2f2f715450_10_10Test results: "tests/test_sample_usage.cdc"_10- PASS: testExample
The returned account consists of the address of the account, and a publicKey associated with it.
_11/// Account represents info about the account created on the blockchain._11///_11access(all) struct Account {_11    access(all) let address: Address_11    access(all) let publicKey: PublicKey_11_11    init(address: Address, publicKey: PublicKey) {_11        self.address = address_11        self.publicKey = publicKey_11    }_11}
Executing scripts
Scripts can be run with the executeScript function, which returns a ScriptResult.
The function takes script-code as the first argument, and the script-arguments as an array as the second argument.
_19import Test_19_19access(all) let blockchain = Test.newEmulatorBlockchain()_19_19access(all) fun testExample() {_19    let code = "access(all) fun main(name: String): String { return \"Hello, \".concat(name) }"_19    let args = ["Peter"]_19_19    let scriptResult = blockchain.executeScript(code, args)_19_19    // Assert that the script was successfully executed._19    Test.expect(scriptResult, Test.beSucceeded())_19_19    // returnValue has always the type `AnyStruct`,_19    // so we need to type-cast accordingly._19    let returnValue = scriptResult.returnValue! as! String_19_19    Test.assertEqual("Hello, Peter", returnValue)_19}
The script result consists of the status of the script execution, and a returnValue if the script execution was
successful, or an error otherwise (see errors section for more details on errors).
_13/// The result of a script execution._13///_13access(all) struct ScriptResult {_13    access(all) let status: ResultStatus_13    access(all) let returnValue: AnyStruct?_13    access(all) let error: Error?_13_13    init(status: ResultStatus, returnValue: AnyStruct?, error: Error?) {_13        self.status = status_13        self.returnValue = returnValue_13        self.error = error_13    }_13}
Executing transactions
A transaction must be created with the transaction code, a list of authorizes, a list of signers that would sign the transaction, and the transaction arguments.
_15/// Transaction that can be submitted and executed on the blockchain._15///_15access(all) struct Transaction {_15    access(all) let code: String_15    access(all) let authorizers: [Address]_15    access(all) let signers: [Account]_15    access(all) let arguments: [AnyStruct]_15_15    init(code: String, authorizers: [Address], signers: [Account], arguments: [AnyStruct]) {_15        self.code = code_15        self.authorizers = authorizers_15        self.signers = signers_15        self.arguments = arguments_15    }_15}
The number of authorizers must match the number of AuthAccount arguments in the prepare block of the transaction.
_39import Test_39_39access(all) let blockchain = Test.newEmulatorBlockchain()_39access(all) let account = blockchain.createAccount()_39_39// There are two ways to execute the created transaction._39_39access(all) fun testExample() {_39    let tx = Test.Transaction(_39        code: "transaction { prepare(acct: AuthAccount) {} execute{} }",_39        authorizers: [account.address],_39        signers: [account],_39        arguments: [],_39    )_39_39    // Executing the transaction immediately_39    // This may fail if the current block contains_39    // transactions that have not being executed yet._39    let txResult = blockchain.executeTransaction(tx)_39_39    Test.expect(txResult, Test.beSucceeded())_39}_39_39access(all) fun testExampleTwo() {_39    let tx = Test.Transaction(_39        code: "transaction { prepare(acct: AuthAccount) {} execute{} }",_39        authorizers: [account.address],_39        signers: [account],_39        arguments: [],_39    )_39_39    // Add to the current block_39    blockchain.addTransaction(tx)_39_39    // Execute the next transaction in the block_39    let txResult = blockchain.executeNextTransaction()!_39_39    Test.expect(txResult, Test.beSucceeded())_39}
The result of a transaction consists of the status of the execution, and an Error if the transaction failed.
_11/// The result of a transaction execution._11///_11access(all) struct TransactionResult {_11    access(all) let status: ResultStatus_11    access(all) let error: Error?_11_11    init(status: ResultStatus, error: Error?) {_11        self.status = status_11        self.error = error_11    }_11 }
Commit block
commitBlock block will commit the current block, and will fail if there are any un-executed transactions in the block.
_20import Test_20_20access(all) let blockchain = Test.newEmulatorBlockchain()_20access(all) let account = blockchain.createAccount()_20_20access(all) fun testExample() {_20    let tx = Test.Transaction(_20        code: "transaction { prepare(acct: AuthAccount) {} execute{} }",_20        authorizers: [account.address],_20        signers: [account],_20        arguments: [],_20    )_20_20    blockchain.commitBlock()_20_20    blockchain.addTransaction(tx)_20_20    // This will fail with `error: internal error: pending block with ID 1f9...c0b7740d2 cannot be committed before execution`_20    blockchain.commitBlock()_20}
Deploying contracts
A contract can be deployed using the deployContract function of the Blockchain.
Suppose we have this contract (Foo.cdc):
_11access(all) contract Foo {_11    access(all) let msg: String_11_11    init(_ msg: String) {_11        self.msg = msg_11    }_11_11    access(all) fun sayHello(): String {_11        return self.msg_11    }_11}
_16import Test_16_16access(all) let blockchain = Test.newEmulatorBlockchain()_16access(all) let account = blockchain.createAccount()_16_16access(all) fun testExample() {_16    let contractCode = Test.readFile("Foo.cdc")_16    let err = blockchain.deployContract(_16        name: "Foo",_16        code: contractCode,_16        account: account,_16        arguments: ["hello from args"],_16    )_16_16    Test.expect(err, Test.beNil())_16}
An Error is returned if the contract deployment fails. Otherwise, a nil is returned.
Configuring import addresses
A common pattern in Cadence projects is to define the imports as file locations and specify the addresses corresponding to each network in the Flow CLI configuration file. When writing tests for such a project, it may also require to specify the addresses to be used during the tests as well. However, during tests, since accounts are created dynamically and the addresses are also generated dynamically, specifying the addresses statically in a configuration file is not an option.
Hence, the test framework provides a way to specify the addresses using the
useConfiguration(_ configuration: Test.Configuration) function in Blockchain.
The Configuration struct consists of a mapping of import locations to their addresses.
_10/// Configuration to be used by the blockchain._10/// Can be used to set the address mapping._10///_10access(all) struct Configuration {_10    access(all) let addresses: {String: Address}_10_10    init(addresses: {String: Address}) {_10        self.addresses = addresses_10    }_10}
The Blockchain.useConfiguration is a run-time alternative for
statically defining contract addresses in the flow.json config file.
The configurations can be specified during the test setup as a best-practice.
e.g: Assume running a script that imports the above Foo.cdc contract.
The import location for the contract can be specified using the placeholder "Foo".
This placeholder can be any unique string.
Suppose this script is saved in say_hello.cdc.
_10import "Foo"_10_10access(all) fun main(): String {_10    return Foo.sayHello()_10}
Then, before executing the script, the address mapping can be specified as follows:
_31import Test_31_31access(all) let blockchain = Test.newEmulatorBlockchain()_31access(all) let account = blockchain.createAccount()_31_31access(all) fun setup() {_31    blockchain.useConfiguration(Test.Configuration({_31        "Foo": account.address_31    }))_31_31    let contractCode = Test.readFile("Foo.cdc")_31    let err = blockchain.deployContract(_31        name: "Foo",_31        code: contractCode,_31        account: account,_31        arguments: ["hello from args"],_31    )_31_31    Test.expect(err, Test.beNil())_31}_31_31access(all) fun testExample() {_31    let script = Test.readFile("say_hello.cdc")_31    let scriptResult = blockchain.executeScript(script, [])_31_31    Test.expect(scriptResult, Test.beSucceeded())_31_31    let returnValue = scriptResult.returnValue! as! String_31_31    Test.assertEqual("hello from args", returnValue)_31}
The subsequent operations on the blockchain (e.g: contract deployment, script/transaction execution) will resolve the import locations to the provided addresses.
Errors
An Error maybe returned when an operation (such as executing a script, executing a transaction, etc.) has failed.
It contains a message indicating why the operation failed.
_10// Error is returned if something has gone wrong._10//_10access(all) struct Error {_10    access(all) let message: String_10_10    init(_ message: String) {_10        self.message = message_10    }_10}
An Error can be asserted against its presence or absence.
_29import Test_29_29access(all) let blockchain = Test.newEmulatorBlockchain()_29access(all) let account = blockchain.createAccount()_29_29access(all) fun testExample() {_29    let script = Test.readFile("say_hello.cdc")_29    let scriptResult = blockchain.executeScript(script, [])_29_29    // If we expect a script to fail, we can use Test.beFailed() instead_29    Test.expect(scriptResult, Test.beSucceeded())_29_29    let tx = Test.Transaction(_29        code: "transaction { prepare(acct: AuthAccount) {} execute{} }",_29        authorizers: [account.address],_29        signers: [account],_29        arguments: [],_29    )_29    let txResult = blockchain.executeTransaction(tx)_29_29    // If we expect a transaction to fail, we can use Test.beFailed() instead_29    Test.expect(txResult, Test.beSucceeded())_29_29    let err: Test.Error? = txResult.error_29_29    if err != nil {_29        log(err!.message)_29    }_29}
Blockchain events
We can also assert that certain events were emitted from the blockchain, up to the latest block.
Suppose we have this contract (Foo.cdc):
_14access(all) contract Foo {_14    access(all) let msg: String_14_14    access(all) event ContractInitialized(msg: String)_14_14    init(_ msg: String) {_14        self.msg = msg_14        emit ContractInitialized(msg: self.msg)_14    }_14_14    access(all) fun sayHello(): String {_14        return self.msg_14    }_14}
_31import Test_31_31access(all) let blockchain = Test.newEmulatorBlockchain()_31access(all) let account = blockchain.createAccount()_31_31access(all) fun setup() {_31    blockchain.useConfiguration(Test.Configuration({_31        "Foo": account.address_31    }))_31_31    let contractCode = Test.readFile("Foo.cdc")_31    let err = blockchain.deployContract(_31        name: "Foo",_31        code: contractCode,_31        account: account,_31        arguments: ["hello from args"],_31    )_31_31    Test.expect(err, Test.beNil())_31_31    // As of now, we have to construct the composite type by hand,_31    // until the testing framework allows developers to import_31    // contract types, e.g.:_31    // let typ = Type<FooContract.ContractInitialized>()_31    let typ = CompositeType("A.01cf0e2f2f715450.Foo.ContractInitialized")!_31    let events = blockchain.eventsOfType(typ)_31    Test.assertEqual(1, events.length)_31_31    // We can also fetch all events emitted from the blockchain_31    log(blockchain.events())_31}
Commonly used contracts
The commonly used contracts are already deployed on the blockchain, and can be imported without any additional setup.
Suppose this script is saved in get_type_ids.cdc.
_16import "FungibleToken"_16import "FlowToken"_16import "NonFungibleToken"_16import "MetadataViews"_16import "ViewResolver"_16import "ExampleNFT"_16import "NFTStorefrontV2"_16import "NFTStorefront"_16_16access(all) fun main(): [String] {_16    return [_16        Type<FlowToken>().identifier,_16        Type<NonFungibleToken>().identifier,_16        Type<MetadataViews>().identifier_16    ]_16}
_20import Test_20_20access(all) let blockchain = Test.newEmulatorBlockchain()_20_20access(all) fun testExample() {_20    let script = Test.readFile("get_type_ids.cdc")_20    let scriptResult = blockchain.executeScript(script, [])_20_20    Test.expect(scriptResult, Test.beSucceeded())_20_20    let returnValue = scriptResult.returnValue! as! [String]_20_20    let expected = [_20        "A.0ae53cb6e3f42a79.FlowToken",_20        "A.f8d6e0586b0a20c7.NonFungibleToken",_20        "A.f8d6e0586b0a20c7.MetadataViews"_20    ]_20_20    Test.assertEqual(expected, returnValue)_20}
Reading from files
Writing tests often require constructing source-code of contracts/transactions/scripts in the test script. Testing framework provides a convenient way to load programs from a local file, without having to manually construct them within the test script.
_10let contractCode = Test.readFile("./sample/contracts/FooContract.cdc")
readFile returns the content of the file as a string.
Logging
The log function is available for usage both in test scripts, as well as contracts/scripts/transactions.
The Blockchain.logs() method aggregates all logs from contracts/scripts/transactions.
_18import Test_18_18access(all) let blockchain = Test.newEmulatorBlockchain()_18access(all) let account = blockchain.createAccount()_18_18access(all) fun testExample() {_18    let tx = Test.Transaction(_18        code: "transaction { prepare(acct: AuthAccount) {} execute{ log(\"in a transaction\") } }",_18        authorizers: [account.address],_18        signers: [account],_18        arguments: [],_18    )_18_18    let txResult = blockchain.executeTransaction(tx)_18_18    Test.expect(txResult, Test.beSucceeded())_18    Test.assertEqual(["in a transaction"], blockchain.logs())_18}
Examples
This repository contains some functional examples that demonstrate most of the above features, both for contrived and real-world smart contracts. It also contains a detailed explanation on using code coverage from within the testing framework.