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: env:
IMG_TOOL: docker IMG_TOOL: docker
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs: jobs:
Test: Test:
runs-on: ubuntu-22.04 runs-on: ubuntu-22.04

View File

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

View File

@ -57,10 +57,7 @@ const sendRequest = async () => {
type: 'success' type: 'success'
}) })
} }
if (e.body !== '') { parseResponseBody(e.body)
testResult.value.bodyObject = JSON.parse(e.body)
testResult.value.originBodyObject = JSON.parse(e.body)
}
Cache.SetTestCaseResponseCache(suite + '-' + name, { Cache.SetTestCaseResponseCache(suite + '-' + name, {
body: testResult.value.bodyObject, body: testResult.value.bodyObject,
@ -74,11 +71,24 @@ const sendRequest = async () => {
requestLoading.value = false requestLoading.value = false
UIAPI.ErrorTip(e) 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('') const responseBodyFilterText = ref('')
function responseBodyFilter() { function responseBodyFilter() {
if (responseBodyFilterText.value === '') { if (responseBodyFilterText.value === '') {
@ -803,9 +813,14 @@ const queryHeaderValues = (queryString: string, cb: (arg: any) => void) => {
<Codemirror v-model="testResult.output"/> <Codemirror v-model="testResult.output"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="Body" name="body"> <el-tab-pane label="Body" name="body">
<div v-if="testResult.bodyObject">
<el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText" <el-input :prefix-icon="Search" @change="responseBodyFilter" v-model="responseBodyFilterText"
clearable label="dddd" placeholder="$.key" /> clearable placeholder="$.key" />
<JsonViewer :value="testResult.bodyObject" :expand-depth="5" copyable boxed sort /> <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>
<el-tab-pane name="response-header"> <el-tab-pane name="response-header">
<template #label> <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"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -30,12 +30,13 @@ export interface Suite {
export interface TestResult { export interface TestResult {
body: string body: string
bodyObject: {} bodyObject: {}
bodyText: string
output: string output: string
error: string error: string
statusCode: number statusCode: number
header: Pair[] header: Pair[]
// inner fileds // inner fields
originBodyObject:{} 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) { func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result *TestCaseResult, err error) {
var targetTestSuite testing.TestSuite var targetTestSuite testing.TestSuite
result = &TestCaseResult{}
loader := s.getLoader(ctx) loader := s.getLoader(ctx)
defer loader.Close() defer loader.Close()
targetTestSuite, err = loader.GetTestSuite(in.Suite, true) targetTestSuite, err = loader.GetTestSuite(in.Suite, true)
if err != nil { if err != nil || targetTestSuite.Name == "" {
err = nil err = nil
result = &TestCaseResult{ result.Error = fmt.Sprintf("not found suite: %s", in.Suite)
Error: fmt.Sprintf("not found suite: %s", in.Suite),
}
return return
} }
@ -453,9 +452,10 @@ func (s *server) RunTestCase(ctx context.Context, in *TestCaseIdentity) (result
} }
var reply *TestResult var reply *TestResult
var lastItem *TestCaseResult
if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 { if reply, err = s.Run(ctx, task); err == nil && len(reply.TestCaseResult) > 0 {
lastIndex := len(reply.TestCaseResult) - 1 lastIndex := len(reply.TestCaseResult) - 1
lastItem := reply.TestCaseResult[lastIndex] lastItem = reply.TestCaseResult[lastIndex]
if len(lastItem.Body) > GrpcMaxRecvMsgSize { if len(lastItem.Body) > GrpcMaxRecvMsgSize {
e := "the HTTP response body exceeded the maximum message size limit received by the gRPC client" 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 return
} }
result = &TestCaseResult{
Output: reply.Message,
Error: reply.Error,
Body: lastItem.Body,
Header: lastItem.Header,
StatusCode: lastItem.StatusCode,
}
} else if err != nil { } else if err != nil {
result = &TestCaseResult{ result.Error = err.Error()
Error: err.Error(),
} }
} else {
result = &TestCaseResult{ if reply != nil {
Output: reply.Message, result.Output = reply.Message
Error: reply.Error, result.Error = reply.Error
} }
if lastItem != nil {
result.Body = lastItem.Body
result.Header = lastItem.Header
result.StatusCode = lastItem.StatusCode
} }
} }
return return

View File

@ -31,6 +31,7 @@ import (
"github.com/h2non/gock" "github.com/h2non/gock"
atest "github.com/linuxsuren/api-testing/pkg/testing" atest "github.com/linuxsuren/api-testing/pkg/testing"
"github.com/linuxsuren/api-testing/pkg/util"
"github.com/linuxsuren/api-testing/sample" "github.com/linuxsuren/api-testing/sample"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -127,22 +128,49 @@ func TestRemoteServer(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
const sampleBody = `{"message": "hello"}`
func TestRunTestCase(t *testing.T) { func TestRunTestCase(t *testing.T) {
loader := atest.NewFileWriter("") loader := atest.NewFileWriter("")
loader.Put("testdata/simple.yaml") loader.Put("testdata/simple.yaml")
server := NewRemoteServer(loader, nil, nil, nil, "", 1024*1024*4) server := NewRemoteServer(loader, nil, nil, nil, "", 1024*1024*4)
t.Run("json response", func(t *testing.T) {
defer gock.Clean() defer gock.Clean()
gock.New(urlFoo).Get("/").MatchHeader("key", "value"). gock.New(urlFoo).Get("/").MatchHeader("key", "value").
Reply(http.StatusOK). Reply(http.StatusOK).SetHeader(util.ContentType, util.JSON).
BodyString(`{"message": "hello"}`) BodyString(sampleBody)
result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{ result, err := server.RunTestCase(context.TODO(), &TestCaseIdentity{
Suite: "simple", Suite: "simple",
Testcase: "get", Testcase: "get",
}) })
assert.NoError(t, err) 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") 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)
})
} }
func TestFindParentTestCases(t *testing.T) { func TestFindParentTestCases(t *testing.T) {