agentsclimarketplace

Sui tester

Skill first-mover-tw/sui-dev-agents/skills/sui-tester

Use when writing Move tests, setting up test suites, running gas benchmarks, or planning test strategy for SUI contracts. Triggers on "write tests", "test this module", "#[test]", "test coverage", "gas benchmark", "property-based test", or any Move testing task. Use even for simple "how do I test this function" questions.From its SKILL.md

Install
npx -y skills add first-mover-tw/sui-dev-agents --skill sui-tester

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.4 KB, as published. Nobody here has run it

SUI Tester

Complete testing solution for SUI Move contracts and frontend applications.

Overview

This skill provides comprehensive testing across all layers:

  • Unit Tests - Test individual Move functions
  • Integration Tests - Test module interactions
  • E2E Tests - Test complete user journeys (frontend + contract)
  • Property-Based Tests - Test invariants with random inputs
  • Gas Benchmarks - Measure and track gas consumption

SUI Protocol 127 Testing Updates (shipped testnet v1.74.0; now mainnet v1.77.2 / P133)

Key changes affecting testing (June 2026):

  • Move Linter (P128 / v1.74.1+): sui move lint runs Move linters on the package. Lints also run in sui move build/test by default — --no-lint to skip, --lint for extra linters. Wire into CI alongside sui move test.
  • gRPC SimulateTransaction gasless tier (P127): now accepts gas_price=0 for gasless-tier-eligible transactions instead of erroring — useful for sponsored-tx dry runs.
  • Regex Test Filtering: Test filtering uses regex. Use sui move test --filter "regex_pattern" for precise test selection.
  • poseidon_bn254: Available on all networks. Add tests for ZK-related functions using sui::poseidon::poseidon_bn254.
  • TxContext Flexible Positioning: TxContext can be in any argument position. Update integration tests if they assume last-position TxContext.
  • gRPC Data Access: Integration tests must use gRPC client — JSON-RPC Quorum Driver is disabled and public-fullnode JSON-RPC is shut off (since 2026-07-31).
  • #[error] Annotation: Use #[error] on error constants for human-readable abort messages. Update #[expected_failure] tests to reference constant names, not hardcoded values.
  • GraphQL Simulation: events field removed from simulateResult. Access events via effects.events() in dry-run tests.
  • Gas Re-benchmarking: The New Move VM on testnet may produce different gas profiles compared to Protocol 118. If your tests assert specific gas values, re-run sui move test --gas-limit and update expected values.
  • Decoded Object Inspection: sui client object now shows decoded struct fields — useful for manual verification during integration tests.

Sender impersonation on a forked network (sui-fork + --skip-signing)

The sui-fork tool spins up a local network forked from mainnet/testnet/devnet state, then you submit transactions unsigned under any sender — useful for reproducing user-reported bugs without their keys. sui-fork is a separate crate in MystenLabs/sui (crates/sui-fork, subcommands start / status / advance-clock / advance-checkpoint); it's not shipped via suiup, build it with cargo build -p sui-fork.

# 1. Start a local fork from testnet state
sui-fork start --network testnet            # optional: --checkpoint <n> --data-dir <path>

# 2. Point the CLI at the fork
sui client new-env --alias local-fork --rpc http://127.0.0.1:9000
sui client switch --env local-fork

# 3. Submit a tx as an impersonated sender, unsigned
sui client call --package <pkg> --module <mod> --function <fn> \
  --sender 0x<address> \
  --skip-signing                            # renamed from --forking-mode in v1.74.1

--skip-signing (a sui client tx flag, not a sui replay flag): "Submit the transaction without signatures for forked networks that support sender impersonation. Only intended for local forked-network testing." Use this when an integration test needs to mimic real on-chain state under a specific signer.

Quick Start

# Run all tests
sui move test

# Run with coverage
sui move test --coverage

# Generate coverage report
sui move coverage summary

# Run specific test (now uses regex!)
sui move test --filter "test_create_listing"

# Run all tests matching pattern
sui move test --filter "test_.*listing"

Test Types

Aim for a test pyramid — most coverage cheap and fast at the bottom, a few expensive checks at the top:

          E2E Tests (5%)
         /            \
    Integration (15%)
       /                \
   Unit Tests (80%)

1. Move Unit Tests

#[test]
fun test_create_listing() {
    let seller = @0xA;
    let mut scenario = test_scenario::begin(seller);

    // Reusable helpers keep setup DRY across tests
    let nft = create_test_nft(&mut scenario);
    let listing = create_listing(nft, 1000, scenario.ctx());

    assert!(price(&listing) == 1000, 0);
    assert!(seller(&listing) == seller, 1);

    test_scenario::end(scenario);
}

