Open psiemens opened 1 year ago
Also, I completely understand if what I'm proposing is outside the scope of a testing feature or doesn't make sense due to fundamental constraints in Cadence.
I'm now wondering if this requires the Cadence interpreter to know too much about blockchain-specific features (i.e. account storage). π€
Thank you @psiemens for spending time to test the feature and for the feedback! π
The test-framework provides two approaches for testing:
Integration tests
Integration basically allows you to mimic the real-world scenarios - Creating accounts, deploying contracts, submitting transactions/scripts to the chain, etc. For e.g: the blockchain
used for testing is an emulator-backed one in this initial version. But it can also be extended in future to use a local-net, and even testnet as the blockchain for testing.
Many of the functionality implemented in the current version is to support this.
Also, one reason to allow reading the content from file (as string) and mapping the import paths to addresses is to allow devs to use the existing project as-is without changing and use them for testing.
Unit testing I think this is mostly what you are suggesting. No blockchain. Can directly import contracts and call their functions. e.g: https://github.com/SupunS/cadence-testing/blob/main/sample_1/unit_tests.cdc
For now, the features supported for unit testing are very limited due to some implementation complexities.
But definitely, this unit testing can be improved a lot, and these ideas are great!
Added these to the improvements list: https://github.com/onflow/cadence/issues/1889
I made a very similar comment before @psiemens, but your implementation looks even better.
Maybe even better can be using some helper functions (instead of import syntax), instead of import Foo from "contracts/Foo.cdc"
maybe var Foo = getContract("contracts/Foo.cdc")
for example.
I'm now wondering if this requires the Cadence interpreter to know too much about blockchain-specific features (i.e. account storage).
I think this is good case to make it like as you said, so Cadence can have more access to chain when in normal use too
The test-framework provides two approaches for testing:
- Integration tests
- Unit tests
I guess I'm proposing a combination of the two approaches you described. I think it should be possible to create accounts, deploy contracts and submit transactions directly inside unit tests.
If the unit testing functionality was extended to support the cases I showed above, as a developer, I probably wouldn't use the emulator-backed blockchain inside Cadence. I like that the unit tests allow me to focus on my Cadence code without any overhead.
If I wanted to test across different networks, I think I'd prefer to use an external client library through the Access API so that I can make sure my application is properly connecting to the blockchain, signing transactions, properly decoding output, etc.
Also, one reason to allow reading the content from file (as string) and mapping the import paths to addresses is to allow devs to use the existing project as-is without changing and use them for testing.
Yeah, I think it's important to allow developers to test the same transaction and script files that they use in their production app. The approach I outlined also aims to allow a project to keep its files as-is (transactions/setBar.cdc
and scripts/getBar.cdc
are loaded from external files, presumably the same ones that would be loaded by an application or wallet).
Yeah, makes sense.
The current challenge is to support this within the existing cadence syntax/semantics.
For e.g: imagine the test script imports Foo
and Bar
, where Foo imports Baz
in one account (say acct1
) , and Bar
imports Baz
from another account (say acct2
). The two Baz
contracts have the same name but they are two completely different contracts.
Now for the test script, to import both Foo
and Bar
, I would also need to instantiate/deploy both of the Baz
contracts first. With first-class support, this causes name conflicts. i.e: I can't import both the Baz
s.
This is just a hypothetical example - but it's possible to have such dependencies. Not saying we can't implement this, but just pointing out some edge cases we need to consider when designing the API/semantics.
Contracts were made first-class in https://github.com/onflow/cadence-tools/pull/210. And thus also scripts can become first class (methods in the same test script) too.
First off, great work on the Cadence testing framework! It's so awesome to see native testing features.
As I was trying it out, I was a bit surprised to find that contracts, scripts and transactions are still passed as strings inside Cadence. It felt odd to me that I had to put Cadence code in a string inside a Cadence program.
I was then thinking: do we need to have the
Blockchain
construct in order to test Cadence programs?Would it be possible to have a version like this?
Sorry this feedback is so late. I wish I'd had a chance to dig into the testing framework sooner. Even if none of this makes sense for the first version, wanted to share some ideas for future versions.