I'm testing AMM, so I have steps like

  1. add liquidity,
  2. try to swap
  3. remove liquidity


I can just add it in one it block like this answer suggests

contract('amm', (accounts) => {
    it ("test all three steps", async () => {
        // await step 1
        // await step 2
        // await step 3

however the test output would in one block together, which isn't very informative. I can't use several It blocks because one steps depends on previous one.

Mocha has steps for that purpose, what's the truffle analog, if any?

  • "I can't use several it blocks because one steps depends on previous one" - you actually can, as long as there is no beforeEach clause at the beginning. Dec 24, 2020 at 18:26
  • of course I can write several it and would perfectly run in parallel without waiting one another. And this is precisely what I don't want to happen because this fail by DEX logic: you can not swap before you add liquidity. So I want that the first "it" run, wait until the result, and only after that run another one.
    – lebed2045
    Dec 30, 2020 at 0:01

1 Answer 1


Using several it blocks is exactly what you need in the given scenario. If I understand correctly, then your testing document should look like something like this:

contract('amm', (accounts) =>{
  var tokenInstance;

      it('adds the funds', ()=> {
        return AMMToken.deployed().then((instance)=> {
          tokenInstance = instance;
          return tokenInstance.addFund(12);
        }).then((addFundReceipt)=> {
          assert.equal(addFundReceipt.success, true, 'fund added correctly');

      it('performs the swap',()=> {
        return AMMToken.deployed().then((instance)=> {
          tokenInstance = instance;
          return tokenInstance.swap(to,from);
          assert.equal(SwapFundReceipt.success, true, 'fund added correctly');

Using the above structure, in every call, you can set your Arrange and Act by calling tokenInstance.callYourFunction(ARRANGED values) and Assert in the succeeding promise. Since truffle comes with Chai Assertion Library, its very intuitive to use it. Also, if there are other steps that need to be performed before adding your funds like validating if funds are available, then you can test them all before calling. Since your Assert statements have a statement to go with it, if any of the assertions fail, you will see exactly what failed, this solves the problem of your block being "non-informative".

I personally have never got over promises. I keep coming back to it when writing tests.

  • since both it blocks are async in nature, they would be run in parallel, but you can't swap before you add liquidity
    – lebed2045
    Dec 29, 2020 at 23:57
  • If you need to "add liquidity" before you swap, in the it block of swap, you need to add the "add liquidity" as well. It depends on how much control you want in your unit test, if you feel that one block is enough to test both the feature, you can go ahead, but i find myself doing it in different blocks. So for eg, i would test the "add liquidity" feature with edge cases in one block. And again use it in "swap" block, here i don't need to test whatever I have already tested, I am only using it so that the accounts have fund to swap and I can focus on edge cases of swap feature. Dec 30, 2020 at 19:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.