'Elrond mandos test elrond_wasm_debug::mandos_rs pass however erdpy contract test fail

I'm writing test cases for my NFT smart contract (SC). When I check the state of the SC after creating my NFT I'm expecting to see a variable (next_index_to_mint:u64, that's I increase by 1 every new NFT) to be updated.

So I'm running the test using the command:

$ erdpy contract test
INFO:projects.core:run_tests.project: /Users/<user>/sc_nft
INFO:myprocess:run_process: ['/Users/<user>/elrondsdk/vmtools/mandos-test', '/Users/<user>/sc_nft/mandos'], in folder: None
CRITICAL:cli:External process error:
Command line: ['/Users/<user>/elrondsdk/vmtools/mandos-test', '/Users/<user>/sc_nft/mandos']
Output: Scenario: buy_nft.scen.json ...   FAIL: wrong account storage for account "sc:nft-minter":
  for key 0x6e657874496e646578546f4d696e74 (str:nextIndexToMint): Want: "0x02". Have: ""
Scenario: create_nft.scen.json ...   FAIL: wrong account storage for account "sc:nft-minter":
  for key 0x6e657874496e646578546f4d696e74 (str:nextIndexToMint): Want: "0x02". Have: ""
Scenario: init.scen.json ...   ok
Done. Passed: 1. Failed: 2. Skipped: 0.
ERROR: some tests failed

However, when I'm running the test using elrond_wasm_debug::mandos_rs function with the create_nft.scen.json file, it passed.

use elrond_wasm_debug::*;

fn world() -> BlockchainMock {
    let mut blockchain = BlockchainMock::new();
    blockchain.set_current_dir_from_workspace("");

    blockchain.register_contract_builder("file:output/test.wasm", nft_auth_card::ContractBuilder);
    blockchain
}

#[test]
fn create_nft() {
    elrond_wasm_debug::mandos_rs("mandos/create_nft.scen.json", world());
}

BTW, if you want to add this to the NFT SC example, that would be great in the tests/ folder.

I tried to put an incorrect value, and it failed as expected. So my question is how could it be possible that it work using mandos elrond_wasm debug but not erdpy ?

running 1 test
thread 'create_nft' panicked at 'bad storage value. Address: sc:nft-minter. Key: str:nextIndexToMint. Want: "0x04". Have: 0x02', /Users/<user>/elrondsdk/vendor-rust/registry/src/github.com-1ecc6299db9ec823/elrond-wasm-debug-0.28.0/src/mandos_step/check_state.rs:56:21

Here is the code (I use the default NFT SC example):

const NFT_INDEX: u64 = 0;
fn create_nft_with_attributes<T: TopEncode>(...) -> u64 {
    ...
    self.next_index_to_mint().set_if_empty(&NFT_INDEX);
    let next_index_to_mint = self.next_index_to_mint().get();
    self.next_index_to_mint().set(next_index_to_mint+1);
    ...
}

#[storage_mapper("nextIndexToMint")]
fn next_index_to_mint(&self) -> SingleValueMapper<u64>;


Solution 1:[1]

Short answer: most likely you haven't re-built your contract before testing it with erdpy.

Long answer: currently there are two ways mandos tests are executed, as you've exemplified in your case:

  • Run tests directly from rust through mandos_rs
  • Run tests through erdpy (which in turn uses mandos_go)

These two frameworks (mandos_rs and mandos_go) are functioning in different ways:

  • mandos_rs: this framework is running on your rust code directly and it's testing it agains a mocked VM and mocked blockchain in the background. Therefore, it's not necessary to build your contract when using mandos_rs.
  • mandos_go: this framework is testing your compiled contract against a REAL VM with mocked blockchain in the background, so it's necessary to build your latest changes into a .wasm bytecode (e.g. erdpy contract build) before running the tests via mandos_go, as this compiled file will be loaded by the VM like in a real use scenario.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Brother Jder