Skip to content

How to write a TestCase

xushiwei edited this page Jul 20, 2020 · 8 revisions

There are two ways to test a package in github.com/qiniu/x/ts.

Check output parameters

Suppose we have a function named foo to test:

func foo(arg1 Type1, arg2 Type2, ..., argN TypeN) (ret1 RetType1, ret2 RetType2, ..., retM RetTypeM)

Normally we test it like this:

func TestXXX(t *testing.T) {
    ret1, ret2, ..., retM := foo(arg1, arg2, ..., argN)
    if ret1 != expect1 {
        t.Fatal("TestXXX failed: ret1 != expect1 -", ret1, expect1)
    }
    if ret2 != expect2 {
        t.Fatal("TestXXX failed: ret2 != expect2 -", ret2, expect2)
    }
    ...
    if retM != expectM {
        t.Fatal("TestXXX failed: retM != expectM -", retM, expectM)
    }
}

By using github.com/qiniu/x/ts, we can test it like this:

import "github.com/qiniu/x/ts"

func TestXXX(test *testing.T) {
    t := ts.New(test)
    t.Call(foo, arg1, arg2, ..., argN).Equal(expect1).Next().Equal(expect2)...Next().Equal(expectM)
}

Sometimes we check properties of output parameters. For example:

func TestXXX(t *testing.T) {
    ret1, ret2, ..., retM := foo(arg1, arg2, ..., argN)
    ...
    if retI.prop != propExpect {
        t.Fatal("TestXXX failed: retI.prop != propExpect -", retI.prop, propExpect)
    }
    ...
}

By using github.com/qiniu/x/ts, we check properties like this:

func TestXXX(test *testing.T) {
    t := ts.New(test)
    t.Call(foo, arg1, arg2, ..., argN)...Next().PropEqual("prop", propExpect)...
}

Check stdout/stderr

func TestXXX(t *testing.T) {
    e := ts.StartExpecting(t, ts.CapStdout|ts.CapStderr)
    defer e.Close()

    fmt.Println("Hello")
    fmt.Fprintln(os.Stderr, "world")

    e.Expect("Hello\n").ExpectErr("world\n").NoPanic()
}

or:

func TestXXX(t *testing.T) {
    e := ts.StartExpecting(t, ts.CapStdout|ts.CapStderr)
    defer e.Close()

    e.Call(func() {
        fmt.Println("Hello")
        fmt.Fprintln(os.Stderr, "world")
    }).Expect(
        "Hello\n",
    ).ExpectErr(
        "world\n",
    ).NoPanic()
}

What is the difference between them? If the code to be tested doesn't panic, they are equivalent. But if it may panic, we suggest you use the second way. For example:

func TestXXX(t *testing.T) {
    e := ts.StartExpecting(t, ts.CapStdout|ts.CapStderr)
    defer e.Close()

    e.Call(func() {
        panic("an error message")
    }).Expect(
        "",
    ).Panic(
        "an error message",
    )
}
Clone this wiki locally