forked from skeema/tengo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testing.go
82 lines (73 loc) · 2.79 KB
/
testing.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package tengo
import (
"fmt"
"os"
"reflect"
"strings"
"testing"
)
// This file contains public functions and structs designed to make integration
// testing easier. These functions are used in Tengo's own tests, but may also
// be useful to other packages and applications using Tengo as a library.
// IntegrationTestSuite is the interface for a suite of test methods. In
// addition to implementing the 3 methods of the interface, an integration test
// suite struct should have any number of test methods of form
// TestFoo(t *testing.T), which will be executed automatically by RunSuite.
type IntegrationTestSuite interface {
Setup(backend string) error
Teardown(backend string) error
BeforeTest(backend string) error
}
// RunSuite runs all test methods in the supplied suite once per backend. It
// calls suite.Setup(backend) once per backend, then iterates through all Test
// methods in suite. For each test method, suite.BeforeTest will be run,
// followed by the test itself. Finally, suite.Teardown(backend) will be run.
// Backends are just strings, and may contain docker image names or any other
// string representation that the test suite understands.
func RunSuite(suite IntegrationTestSuite, t *testing.T, backends []string) {
var suiteName string
suiteType := reflect.TypeOf(suite)
suiteVal := reflect.ValueOf(suite)
if suiteVal.Kind() == reflect.Ptr {
suiteName = suiteVal.Elem().Type().Name()
} else {
suiteName = suiteType.Name()
}
if len(backends) == 0 {
t.Skipf("Skipping integration test suite %s: No backends supplied", suiteName)
}
for _, backend := range backends {
if err := suite.Setup(backend); err != nil {
t.Fatalf("RunSuite %s: Setup(%s) failed: %s", suiteName, backend, err)
}
// Run test methods
for n := 0; n < suiteType.NumMethod(); n++ {
method := suiteType.Method(n)
if strings.HasPrefix(method.Name, "Test") {
subtestName := fmt.Sprintf("%s.%s:%s", suiteName, method.Name, backend)
subtest := func(subt *testing.T) {
if err := suite.BeforeTest(backend); err != nil {
suite.Teardown(backend)
t.Fatalf("RunSuite %s: BeforeTest(%s) failed: %s", suiteName, backend, err)
}
method.Func.Call([]reflect.Value{reflect.ValueOf(suite), reflect.ValueOf(subt)})
}
t.Run(subtestName, subtest)
}
}
if err := suite.Teardown(backend); err != nil {
t.Fatalf("RunSuite %s: Teardown(%s) failed: %s", suiteName, backend, err)
}
}
}
// SplitEnv examines the specified environment variable and splits its value on
// commas to return a list of strings. Note that if the env variable is blank or
// unset, an empty slice will be returned; this behavior differs from that of
// strings.Split.
func SplitEnv(key string) []string {
value := os.Getenv(key)
if value == "" {
return []string{}
}
return strings.Split(value, ",")
}