smartystreets/goconvey

Is there a way to gorup assertions without rerunning the previous steps

maczikasz opened this issue · 2 comments

Hi I am using Convey to write integration tests.

In these tests there are sometimes multiple things that happen after a REST call, and I woul dlike to verify all of them in my tests

Let's assume we have a REST endpoint that creates a user with the a set of default groups where the user should belong to
After executing this REST call I would like to check that
a) The user is created and visible when I list all users
b) The groups defined contain the user we just added

In my GWT I would write something like

Given user is created
When default groups are used
Then all users list contains the User
Then the default groups contain the user

Now If i Add a Convey() call for each of these lines, I can do either

Convey("Given user is created",t, func() {
 // Create user data
   Convey("When default groups are used, func() {
    // Add default group
    // Call POST call
      Convey("Then all users list contains the User", func() {
         // Call GET all users
         So(users, ShouldContain, userId)
         Convey("Then the default groups contain the user", func() {
             //Call GET /$groupId/users for each group
             So(groupResult.users,ShouldContain, userId)
         })
      })
   })
})

This would in fact do what I would like it to do, but I do not really like the fact that I have to nest the last convey in the previous Then, where they have no parent children relation logically. But If I put the last Convey as a child of the "When" convey it will rerun the REST call, which in an integration test could cause failures, since the test is not stateless.

What I would like to have is something like this

Convey("Given user is created",t, func() {
 // Create user data
   Convey("When default groups are used, func() {
    // Add default group
    // Call POST call
    Convey("Then all verifications pass", func() {
      convey.Then("Then all users list contains the User", func() {
         // Call GET all users
         So(users, ShouldContain, userId)      
      })
      convey.Then("Then the default groups contain the user", func() {
         //Call GET /$groupId/users for each group
         So(groupResult.users,ShouldContain, userId)
      })
     })
   })
})

In this scenario the multiple Convey.Then will not cause the parent scopes to reexecute, but would rather provide a logical goruping for assertions.

I don't know if my makeshift example managed to explain what I am looking for and if there is anything already that I missed for this, or if this is something that may be interesting for the community to look into

Thanks
Szava

In the current formulation of goconvey, this isn't really possible; Each Convey block indicates "please run from the top through to this block".

However, we did just merge a change which adds SoMsg which may let you do what you want; it will create a new convey scope around a single So assertion without introducing that from-the-top behavior. So then you could do:

Convey("Given user is created",t, func() {
   // Create user data
   Convey("When default groups are used, func() {
    // Add default group
    // Call POST call
    Convey("Then all verifications pass", func() {
      // Call GET all users
      SoMsg("Then all users list contains the User", users, ShouldContain, userId)  

      //Call GET /$groupId/users for each group
      SoMsg("Then the default groups contain the user", groupResult.users,ShouldContain, userId)
    })
  })
})

But it only really works on the 'leaf' level... maybe it would be good enough to solve your usecase?

Hey that's awesome, i am not sure if it solves 100% but it definitely solves some troubles i have. Maybe if i have time I can try to come up with something that would fit your ecosystem and PR it