What is the Branching Tree Technique?
The Branching Tree Technique (BTT) is a structured approach to test case design that ensures comprehensive coverage of all possible scenarios and edge cases in your smart contract tests.
BTT organizes test cases in a tree-like structure, where:
- ├──Branches represent different conditions or states
- └──Leaves represent specific test cases or assertions
Example BTT Structure
HashPairTest ├── When first arg is smaller than second arg │ └── It should match the result of keccak256(a,b). └── When first arg is bigger than second arg └── It should match the result of keccak256(b,a).
This technique helps developers:
- ├──Visualize all possible test scenarios
- ├──Ensure complete test coverage
- ├──Easily identify missing test cases
- └──Maintain a clear and organized test structure
Bulloak leverages BTT to automatically generate comprehensive test suites, saving time and improving the quality of smart contract testing.
What is bulloak?
bulloak is a powerful tool that brings the Branching Tree Technique to life for developers. It automates the process of creating comprehensive test suites based on BTT specifications. Check out the full README on GitHub.
Bulloak
├── Scaffold Command
│ ├─── Generates test files from .tree specifications
│ │ ├── Creates modifiers for conditions
│ │ └── Generates test functions for actions
│ ├─── Reports syntax errors in your specification
│ └─── Provides a full AST for easy extension
├── Check Command
│ ├── Ensures implementation matches its specification
│ ├── Reports missing tests
│ └── Identifies structural mismatches
├── Multiple Tree Support
│ └── Define multiple test trees in a single file
├── Flexible Syntax
│ ├── Supports 'when' and 'given' for conditions and states, respectively
│ └── Case-insensitive keywords
└── Automatic Fixes
├── Adds missing functions
└── Corrects incorrect ordering
hash_pair.tree
HashPairTest
├── When first arg is smaller than second arg
│ └── It should match the result of
│ keccak256(abi.encodePacked(a,b)).
└── When first arg is bigger than second arg
└── It should match the result of
keccak256(abi.encodePacked(b,a)).
CLI
# Generate Solidity tests.
$ bulloak scaffold hash_pair.tree
# Check if tests match the specification.
$ bulloak check hash_pair.tree
# Automatically fix issues.
$ bulloak check --fix hash_pair.tree
Usage
1. Install Bulloak
$ cargo install bulloak
2. Create a .tree file (e.g., foo.tree)
FooTest
└── When stuff is called
└── When a condition is met
└── It should revert.
└── Because we shouldn't allow it.
3. Generate Solidity test files
$ bulloak scaffold foo.tree
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
contract FooTest {
modifier whenStuffIsCalled() {
_;
}
function test_RevertWhen_AConditionIsMet() external whenStuffIsCalled {
// It should revert.
// Because we shouldn't allow it.
}
}
4. Check if the code matches the specification
$ bulloak check foo.tree
warn: function "test_WhenFirstArgIsBiggerThanSecondArg" is missing in .sol
+ fix: run `bulloak check --fix foo.tree`
--> foo.tree:5
warn: 1 check failed (run `bulloak check --fix foo.tree` to apply 1 fix)
5. Automatically fix issues (if any)
$ bulloak check --fix foo.tree
...
success: 1 issue fixed.
For more detailed usage instructions and options, refer to the full documentation on GitHub.