Skip to Content
Scalus Club is now open! Join us to get an early access to new features 🎉

Cardano Smart Contract Testing

Scalus provides comprehensive testing tools for Cardano smart contracts — unit testing, debugging, and local execution environments.

Testing Tools Overview

ToolPurposeBest For
Unit TestingProperty-based tests with ScalaCheckValidator logic verification
DebuggingIDE debugging, logging, error tracesFinding and fixing bugs
EmulatorIn-memory Cardano nodeFast iteration, CI/CD
Local DevnetDocker-based real Cardano nodeIntegration tests, pre-deployment

Unit Testing with ScalaCheck

Write property-based tests using ScalaCheck  to verify validator logic:

class MyValidatorTest extends AnyFunSuite with ScalusTest { test("validator accepts valid signature") { val txInfo = random[TxInfo] val signer = random[PubKeyHash] // Test your validator logic } }

See Unit Testing for complete guide.

Debugging

Debug validators as regular Scala code — use IDE breakpoints, step through execution, and inspect variables:

@Compile object MyValidator extends Validator: inline override def spend(...): Unit = { log("Starting validation") val owner = datum.getOrFail("No datum").to[PubKeyHash] // Set breakpoint here, inspect variables require(tx.signatories.contains(owner), "Not signed") }

See Debugging for IDE setup and logging.

Local Execution Environments

Emulator — Fast In-Memory Testing

The Emulator validates transactions and executes Plutus scripts instantly — no Docker required:

val emulator = Emulator.withAddresses(Seq(Alice.address, Bob.address)) val tx = TxBuilder(testEnv) .payTo(Bob.address, Value.ada(10)) .complete(emulator, Alice.address) .await() .sign(Alice.signer) .transaction emulator.submit(tx).await() // Instant validation + script execution

Local Devnet — Real Cardano Node

Local Devnet runs a real Cardano node (Yaci DevKit) in Docker:

class MyTest extends AnyFunSuite with YaciDevKit { test("submit transaction to local devnet") { val ctx = createTestContext() val tx = TxBuilder(ctx.cardanoInfo) .payTo(recipient, Value.ada(10)) .complete(ctx.provider, ctx.address) .await(30.seconds) .sign(ctx.signer) .transaction ctx.submitTx(tx) // Real Cardano node validation } }

Test pyramid: Tests → Emulator → Local Devnet → Testnet → Mainnet

Development: Write code → Run tests → Emulator → Fast feedback → Debug with IDE

Pre-deployment: All tests pass → Local Devnet → Deploy with confidence

See Also

  • Unit Testing — Property-based testing with ScalaCheck
  • Debugging — IDE debugging and logging
  • Emulator — In-memory testing with instant feedback
  • Local Devnet — Integration testing with real Cardano node
  • Ledger Rules — Validation rules used by testing tools
Last updated on