diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b3d370ef7..f98496178e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Forge +#### Added + +- Partitioned test execution with `--partition ` flag. Read more [here](https://foundry-rs.github.io/starknet-foundry/snforge-advanced-features/tests-partitioning.html) + #### Changed - Gas values in fuzzing test output are now displayed as whole numbers without fractional parts diff --git a/docs/book.toml b/docs/book.toml index a11de383ec..4e3011eedf 100644 --- a/docs/book.toml +++ b/docs/book.toml @@ -30,3 +30,4 @@ level = 0 [preprocessor.variables.variables] snforge_std_version = "0.51.0" +matrix.partition = "{{ matrix.partition }}" diff --git a/docs/example_workflows/basic_workflow.yml b/docs/example_workflows/basic_workflow.yml index e419f0290e..67aeb28029 100644 --- a/docs/example_workflows/basic_workflow.yml +++ b/docs/example_workflows/basic_workflow.yml @@ -17,4 +17,6 @@ jobs: scarb-lock: ./hello_starknet/Scarb.lock - name: Run tests - run: cd hello_starknet && snforge test + run: | + cd hello_starknet + snforge test diff --git a/docs/example_workflows/partitioned_workflow.yml b/docs/example_workflows/partitioned_workflow.yml new file mode 100644 index 0000000000..6bce1d2b90 --- /dev/null +++ b/docs/example_workflows/partitioned_workflow.yml @@ -0,0 +1,26 @@ +name: My workflow +on: + push: + pull_request: +jobs: + check: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + partition: [ 1, 2, 3, 4 ] + steps: + - uses: actions/checkout@v4 + + - name: Setup Starknet Foundry + uses: foundry-rs/setup-snfoundry@v3 + + - name: Setup Scarb + uses: software-mansion/setup-scarb@v1 + with: + scarb-lock: ./hello_starknet/Scarb.lock + + - name: Run tests + run: | + cd hello_starknet + snforge test --partition '${{ matrix.partition }}/4' diff --git a/docs/listings/tests_partitioning/Scarb.toml b/docs/listings/tests_partitioning/Scarb.toml new file mode 100644 index 0000000000..f96c865a22 --- /dev/null +++ b/docs/listings/tests_partitioning/Scarb.toml @@ -0,0 +1,14 @@ +[package] +name = "tests_partitioning" +version = "0.1.0" +edition = "2024_07" + +[dependencies] +starknet = "2.12.0" +assert_macros = "2.12.0" + +[dev-dependencies] +snforge_std = { path = "../../../snforge_std" } + +[scripts] +test = "snforge test" diff --git a/docs/listings/tests_partitioning/src/lib.cairo b/docs/listings/tests_partitioning/src/lib.cairo new file mode 100644 index 0000000000..71726c3bdc --- /dev/null +++ b/docs/listings/tests_partitioning/src/lib.cairo @@ -0,0 +1,5 @@ +#[starknet::contract] +pub mod HelloStarknet { + #[storage] + struct Storage {} +} diff --git a/docs/listings/tests_partitioning/tests/example.cairo b/docs/listings/tests_partitioning/tests/example.cairo new file mode 100644 index 0000000000..1d2dcf1bb6 --- /dev/null +++ b/docs/listings/tests_partitioning/tests/example.cairo @@ -0,0 +1,34 @@ +#[test] +fn test_a() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_b() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_c() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_d() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_e() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_f() { + assert_eq!(1 + 1, 2); +} + +#[test] +fn test_g() { + assert_eq!(1 + 1, 2); +} diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 111a8991b7..b65bd6a93e 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -40,6 +40,7 @@ * [Debugging](snforge-advanced-features/debugging.md) * [Oracles](snforge-advanced-features/oracles.md) * [Parametrized Tests](snforge-advanced-features/parametrized-testing.md) +* [Tests Partitioning](snforge-advanced-features/tests-partitioning.md) --- diff --git a/docs/src/appendix/snforge/test.md b/docs/src/appendix/snforge/test.md index eb97bcc2ef..f0babcb181 100644 --- a/docs/src/appendix/snforge/test.md +++ b/docs/src/appendix/snforge/test.md @@ -143,6 +143,11 @@ Use Scarb dev profile. Enable experimental [oracles](../../snforge-advanced-features/oracles.md) support. +## `--partition ` + +If specified, divides tests into partitions and runs specified partition. +`` is in the format `INDEX/TOTAL`, where `INDEX` is the 1-based index of the partition to run, and `TOTAL` is the number of partitions. + ## `-h`, `--help` Print help. diff --git a/docs/src/appendix/starknet-foundry-github-action.md b/docs/src/appendix/starknet-foundry-github-action.md index 59ce3d4b65..c4a96eaead 100644 --- a/docs/src/appendix/starknet-foundry-github-action.md +++ b/docs/src/appendix/starknet-foundry-github-action.md @@ -12,3 +12,13 @@ Make sure you pass the valid path to `Scarb.lock` to [setup-scarb](https://githu ```yml {{#include ../../example_workflows/basic_workflow.yml}} ``` + +## Workflow With Partitioned Tests + +If you have a large number of tests, you can speed up your CI by partitioning tests and running them in parallel jobs. Here's an example workflow that demonstrates how to achieve this: + +```yml +{{#include ../../example_workflows/partitioned_workflow.yml}} +``` + +Read more about [tests partitioning here](../snforge-advanced-features/tests-partitioning.md). \ No newline at end of file diff --git a/docs/src/snforge-advanced-features/tests-partitioning.md b/docs/src/snforge-advanced-features/tests-partitioning.md new file mode 100644 index 0000000000..56c483cfe1 --- /dev/null +++ b/docs/src/snforge-advanced-features/tests-partitioning.md @@ -0,0 +1,44 @@ +# Tests Partitioning + +When your test suite contains a large number of tests (especially fuzz tests), it can be helpful to split them into partitions and run each partition separately, for example in parallel CI jobs. + + +`snforge` supports this via the `--partition ` flag. + +When this flag is provided, `snforge` will divide all collected tests into `TOTAL` partitions and run only the partition with the given `INDEX` (1-based). + +## Example + +Let's consider package with the following 7 tests: + +```rust +{{#include ../../listings/tests_partitioning/tests/example.cairo}} +``` + +Running `snforge test --partition 1/2` will run tests `test_a`, `test_c`, `test_e`, `test_g` (4 tests), while running `snforge test --partition 2/2` will run tests `test_b`, `test_d`, `test_f` (3 tests). + + +```shell +$ snforge test --partition 1/2 +``` + +
+Output: + +```shell +Collected 4 test(s) from tests_partitioning package +Running 4 test(s) from tests/ +[PASS] tests_partitioning_integrationtest::example::test_a ([..]) +[PASS] tests_partitioning_integrationtest::example::test_e ([..]) +[PASS] tests_partitioning_integrationtest::example::test_c ([..]) +[PASS] tests_partitioning_integrationtest::example::test_g ([..]) +Running 0 test(s) from src/ +Tests: 4 passed, 0 failed, 0 ignored, 0 filtered out + +Finished partition run: 1/2 +``` + +
+ + +See example Github Actions workflow demonstrating partitioned test execution [here](../appendix/starknet-foundry-github-action.html#workflow-with-partitioned-tests).