Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
k3d cluster create
k3d cluster list

atest init -k $2 --wait-namespace $3 --wait-resource $4
atest init -k "$2" --wait-namespace "$3" --wait-resource "$4"
atest run -p "$1"
17 changes: 8 additions & 9 deletions pkg/runner/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"reflect"
Expand Down Expand Up @@ -83,7 +82,7 @@ func RunTestCase(testcase *testing.TestCase, ctx interface{}) (output interface{
}

var responseBodyData []byte
if responseBodyData, err = ioutil.ReadAll(resp.Body); err != nil {
if responseBodyData, err = io.ReadAll(resp.Body); err != nil {
return
}
if testcase.Expect.Body != "" {
Expand All @@ -100,13 +99,13 @@ func RunTestCase(testcase *testing.TestCase, ctx interface{}) (output interface{
case *json.UnmarshalTypeError:
if b.Value != "array" {
return
} else {
arrayOutput := []interface{}{}
if err = json.Unmarshal(responseBodyData, &arrayOutput); err != nil {
return
}
output = arrayOutput
}

var arrayOutput []interface{}
if err = json.Unmarshal(responseBodyData, &arrayOutput); err != nil {
return
}
output = arrayOutput
default:
return
}
Expand Down Expand Up @@ -141,7 +140,7 @@ func RunTestCase(testcase *testing.TestCase, ctx interface{}) (output interface{
}

if !result.(bool) {
err = fmt.Errorf("faild to verify: %s", verify)
err = fmt.Errorf("failed to verify: %s", verify)
break
}
}
Expand Down
272 changes: 270 additions & 2 deletions pkg/runner/simple_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package runner

import (
"errors"
"net/http"
"testing"

_ "embed"
"github.com/h2non/gock"
atest "github.com/linuxsuren/api-testing/pkg/testing"
"github.com/stretchr/testify/assert"
Expand All @@ -17,7 +19,7 @@ func TestTestCase(t *testing.T) {
prepare func()
verify func(t *testing.T, output interface{}, err error)
}{{
name: "normal",
name: "normal, response is map",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
Expand Down Expand Up @@ -51,13 +53,279 @@ func TestTestCase(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, map[string]interface{}{"name": "linuxsuren"}, output)
},
}, {
name: "normal, response is slice",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
StatusCode: http.StatusOK,
Body: `["foo", "bar"]`,
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").
Reply(http.StatusOK).
BodyString(`["foo", "bar"]`)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.Nil(t, err)
assert.Equal(t, []interface{}{"foo", "bar"}, output)
},
}, {
name: "normal, response from file",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
Method: http.MethodPost,
BodyFromFile: "testdata/generic_response.json",
},
Expect: atest.Response{
StatusCode: http.StatusOK,
},
},
prepare: func() {
gock.New("http://localhost").
Post("/foo").BodyString(genericBody).
Reply(http.StatusOK).BodyString("123")
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "response from a not found file",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
Method: http.MethodPost,
BodyFromFile: "testdata/fake.json",
},
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "bad request",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
StatusCode: http.StatusOK,
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusBadRequest)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "error with request",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").ReplyError(errors.New("error"))
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "not match with body",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
Body: "bar",
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString("foo")
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "not match with header",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
Header: map[string]string{
"foo": "bar",
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).SetHeader("foo", "value")
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "not found from fields",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
BodyFieldsExpect: map[string]string{
"foo": "bar",
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(genericBody)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "body filed not match",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
BodyFieldsExpect: map[string]string{
"name": "bar",
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(genericBody)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
},
}, {
name: "invalid filed finding",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
BodyFieldsExpect: map[string]string{
"items[1]": "bar",
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(`{"items":[]}`)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "failed to get field")
},
}, {
name: "verify failed",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
Verify: []string{
"len(items) > 0",
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(`{"items":[]}`)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "failed to verify")
},
}, {
name: "failed to compile",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
Verify: []string{
`println("12")`,
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(`{"items":[]}`)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "unknown name println")
},
}, {
name: "failed to compile",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo",
},
Expect: atest.Response{
Verify: []string{
`1 + 1`,
},
},
},
prepare: func() {
gock.New("http://localhost").
Get("/foo").Reply(http.StatusOK).BodyString(`{"items":[]}`)
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "expected bool, but got int")
},
}, {
name: "wrong API format",
testCase: &atest.TestCase{
Request: atest.Request{
API: "ssh://localhost/foo",
Method: "fake,fake",
},
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "invalid method")
},
}, {
name: "failed to render API",
testCase: &atest.TestCase{
Request: atest.Request{
API: "http://localhost/foo/{{.abc}",
},
},
verify: func(t *testing.T, output interface{}, err error) {
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "template: api:1:")
},
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer gock.Clean()
tt.prepare()
if tt.prepare != nil {
tt.prepare()
}
output, err := RunTestCase(tt.testCase, tt.ctx)
tt.verify(t, output, err)
})
}
}

//go:embed testdata/generic_response.json
var genericBody string
3 changes: 1 addition & 2 deletions pkg/testing/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@ func (r *Request) Render(ctx interface{}) (err error) {
buf := new(bytes.Buffer)
if err = tpl.Execute(buf, ctx); err != nil {
return
} else {
r.API = buf.String()
}
r.API = buf.String()

// read body from file
if r.BodyFromFile != "" {
Expand Down