Discussion: using TypeScript for writing smart contract tests

Using TypeScript for writing smart contract tests

Discussion started by @Luiserebii: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1902

Idea

This has been something on my mind for a while now, the potential for using TypeScript for writing tests. Strict typing could be a good boost to ensuring things are running as expected, and an argument that comes to mind is that vanilla JavaScript is a forgiving language that may not be the best for writing smart contract tests for, given how sensitive they may be.

Counter-arguments

To play devil's advocate, what comes to mind is that it can limit developer contributions since most people are familiar with JavaScript, and perhaps well-written JavaScript along with a linter might be the most productive route to go, since I've personally had issues with figuring out how to work with untyped modules I may be using.

Most importantly, I was curious to know if the team has thought about this before? I looked into the issues, and no mention of this was made, so this made me very curious to ask.

@nventuro: We're actually planning on bringing some changes into the test suite! What sort of things do you think TypeScript could help with? I know there were some efforts to create typed contract objects, but I'm not sure how far along those have come. Do you use TS in your own setup?

@Luiserebii: That's great to hear! I'm happy to hear that this is topic conveniently relevant. I think that the type-checking TypeScript could be able to offer could strengthen tests and detect bugs at compile-time. I've heard from friends that web3.js can sometimes return objects they weren't quite expecting, though I can't remember for myself if this was ever the case for me.

ESLint itself helps quite a bit in detecting things such as unused variables, I'm not sure if there's anything TypeScript covers that ESLint doesn't cover. Something nice about TypeScript is the ability to define interfaces for objects, thus guaranteeing that the objects you're expecting do have the properties you're looking for. During run-time, this issue may pass silently and simply reveal itself as undefined .

When it comes to objects with fluid structures, though, like results returned from call functions, I'm not 100% certain what the best practice is for handling this in TypeScript, I think that probably using any as the type would work as a work-around.

I actually haven't heard of the typed contract objects thing, but I have recently tried integrating TypeScript into a setup as a proof-of-concept, and also something reusable for anyone looking to set something like this up in the future, since it took me some research to quite get everything together. The project is called Maximum Solidity Environment, and can be found here: https://github.com/Luiserebii/Maximum-Solidity-Environment

Feel free to add your thoughts to the discussion in the forum.

4 Likes

Hello, just wanted to confirm that I can communicate in this forum and continue the discussion if preferable, the sign in with GitHub was very smooth :smiley:

4 Likes

Welcome to the community forum @Luiserebii :wave: Thanks for joining.

2 Likes

I would love to see a smart contract project trying this out. Setting up a test suite in TypeScript is not completely smooth in my experience though. I kind of like the setup I put together for solidity-docgen.

2 Likes

Hey @frangio,

Ahh, I see! I’ll take a look at how you set it up. What I ended up doing was something like:

    "test": "rm -rf ./test/bin/ && tsc --project ./test/tsconfig.json && truffle test ./test/bin/*"

I’m not sure if you’d consider this complete, but I did set it up here, with a really basic Calculator contract: https://github.com/Luiserebii/Maximum-Solidity-Environment

There is also this smart contract project that does have the TypeScript testing integration together: https://github.com/CryptoDevsDiscord/CryptoDevs-Discord-1st-Anniversary-NFT

Would love to hear your thoughts on this.

1 Like

That works but I’m not a fan of rm -rf, it feels unsafe, and is also not cross platform.

Additionally I think having a good “watch mode” is really important. A test runner like Ava might be the best tool for this use case since it integrates Babel out of the box (you can use Babel to remove the type annotations), though you would probably have to type check separately.

1 Like

Hmmmm, I need to look into Ava, I haven’t heard of it before. Minor question, so the advantage of Babel would be to run the code as JS almost as is without compiling? I suppose someone could run tsc with the --noEmit flag, maybe specify it in the config file, and if it passes, continue onto running the tests.

1 Like

Yep, that's exactly what people do when they use Babel!

As for the compilation, Typescript doesn't do a lot more than removing annotations either. But I haven't used this myself so I only know from reading about it. :sweat_smile:

2 Likes

Interesting, ok! I might experiment a little with using Ava and your setup in the near future. Out of curiosity, did you find any other bumpy steps in the road to integrating this? Also, how do you feel on TypeScript vs vanilla JS? I’m 50/50 on it, and am kind of curious as to how likely you think it might be integrated in the next major release.

1 Like

In the next major release of what do you mean?

1 Like

I mean, for openzeppelin-solidity; I wasn’t sure what word to use, I thought of release since it has the whole dependency usage in npm/ethpm. I guess I mean more of, in the future of the repo, was curious to just get a feel of things. I know @nventuro mentioned changes in the test suite being planned

1 Like

Ah I see. Changes to the test suite are “internal” so they are independent of the release cycle.

For now we have no plans to incorporate TypeScript into the existing OpenZeppelin Contracts test suite, but some of us in the OpenZeppelin engineering team are starting to use TypeScript for testing new projects.

For example, Network.js and solidity-docgen have TypeScript tests. :grinning:

2 Likes

Ahhh, ok, great to hear! Was just curious. If there are any plans to integrating TypeScript into the current contracts test suite, I would be open to contributing and helping!

For the moment, I will look into the way OpenZeppelin is using TypeScript to write tests for new projects, especially the ones that you linked. Thank you for your help!

2 Likes

I was able to convert my project setup to use typescript for tests with no big issues by using buidler.

You can take a look here if you are curious: https://github.com/ohmydai/ohmydai-contracts/tree/develop

I’ve just converted it, so it might not be using all typescript features, I made it just compile/run with no errors.

The only problem I found was regarding one of the types provided by openzeppelin SDK and opened an issue for this in github: https://github.com/OpenZeppelin/openzeppelin-sdk/issues/1373

1 Like