Test suite
When building a complex contract ecosystem with multiple moving parts and dependencies, comprehensive testing is essential. This includes testing for both positive and negative scenarios. Positive tests should verify that each function's side effect is as expected, while negative tests should cover every revert, preferably in every logical branch.
Good test coverage has multiple effects.
It finds bugs and design flaws early (preaudit or prerelease).
It gives insight into areas for optimization (e.g., gas cost).
It displays code maturity.
It improves understanding of how the code functions, integrates, and operates — for developers and auditors alike.
We recommend creating unit tests for the following instructions:
StakeInstruction::SetLockup
StakeInstruction::AuthorizeWithSeed
StakeInstruction::DeactivateDelinquent
Additionally, we believe the following tests should be more comprehensive; that is, the following tests do not cover all positive or negative behaviors:
StakeInstruction::SetLockupChecked
StakeInstruction::AuthorizeCheckedWithSeed
Practically speaking, most of the code in the underlying state.rs module (used by the StakeInstruction::SetLockupChecked
and StakeInstruction::AuthorizeCheckedWithSeed
functions in particular) has been tested in the staking program tests. However, we recommend testing through the new BPF interface too for the aforementioned reasons.