2. Integration Tests

Test cross-module interactions (marketplace + royalty).

3. Frontend E2E Tests

// @check:skip
test('complete buy flow', async ({ page }) => {
    await page.goto('http://localhost:5173');
    await page.click('button:has-text("Connect Wallet")');
    await page.click('button:has-text("Buy Now")');
    await expect(page.locator('text=Purchase successful')).toBeVisible();
});

4. Property-Based Tests

#[test]
fun property_price_distribution() {
    // Test invariant: total = seller + royalty + fee
    let iterations = 100;
    // ... verify invariant holds
}

5. Gas Benchmarks

sui move test --gas-profile

Test Coverage

Target: >90% code coverage for core modules

Quick Coverage Check

sui move test --coverage
sui move coverage summary

Automated Coverage Analysis Tools

This skill includes Python scripts in scripts/ for detailed coverage analysis:

# Location (relative to plugin install path)
SCRIPTS=<plugin_path>/skills/sui-tester/scripts

# Step 1: Run tests with coverage
cd /path/to/move/package
sui move test --coverage --trace

# Step 2: Source-level analysis (primary tool)
# Uses PTY to capture colored output, identifies exact uncovered segments
python3 $SCRIPTS/analyze_source.py -m <module_name>
python3 $SCRIPTS/analyze_source.py -m <module_name> -o coverage.md        # Markdown report
python3 $SCRIPTS/analyze_source.py -m <module_name> --json                # JSON output

# Step 3: LCOV statistics (function/line/branch breakdown)
sui move coverage lcov
python3 $SCRIPTS/analyze_lcov.py lcov.info -s sources/ --issues-only

# Step 4: Low-level bytecode analysis (optional)
sui move coverage bytecode --module <name> | python3 $SCRIPTS/parse_bytecode.py

# Step 5: Piped source analysis (alternative to analyze_source.py)
script -q /dev/null sui move coverage source --module <name> | python3 $SCRIPTS/parse_source.py

Coverage Improvement Workflow

  1. Analyze — Run analyze_source.py to get uncovered segments
  2. Identify gaps:
    • Uncalled functions → write tests that call them
    • Uncovered assertions → write #[expected_failure] tests
    • Untaken branches → write tests for both if/else paths
  3. Write tests for each gap (see patterns below)
  4. Verify — Re-run analysis to confirm improvement
  5. Repeat until >90% coverage

Coverage Test Patterns

A. Uncalled function:

#[test]
fun test_<function_name>() {
    let mut ctx = tx_context::dummy();
    <function_name>(&mut ctx);
    // Assert expected behavior
}

B. Assertion failure path:

#[test]
#[expected_failure(abort_code = <ERROR_CONST>)]
fun test_<function>_fails_when_<condition>() {
    let mut ctx = tx_context::dummy();
    // Setup state that triggers the assertion failure
    <function_call_that_should_fail>();
}

C. Branch coverage (if/else):

#[test]
fun test_<function>_when_true() { /* condition = true path */ }

#[test]
fun test_<function>_when_false() { /* condition = false path */ }

Common Mistakes

❌ Not using test_scenario properly

  • Problem: Tests fail with "object not found" errors
  • Fix: Always call test_scenario::next_tx between transactions, clean up with test_scenario::end

❌ Testing with unrealistic gas budgets

  • Problem: Tests pass but fail in production due to gas limits
  • Fix: Set realistic gas budgets in tests, use --gas-limit flag

❌ Ignoring test cleanup

  • Problem: Objects leak between tests, intermittent failures
  • Fix: Delete all created objects or use #[expected_failure] for abort tests

❌ Not testing error cases

  • Problem: Production failures from unexpected inputs
  • Fix: Test all assert! and abort paths with #[expected_failure(abort_code = X)]

❌ Skipping property-based tests for math

  • Problem: Edge cases cause overflow/underflow in production
  • Fix: Test invariants with 100+ random inputs (prices, quantities, percentages)

❌ Not benchmarking gas costs

  • Problem: Expensive operations drain user funds
  • Fix: Run sui move test --gas-profile, track gas per operation

❌ E2E tests without proper wallet setup

  • Problem: Tests fail on wallet connection
  • Fix: Use Playwright with wallet mock or testnet faucet automation

Configuration

Test execution targets:

  • Unit tests: <30 seconds
  • Integration tests: <2 minutes
  • E2E tests: <10 minutes
  • Full suite: <15 minutes

For installing the CLI, localnet setup, or faucet tokens, see the sui-install skill.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.