franela / goblin

Minimal and Beautiful Go testing framework
MIT License
887 stars 79 forks source link

How to run each test in parallel in test suite? #109

Open HeykQA opened 2 years ago

HeykQA commented 2 years ago
package foobar

import (
    "testing"
    . "github.com/franela/goblin"
)

func Test(t *testing.T) {
    g := Goblin(t)
    g.Describe("Numbers", func() {
        // Passing Test
        g.It("Should add two numbers ", func() {
            g.Assert(1+1).Equal(2)
        })
        // Failing Test
        g.It("Should match equal numbers", func() {
            g.Assert(2).Equal(4)
        })
        // Pending Test
        g.It("Should substract two numbers")
        // Excluded Test
        g.Xit("Should add two numbers ", func() {
            g.Assert(3+1).Equal(4)
        })
    })
}
HeykQA commented 2 years ago

Hello! @marcosnils How to run these tests in parallel?

dgunay commented 2 years ago

I'm not 100% sure this does it, but you can do something like this for "asynchronous tests". Unsure whether or not they're actually done in parallel with each other.

g.It("returns true if the slice contains the item", func(done goblin.Done) {
        go func() {
          slice := []string{"a", "b", "c", "d"}
      Expect(util.Contains(slice, "a")).To(BeTrue())
          done()
        }()
})
marcosnils commented 2 years ago

Goblin doesn't have a way to run each it block in parallel. If you want Parallel tests, you'll have to separate the Describe and it blocks that you want to run separately.

For example:

func Test(t *testing.T) {
    t.Parallel()
    g := Goblin(t)
    g.Describe("Numbers", func() {
        // Passing Test
        g.It("Should add two numbers ", func(done goblin.Done) {
            fmt.Println("one")
            time.Sleep(1 * time.Second)
            done()
        })

        g.It("Should add two numbers ", func(done goblin.Done) {
            fmt.Println("two")
            time.Sleep(2 * time.Second)
            done()
        })
    })
}

func TestStrings(t *testing.T) {
    t.Parallel()
    g := Goblin(t)
    g.Describe("Strings", func() {
        // Passing Test
        g.It("Should add two numbers ", func(done goblin.Done) {
            fmt.Println("foo")
            time.Sleep(1 * time.Second)
            done()
        })

        g.It("Should add two numbers ", func(done goblin.Done) {
            fmt.Println("bar")
            time.Sleep(2 * time.Second)
            done()
        })
    })
}

Then you can use go test -parallel 2 ./...

I'm leaving this open in case someone wants to add support for Goblin native parallel tests

shasaur commented 2 years ago

Was this ever changed? Because when I run my tests now the its inside one describe block actually seem to be working in parallel. I don't know if go changed something, or whether it was always like this.

Proof: image

shasaur commented 2 years ago

I had to add this to the describe block to fix it:

runningRight := sync.Mutex{}
g.BeforeEach(func() {
  runningRight.Lock()
})
g.AfterEach(func() {
  runningRight.Unlock()
})