Rust 스마트 계약 개발에 대한 이전 BlockSec 기사에서 계약 StatusMessage에 대한 계약 상태를 정의하는 방법을 소개하고 계약에 대한 다양한 방법을 구현했습니다. 이번 호에서는 계속해서 컨트랙트를 기반으로 서술하고, 단위 테스트 케이스 작성 방법을 자세히 소개하고, 컨트랙트를 현지에서 테스트해보도록 하겠습니다.1. 단위 테스트 환경 준비
1 #[cfg(not(target_arch = "wasm32"))]
2 #[cfg(test)]
3 mod tests {
4 use super::*;
5 use near_sdk::MockedBlockchain;
6 use near_sdk::{testing_env, VMContext};
7
8 ...
9}
단위 테스트를 작성하려면 먼저 다음 코드를 src/lib.rs에 추가하여 단위 테스트 환경을 설정해야 합니다."wasm32"))]。
위 코드의 1-3행에서 StatusMessage에 대한 테스트 하위 모듈(mod 키워드를 사용하여 새 모듈 선언)을 추가하고 모듈의 코드 스니펫 앞에 cfg 속성 매크로 #[cfg(test)]를 표시했습니다. 또한 Rust의 기본 단위 테스트는 Wasm 코드를 가져올 필요가 없으므로 Rust 컴파일 조건으로 테스트 모듈을 구성할 수 있습니다. #[cfg(not(target_arch =
코드의 4-6행은 near_sdk(NEAR의 소프트웨어 개발 키트)에서 계약 테스트 환경의 관련 종속성을 가져옵니다. 특히, 코드의 각 줄에서 use 키워드의 사용법은 다른 종속 모듈을 가져올 때 Python 언어 코드에서 사용하는 가져오기와 유사합니다. use 선언은 다른 경로와 동의어인 하나 이상의 로컬 이름 바인딩을 생성합니다. 즉, use 키워드는 종종 모듈 항목을 참조하는 데 필요한 경로를 선언하는 데 사용되며 이러한 선언은 일반적으로 Rust 모듈 또는 코드 블록 .
4행에서 super 키워드는 현재 모듈에서 상위 모듈 StatusMessage에 액세스하는 데 사용할 수 있으며, 이전에 StatusMessage 계약에 대해 정의한 메소드 함수 set_status 및 get_status와 같이 상위 모듈에 정의된 함수 및 메소드에 대한 액세스를 가능하게 합니다. 5행은 use 키워드를 사용하여 스마트 계약 테스트에 사용할 수 있는 nearsdk에서 제공하는 모의 블록체인 MockedBlockchain 지원 모듈을 참조합니다. 6행은 nearsdk의 계약 테스트 실행 환경과 테스트 환경의 컨텍스트 정보 형식 지원을 소개합니다.
1 fn get_default_context(view_call: bool) -> VMContext {
2 VMContext {
3 current_account_id: "alice_near".to_string(),
4 signer_account_id: "bob_near".to_string(),
5 signer_account_pk: vec!,
6 predecessor_account_id: "carol_near".to_string(),
7 input: vec!,
8 block_index: 0,
9 block_timestamp: 0,
10 account_balance: 0,
11 account_locked_balance: 0,
12 storage_usage: 0,
13 attached_deposit: 0,
14 prepaid_gas: 10u64.pow(18),
15 random_seed: vec!,
16 is_view: view_call,
17 output_data_receivers: vec!,
18 epoch_height: 0,
19 }
20 }
NEAR 스마트 계약 단위 테스트를 지원하는 데 필요한 외부 종속성 모듈을 가져온 후 테스트 환경에 필요한 컨텍스트 정보를 구성하고 반환하기 위해 테스트 모듈에서 다음 함수 get_context()를 정의해야 합니다. VMContext.
VMContext는 여러 시뮬레이션, 컨트랙트 사용자 계정 정보, 블록 높이, 블록 타임스탬프, 컨트랙트 스토리지 사용량 등 블록체인의 하단 레이어와 관련된 컨텍스트 구성 정보를 설정합니다.
다음은 먼저 VMContext의 몇 가지 주요 특성 구성을 설명합니다.
current_account_id: 현재 계약을 실행하는 계정입니다. signer_account_id: 현재 계약 함수 호출의 실행을 트리거하는 트랜잭션 서명자입니다. 모든 계약 호출은 트랜잭션의 결과이며 트랜잭션은 signer_account_id인 액세스 키를 사용하여 계정에 의해 서명됩니다. signer_account_pk: 트랜잭션 서명자가 사용하는 액세스 키 공개 키(Public Key). 이전 계정_ID: 계약 실행이 계약 간 호출 또는 콜백인 경우 이 속성은 호출의 개시자 계정을 참조합니다. 단일 계약 내부 함수 호출을 수행할 때 이 값은 signer_account_id와 일치합니다. prepaid_gas: 블록체인에서 컨트랙트를 실행할 때 사용자가 일정한 거래 실행 수수료(가스 수수료)를 지불해야 하는 기능이 있습니다. 여기서 prepaid_gas는 현재 트랜잭션 컨트랙트 함수 호출 시 차감할 수 있는 Gas의 최대값을 설정하여 현재 컨트랙트 호출에 추가합니다. is_view: 매개 변수 is_view(유형은 bool)는 계약 함수 호출이 계약의 상태 데이터를 수정할 수 있는지 여부를 설정할 수 있습니다. 값이 true이면 계약 기능이 실행될 때 계약의 상태 데이터가 읽기 전용입니다. 반대로 값이 거짓이면 계약 실행 환경에서 계약 데이터 수정을 허용합니다. VMContext에 있는 나머지 특성의 내용과 사용법은 후속 기사에서 자세히 설명합니다.
near_sdk::env::current_account_id()
near_sdk::env::predecessor_account_id()
near_sdk::env::signer_account_pk()
near_sdk::env::input()
near_sdk::env::predecessor_account_id()
NEAR 계약을 실행할 때 프로그램은 설정된 컨텍스트 정보를 읽기 위해 NEAR SDK에서 제공하는 일부 관련 API와 협력할 수 있습니다. 예를 들어:
위의 모든 API는 컨텍스트별 속성 값을 반환하며 이러한 API는 앞에서 설명한 use 문을 사용하여 가져올 수 있습니다.
get_context() 함수를 정의한 후 단위 테스트 내용을 테스트 모듈에 하나씩 작성할 수 있습니다.
2. 단위 테스트 1
1 #[test]
2 fn set_get_message() {
3 let context = get_default_context(false);
4 testing_env!(context);
5 let mut contract = StatusMessage::default();
6 contract.set_status("hello".to_string());
7 assert_eq!(
8 "hello".to_string(),
9 contract.get_status("bob_near".to_string()).unwrap()
10 );
11 }
다음은 단위 테스트 1의 코드 스니펫입니다.
이제 테스트 케이스를 작성하는 구체적인 방법을 설명합니다.
위 코드 스니펫의 1행에서 #[test] 매크로로 단위 테스트 함수를 표시하여 이것이 단위 테스트의 시작점임을 나타냅니다. 2행 바로 다음은 단위 테스트 함수 set_get_message()의 선언입니다.
코드의 3-10행은 단위 테스트 함수 내부의 기본 테스트 논리입니다. 여기서 코드 구현은 먼저 이전에 정의된 get_context를 호출하여 테스트 환경에서 사용되는 컨텍스트 컨텍스트를 초기화합니다. 또한 이 단위 테스트는 계약의 상태 데이터에 데이터를 기록해야 하므로 get_context에 대한 매개 변수를 설정하고 위에서 언급한 VMContext의 is_view 속성을 false로 설정해야 합니다. 그렇지 않으면 패닉이 발생합니다. 단위 테스트 내에서 트리거됩니다. 테스트가 실패했습니다.
합리적인 계약 실행 컨텍스트를 설정한 후 코드의 4행은 컨텍스트 VMContext를 사용하여 testing_env! 매크로를 사용하여 스마트 계약 상호 작용을 위한 MockedBlockchain 인스턴스를 초기화합니다. 코드의 5행은 부모 모듈에 정의된 StatusMessage::default()를 호출하여 초기화된 계약 개체 계약을 생성합니다."Hello"후속 코드에서 테스트는 먼저 부모 모듈 StatusMessage에서 정의한 set_status 메서드를 호출하여 계약 상태 데이터에 문자열을 저장합니다."assertion failed". 그런 다음 get_status를 사용하여 계약 상태 데이터에서 데이터를 읽고 예상 내용과 비교합니다. 콘텐츠가 서로 일치하면 이 단위 테스트를 통과하고 일치하지 않으면 이 테스트 스레드에서 실행합니다.
일종의 패닉.
단위 테스트에서 검증을 위해 assert를 사용하는 작성 방법은 다음과 같습니다.
assert_eq!(left,assert!(expression) 매크로는 부울 값을 확인하고 표현식 표현식이 참조하는 내용이 참인 경우에만 테스트를 통과할 수 있습니다.
assert_ne!(left,오른쪽) 매크로는 종종 그들이 같은지 여부를 확인하는 데 사용되며 왼쪽 및 오른쪽 표현식이 참조하는 내용이 일치하는 경우에만 검사를 통과합니다.
오른쪽) 매크로는 서로 다른지 여부를 확인하는 데 자주 사용되며 왼쪽 및 오른쪽 표현식이 참조하는 내용이 다른 경우에만 확인을 통과합니다.
3. 단위 테스트 2
1 #[test]
2 fn get_nonexistent_message() {
3 let context = get_default_context(true);
4 testing_env!(context);
5 let contract = StatusMessage::default();
6 assert_eq!(None, contract.get_status("francis.near".to_string()));
7 }
다음은 단위 테스트 2의 코드 스니펫입니다.
6행의 테스트에서 assert_eq의 오른쪽에 있는 표현식은 get_status 계약 메서드를 사용하여 계약 상태 데이터에서 StatusMessage 계약 사용자 francis.near에 해당하는 메시지 정보를 쿼리하려고 시도합니다. 다만, 코드 5행은 컨트랙트 전체의 상태만 초기화하기 때문에 이때의 컨트랙트 데이터는 전체적으로 비어 있으므로 반환값은 None이 됩니다. 마지막으로 결과가 예상한 대로이므로 어설션이 올바르고 단위 테스트를 통과할 수 있습니다.
4. 테스트 케이스 실행
[dependencies]
near-sdk = "3.1.0"
위의 단위 테스트를 작성한 후 StatusMessage Rust 프로젝트에서 컨트랙트의 Cargo.toml 파일도 구성해야 합니다. 즉, 파일의 [dependencies] 섹션에 near-sdk에 대한 종속성을 추가해야 합니다(버전 번호는 3.1.0).
use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::collections::LookupMap;
use near_sdk::{env, near_bindgen};
동시에 src/lib.rs 파일의 시작 부분에 있는 near_sdk에서 이러한 모듈 또는 패키지를 가져와야 합니다.
$ cargo test --package status-message
계약 프로젝트의 종속성을 구성한 후 cargo를 사용하여 모든 단위 테스트 사례를 실행할 수 있습니다. 구체적인 명령은 다음과 같습니다.
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in0.00s
테스트는 특정 테스트 결과를 반환합니다.
$ cargo test --package status-message set_get_message
마찬가지로 개별 테스트의 결과를 얻을 수 있습니다.
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in0.00s
이 문제의 요약 및 미리 보기
이 문제의 요약 및 미리 보기