near / near-workspaces-js

Write tests once, run them both on NEAR TestNet and a controlled NEAR Sandbox local environment
https://near.github.io/near-workspaces-js/
GNU General Public License v3.0
42 stars 21 forks source link

[Question] Best practice to organize contract repo and workspace tests #109

Closed ailisp closed 2 years ago

ailisp commented 2 years ago

In using workspaces-js, I find there is no recommend way to organize workspace test files (*.ava.ts) in the smart contract repo. Say I have two contract repos: contract_proj_A and contract_proj_B. There are three ways to organize test:

Apporach 1

Put a near-workspaces in each repo:

├── contract_proj_A │   ├── build │   │   └── a.wasm │   ├── near-workspaces │   │   ├── tests │   │   │   └── test_a.ava.js │   │   └── compiled-contracts │   │   └── a.wasm │   └── src │   └── a.js └── contract_proj_B ...

It is natural to people who already have a contract repo. But two problems:

  1. cross contract call tests doesn't fit in the hierachy
  2. user need update the build script to copy build/a.wasm to near-workspaces/compiled-contracts/

Approach 2

Put a near-workspaces at same level of contract_proj_A and contract_proj_B:

├── contract_proj_A │   ├── build │   │   └── a.wasm │   └── src │   └── a.js ├── contract_proj_B │   ├── build │   │   └── b.wasm │   └── src │   └── b.js └── near-workspaces ├── tests │   ├── test_a.ava.js │   ├── test_b.ava.js │   └── test_cross_a_b.ava.js └── compiled-contracts ├── a.wasm └── b.wasm

This solves cross contract call problem, but user would need to maintain a build script to grab a.wasm and b.wasm into near-workspaces. This build script assumes a project layout out of repos, which is not good. Another problem is, tests specific to contract_proj_A doesn't live in the contract_proj_A.

Approach 3

Similar to 2, but have a near-workspaces contains the contract repos:

└── near-workspaces ├── tests │   ├── test_a.js │   ├── test_b.js │   └── test_cross_a_b.js ├── compiled-contracts │   ├── a.wasm │   └── b.wasm ├── contract_proj_A │   ├── build │   │   └── a.wasm │   └── src │   └── a.js └── contract_proj_B ├── build │   └── b.wasm └── src └── b.js

The problem is also contract_proj_A specific tests doesn't live in the contract

ailisp commented 2 years ago

From discussion with @MaximusHaximus , approach 2 is the best :+1:

ailisp commented 2 years ago

Actually, if workspaces-js is just a package, not has any test runner, user can just use workspaces-js as a librar. And thus no explicit directory, user can choose their own test framework (ava, jest, mocha), organize the tests as just other projects that using the test frameworks. We can have near-workspaces-init-ava, near-workspaces-init-jest, etc.

ChaoticTempest commented 2 years ago

Wanted to note that for workspaces-rs, people are using either approach 1 or 2. For smaller projects that just have a single contracts, I've seen it lean towards approach 1 similar to https://github.com/near/near-sdk-rs/tree/master/examples/non-fungible-token where src and tests folder live side by side. Just throwing out thoughts here, but I wonder if its worth consolidating the approaches (for both rs and js versions) for best practices, but also could be hard due to the nature of it being different languages with different tooling

ailisp commented 2 years ago

We recently added example to be reference setup: examples/simple-project and https://github.com/near-examples/rust-counter/tree/master/integration-tests/ts