onsi / ginkgo

A Modern Testing Framework for Go
http://onsi.github.io/ginkgo/
MIT License
8.33k stars 658 forks source link

Is there a way to "parametrize" a spec? #349

Closed blurrcat closed 7 years ago

blurrcat commented 7 years ago

Say we have an interface called Cache and I have a spec that tests its various methods:

Describe("Cache", func() {
    var c Cache

    BeforeEach(func() {
        c = NewLRUCache()
    })

    It("should ...")
    It("should ...")
    ...
})

Suppose I have 2 implementations of Cache, like LRUCache and LFUCache, is there a way to re-use the spec? For example, by allowing the Describe callback accepting some parameters? The table extension seems to work only on the It level.

Currently I wrap the spec inside a for loop:

for _, name := range []string{"LRU", "LFU"} {
    Describe(name + " Cache", func () {
        var c Cache
        BeforeEach(func() {
            if name == "LRU":
                c = NewLRUCache()
            elif name == "LFU":
                c = NewLFUCache()
        })
       // same tests like before
    })
}

What's the recommended way to do it? Thanks in advance.

tinygrasshopper commented 7 years ago

There are some documented ways of reusing specs, I think the first option might be suitable for your usecase

Describe("Cache", func() {
    var c Cache

    AssertCacheBehavior := func(){
        It("should ...")
        It("should ...")
    }

    Describe("LRU Cache", func(){
        BeforeEach(func(){
             c = NewLRUCache()
        } )

        AssertCacheBehavior()
    })

    Describe("Other Cache", func(){
        BeforeEach(func(){
             c = NewOtherCache()
        } )

        AssertCacheBehavior()
    })
})
blurrcat commented 7 years ago

Thanks @tinygrasshopper! This is exactly what I'm looking for. Coming from TDD, the phrase "shared behaviors" just didn't ring the bell for me. Guess I should have read the docs more carefully!