feat: support to return the body string even it is invalid (#453)

Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
Rick 2024-05-24 08:36:18 +08:00 committed by GitHub
parent 98b4dae698
commit ce5ad55216
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 85 additions and 42 deletions

View File

@ -5,6 +5,10 @@ on:
env:
IMG_TOOL: docker
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
Test:
runs-on: ubuntu-22.04

View File

@ -5,11 +5,11 @@ on:
push:
branches:
- master
- feat/mock-timer
jobs:
qodana:
runs-on: ubuntu-latest
if: github.actor == 'linuxsuren'
steps:
- uses: actions/checkout@v3
with:

View File

@ -57,10 +57,7 @@ const sendRequest = async () => {
type: 'success'
})
}
if (e.body !== '') {
testResult.value.bodyObject = JSON.parse(e.body)
testResult.value.originBodyObject = JSON.parse(e.body)
}
parseResponseBody(e.body)
Cache.SetTestCaseResponseCache(suite + '-' + name, {
body: testResult.value.bodyObject,
@ -74,11 +71,24 @@ const sendRequest = async () => {
requestLoading.value = false
UIAPI.ErrorTip(e)
testResult.value.bodyObject = JSON.parse(e.body)
testResult.value.originBodyObject = JSON.parse(e.body)
parseResponseBody(e.body)
})
}
const parseResponseBody = (body) => {
if (body === '') {
return
}
try {
testResult.value.bodyObject = JSON.parse(body)
testResult.value.originBodyObject = JSON.parse(body)
} catch {
testResult.value.bodyText = body
}
}
const responseBodyFilterText = ref('')
function responseBodyFilter() {
if (responseBodyFilterText.value === '') {
@ -803,9 +813,14 @@ const queryHeaderValues = (queryString: string, cb: (arg: any) => void) => {
<Codemirror v-model="testResult.output"/>
</el-tab-pane>
<el-tab-pane label="Body" name="body">
<el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText"
clearable label="dddd" placeholder="$.key" />
<JsonViewer :value="testResult.bodyObject" :expand-depth="5" copyable boxed sort />
<div v-if="testResult.bodyObject">
<el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText"
clearable placeholder="$.key" />
<JsonViewer :value="testResult.bodyObject" :expand-depth="2" copyable boxed sort />
</div>
<div v-else>
<Codemirror v-model="testResult.bodyText"/>
</div>
</el-tab-pane>
<el-tab-pane name="response-header">
<template #label>

View File

@ -1,5 +1,5 @@
/*
Copyright 2023 API Testing Authors.
Copyright 2023-2024 API Testing Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -30,12 +30,13 @@ export interface Suite {
export interface TestResult {
body: string
bodyObject: {}
bodyText: string
output: string
error: string
statusCode: number
header: Pair[]
// inner fileds
// inner fields
originBodyObject:{}
}

View File

@ -431,14 +431,13 @@ func (s *server) GetTestCase(ctx context.Context, in *TestCaseIdentity) (reply *
func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result *TestCaseResult, err error) {
var targetTestSuite testing.TestSuite
result = &TestCaseResult{}
loader := s.getLoader(ctx)
defer loader.Close()
targetTestSuite, err = loader.GetTestSuite(in.Suite, true)
if err != nil {
if err != nil || targetTestSuite.Name == "" {
err = nil
result = &TestCaseResult{
Error: fmt.Sprintf("not found suite: %s", in.Suite),
}
result.Error = fmt.Sprintf("not found suite: %s", in.Suite)
return
}
@ -453,9 +452,10 @@ func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result
}
var reply *TestResult
var lastItem *TestCaseResult
if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 {
lastIndex := len(reply.TestCaseResult) - 1
lastItem := reply.TestCaseResult[lastIndex]
lastItem = reply.TestCaseResult[lastIndex]
if len(lastItem.Body) > GrpcMaxRecvMsgSize {
e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client"
@ -468,23 +468,18 @@ func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result
}
return
}
result = &TestCaseResult{
Output: reply.Message,
Error: reply.Error,
Body: lastItem.Body,
Header: lastItem.Header,
StatusCode: lastItem.StatusCode,
}
} else if err != nil {
result = &TestCaseResult{
Error: err.Error(),
}
} else {
result = &TestCaseResult{
Output: reply.Message,
Error: reply.Error,
}
result.Error = err.Error()
}
if reply != nil {
result.Output = reply.Message
result.Error = reply.Error
}
if lastItem != nil {
result.Body = lastItem.Body
result.Header = lastItem.Header
result.StatusCode = lastItem.StatusCode
}
}
return

View File

@ -31,6 +31,7 @@ import (
"github.com/h2non/gock"
atest "github.com/linuxsuren/api-testing/pkg/testing"
"github.com/linuxsuren/api-testing/pkg/util"
"github.com/linuxsuren/api-testing/sample"
"github.com/stretchr/testify/assert"
"google.golang.org/grpc/metadata"
@ -127,22 +128,49 @@ func TestRemoteServer(t *testing.T) {
assert.Error(t, err)
}
const sampleBody = `{"message": "hello"}`
func TestRunTestCase(t *testing.T) {
loader := atest.NewFileWriter("")
loader.Put("testdata/simple.yaml")
server := NewRemoteServer(loader, nil, nil, nil, "", 1024*1024*4)
defer gock.Clean()
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
Reply(http.StatusOK).
BodyString(`{"message": "hello"}`)
t.Run("json response", func(t *testing.T) {
defer gock.Clean()
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
Reply(http.StatusOK).SetHeader(util.ContentType, util.JSON).
BodyString(sampleBody)
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
Suite: "simple",
Testcase: "get",
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
Suite: "simple",
Testcase: "get",
})
assert.NoError(t, err)
assert.Equal(t, sampleBody, result.Body)
assert.Contains(t, result.Output, "start to run: 'get'\nstart to send request to http://foo\ntest case \"get\", status code: 200\n")
})
t.Run("text response", func(t *testing.T) {
defer gock.Clean()
gock.New(urlFoo).Get("/").MatchHeader("key", "value").
Reply(http.StatusOK).SetHeader(util.ContentType, util.Plain).
BodyString(sampleBody)
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
Suite: "simple",
Testcase: "get",
})
assert.NoError(t, err)
assert.Equal(t, sampleBody, result.Body)
})
t.Run("not suite found", func(t *testing.T) {
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
Suite: "not-found",
})
assert.NoError(t, err)
assert.NotEmpty(t, result.Error)
})
assert.NoError(t, err)
assert.Contains(t, result.Output, "start to run: 'get'\nstart to send request to http://foo\ntest case \"get\", status code: 200\n")
}
func TestFindParentTestCases(t *testing.T) {