8.1 单元测试(Unit Testing)

Forc provides built-in support for building and executing tests for a package.

Forc 为包的构建和执行测试,提供内置支持。

Tests are written as free functions with the #[test] attribute. For example:

测试被编写为带有#[test] 属性的自由函数。例如:

#[test]
fn test_meaning_of_life() {
    assert(6 * 7 == 42);
}

Each test function is ran as if it were the entry point for a script. Tests "pass" if they return successfully, and "fail" if they revert or vice versa while testing failure.

每个测试函数的运行就好像它是一个 脚本 的入点一样。如果成功返回则测试“通过”,否则返回“失败”,在 测试失败时也一样。

If the project has failing tests forc test will exit with exit status 101.

如果项目的测试失败,forc test 将以状态 101 退出。

构建和运行测试(Building and Running Tests)

We can build and execute all tests within a package with the following:

我们可以使用以下命令在一个包中构建和执行所有测试:

forc test

The output should look similar to this:

输出应与此类似:

  Compiled library "core".
  Compiled library "std".
  Compiled library "lib_single_test".
  Bytecode size is 92 bytes.
   Running 1 tests
      test test_meaning_of_life ... ok (170.652µs)
   Result: OK. 1 passed. 0 failed. Finished in 1.564996ms.

Visit the forc test command reference to find the options available for forc test.

访问 forc test 命令,就可以参考/查找可用于 forc test 的选项。

测试失败(Testing Failure )

Forc supports testing failing cases for test functions declared with #[test(should_revert)]. For example:

Forc 支持用#[test(should_revert)] 声明的测试函数测试失败的案例。例如:

#[test(should_revert)]
fn test_meaning_of_life() {
    assert(6 * 6 == 42);
}

Tests with #[test(should_revert)] considered to be passing if they are reverting.

调用合约(Calling Contracts)

Unit tests can call contract functions an example for such calls can be seen below.

单元测试可以调用合约函数,下面可以看到此类调用的示例。

contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}

To test the test_function(), a unit test like the following can be written.

要测试 test_function(),可以编写如下单元测试。

#[test]
fn test_success() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == true)
}

It is also possible to test failure with contract calls as well.

也可以通过合约调用来测试失败。

#[test(should_revert)]
fn test_fail() {
    let caller = abi(MyContract, CONTRACT_ID);
    let result = caller.test_function {}();
    assert(result == false)
}

Note: When running forc test, your contract will be built twice: first without unit tests in order to determine the contract's ID, then a second time with unit tests with the CONTRACT_ID provided to their namespace. This CONTRACT_ID can be used with the abi cast to enable contract calls within unit tests.

注意: 当运行 forc test 时,您的合约将构建两次:第一次 不包括 without 单元测试来确定合约的 ID,然后第二次 包括with 单元测试来提供给其命名空间的 CONTRACT_ID。此 CONTRACT_ID 可与 abi cast 一起使用,以在单元测试中启用合约调用。

Unit tests can call methods of external contracts if those contracts are added as contract dependencies, i.e. in the the contract-dependencies section of the manifest file. An example of such calls is shown below:

如果这些合约被添加为合约一来,即在 [contract-dependencies](https://fuellabs.github.io/sway/v0.38.0/book/forc/manifest_reference .html#the-contract-dependencies-section) 清单文件的部分。此类调用的示例如下所示:

contract;

abi CallerContract {
    fn test_false() -> bool;
}

impl CallerContract for Contract {
    fn test_false() -> bool {
        false
    }
}

abi CalleeContract {
    fn test_true() -> bool;
}

#[test]
fn test_multi_contract_calls() {
    let caller = abi(CallerContract, CONTRACT_ID);
    let callee = abi(CalleeContract, callee::CONTRACT_ID);

    let should_be_false = caller.test_false();
    let should_be_true = callee.test_true();
    assert(!should_be_false);
    assert(should_be_true);
}

Example Forc.toml for contract above:

上面合约的示例Forc.toml

[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
name = "caller"

[dependencies]
std = { path = "../../../sway-lib-std/" }

[contract-dependencies]
callee = { path = "../callee" }

并行或串行运行测试 (Running Tests in Parallel or Serially)

By default, all unit tests in your project are run in parallel. Note that this does not lead to any data races in storage because each unit test has its own storage space that is not shared by any other unit test.

默认情况下,项目中的所有单元测试都是并行运行的。请注意,这不会导致存储中的任何数据竞争,因为每个单元测试都有自己的存储空间,不与任何其他单元测试共享。

By default, forc test will use all the available threads in your system. To request that a specific number of threads be used, the flag --test-threads <val> can be provided to forc test.

默认情况下,forc test 将使用您系统中的所有可用线程。要请求使用特定数量的线程,可以将标志 --test-threads <val> 提供给 forc test

forc test --test-threads 1

Last updated