fix: the shell, python generator is incorrect (#601)

* fix: the shell, python generator is incorrect

* update go.sum

* update the end-of-line

* remove go.work.sum

---------

Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
Rick 2025-01-26 10:54:25 +08:00 committed by GitHub
parent 768b79f0c3
commit 664451e6ee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 210 additions and 2600 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
* text eol=lf

280
README.md
View File

@ -1,140 +1,140 @@
[![CLA assistant](https://cla-assistant.io/readme/badge/LinuxSuRen/api-testing)](https://cla-assistant.io/LinuxSuRen/api-testing)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3f16717cd6f841118006f12c346e9341)](https://app.codacy.com/gh/LinuxSuRen/api-testing/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/3f16717cd6f841118006f12c346e9341)](https://app.codacy.com/gh/LinuxSuRen/api-testing/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![GitHub All Releases](https://img.shields.io/github/downloads/linuxsuren/api-testing/total)](https://tooomm.github.io/github-release-stats/?username=linuxsuren&repository=api-testing)
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxsuren/api-testing)](https://hub.docker.com/r/linuxsuren/api-testing)
[![LinuxSuRen/open-source-best-practice](https://img.shields.io/static/v1?label=OSBP&message=%E5%BC%80%E6%BA%90%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5&color=blue)](https://github.com/LinuxSuRen/open-source-best-practice)
![GitHub Created At](https://img.shields.io/github/created-at/linuxsuren/api-testing)
> English | [中文](README-ZH.md)
This is an awesome API testing tool. 🚀
## Features
* Supported protocols: HTTP, gRPC, tRPC
* Multiple test report formats: Markdown, HTML, PDF, Stdout
* Mock Server in simple configuration, and Open API support
* Support converting to [JMeter](https://jmeter.apache.org/) files
* Response Body fields equation check or [eval](https://expr.medv.io/)
* Validate the response body with [JSON schema](https://json-schema.org/)
* Pre and post handle with the API request
* Run in server mode, and provide the [gRPC](pkg/server/server.proto) and HTTP endpoint
* [VS Code extension](https://github.com/LinuxSuRen/vscode-api-testing) support
* Multiple storage backends supported(Local, ORM Database, S3, Git, Etcd, etc.)
* [HTTP API record](https://github.com/LinuxSuRen/atest-ext-collector)
* Install in multiple use cases(CLI, Container, Native-Service, [Operator](https://github.com/LinuxSuRen/atest-operator), Helm, etc.)
* Monitoring integration with Prometheus, SkyWalking
## Get started
[![Try in PWD](https://github.com/play-with-docker/stacks/raw/cff22438cb4195ace27f9b15784bbb497047afa7/assets/images/button.png)](http://play-with-docker.com?stack=https://raw.githubusercontent.com/LinuxSuRen/api-testing/master/docs/manifests/docker-compose.yml)
Install it via [hd](https://github.com/LinuxSuRen/http-downloader) or download from [releases](https://github.com/LinuxSuRen/api-testing/releases):
```shell
hd install atest
```
or, you can install it in Kubernetes. See also the [manifests](docs/manifests/kubernetes/default/manifest.yaml).
see the following usage:
```shell
API testing tool
Usage:
atest [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
func Print all the supported functions
help Help about any command
json Print the JSON schema of the test suites struct
run Run the test suite
sample Generate a sample test case YAML file
server Run as a server mode
service Install atest as a Linux service
Flags:
-h, --help help for atest
-v, --version version for atest
Use "atest [command] --help" for more information about a command.
```
below is an example of the usage, and you could see the report as well:
`atest run -p sample/testsuite-gitlab.yaml --duration 1m --thread 3 --report md`
| API | Average | Max | Min | Count | Error |
|---|---|---|---|---|---|
| GET https://gitlab.com/api/v4/projects | 1.152777167s | 2.108680194s | 814.928496ms | 99 | 0 |
| GET https://gitlab.com/api/v4/projects/45088772 | 840.761064ms | 1.487285371s | 492.583066ms | 10 | 0 |
consume: 1m2.153686448s
## Use in Docker
Use `atest` as server mode in Docker, then you could visit the UI from `8080`:
```bash
docker run --pull always -p 8080:8080 ghcr.io/linuxsuren/api-testing:master
```
Use `atest-collector` in Docker:
```bash
docker run -p 1234:8080 -v /var/tmp:/var/tmp \
ghcr.io/linuxsuren/api-testing atest-collector \
--filter-path /api \
-o /var/tmp/sample.yaml
# you could find the test cases file from /var/tmp/sample
# cat /var/tmp/sample
```
## Template
The following fields are templated with [sprig](https://masterminds.github.io/sprig/):
* API
* Request Body
* Request Header
### Functions
You could use all the common functions which comes from [sprig](https://masterminds.github.io/sprig/). Besides some specific functions are available:
| Name | Usage |
|---|---|
| `randomKubernetesName` | `{{randomKubernetesName}}` to generate Kubernetes resource name randomly, the name will have 8 chars |
| `sleep` | `{{sleep(1)}}` in the pre and post request handle |
## Verify against Kubernetes
It could verify any kinds of Kubernetes resources. Please set the environment variables before using it:
* `KUBERNETES_SERVER`
* `KUBERNETES_TOKEN`
See also the [example](sample/kubernetes.yaml).
## TODO
* Reduce the size of context.
* Support customized context.
## Limit
* Only support to parse the response body when it's a map or array.
## Community Exchange
Feel free to talk to us about any questions you may have about API Testing in the following ways.
### Mailing List
`api-testing-tech@googlegroups.com`, Feel free to discuss everything related to API Testing via this mailing list.
### `GitHub` discussion
[GitHub Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)
[![CLA assistant](https://cla-assistant.io/readme/badge/LinuxSuRen/api-testing)](https://cla-assistant.io/LinuxSuRen/api-testing)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/3f16717cd6f841118006f12c346e9341)](https://app.codacy.com/gh/LinuxSuRen/api-testing/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/3f16717cd6f841118006f12c346e9341)](https://app.codacy.com/gh/LinuxSuRen/api-testing/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
[![GitHub All Releases](https://img.shields.io/github/downloads/linuxsuren/api-testing/total)](https://tooomm.github.io/github-release-stats/?username=linuxsuren&repository=api-testing)
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxsuren/api-testing)](https://hub.docker.com/r/linuxsuren/api-testing)
[![LinuxSuRen/open-source-best-practice](https://img.shields.io/static/v1?label=OSBP&message=%E5%BC%80%E6%BA%90%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5&color=blue)](https://github.com/LinuxSuRen/open-source-best-practice)
![GitHub Created At](https://img.shields.io/github/created-at/linuxsuren/api-testing)
> English | [中文](README-ZH.md)
This is an awesome API testing tool. 🚀
## Features
* Supported protocols: HTTP, gRPC, tRPC
* Multiple test report formats: Markdown, HTML, PDF, Stdout
* Mock Server in simple configuration, and Open API support
* Support converting to [JMeter](https://jmeter.apache.org/) files
* Response Body fields equation check or [eval](https://expr.medv.io/)
* Validate the response body with [JSON schema](https://json-schema.org/)
* Pre and post handle with the API request
* Run in server mode, and provide the [gRPC](pkg/server/server.proto) and HTTP endpoint
* [VS Code extension](https://github.com/LinuxSuRen/vscode-api-testing) support
* Multiple storage backends supported(Local, ORM Database, S3, Git, Etcd, etc.)
* [HTTP API record](https://github.com/LinuxSuRen/atest-ext-collector)
* Install in multiple use cases(CLI, Container, Native-Service, [Operator](https://github.com/LinuxSuRen/atest-operator), Helm, etc.)
* Monitoring integration with Prometheus, SkyWalking
## Get started
[![Try in PWD](https://github.com/play-with-docker/stacks/raw/cff22438cb4195ace27f9b15784bbb497047afa7/assets/images/button.png)](http://play-with-docker.com?stack=https://raw.githubusercontent.com/LinuxSuRen/api-testing/master/docs/manifests/docker-compose.yml)
Install it via [hd](https://github.com/LinuxSuRen/http-downloader) or download from [releases](https://github.com/LinuxSuRen/api-testing/releases):
```shell
hd install atest
```
or, you can install it in Kubernetes. See also the [manifests](docs/manifests/kubernetes/default/manifest.yaml).
see the following usage:
```shell
API testing tool
Usage:
atest [command]
Available Commands:
completion Generate the autocompletion script for the specified shell
func Print all the supported functions
help Help about any command
json Print the JSON schema of the test suites struct
run Run the test suite
sample Generate a sample test case YAML file
server Run as a server mode
service Install atest as a Linux service
Flags:
-h, --help help for atest
-v, --version version for atest
Use "atest [command] --help" for more information about a command.
```
below is an example of the usage, and you could see the report as well:
`atest run -p sample/testsuite-gitlab.yaml --duration 1m --thread 3 --report md`
| API | Average | Max | Min | Count | Error |
|---|---|---|---|---|---|
| GET https://gitlab.com/api/v4/projects | 1.152777167s | 2.108680194s | 814.928496ms | 99 | 0 |
| GET https://gitlab.com/api/v4/projects/45088772 | 840.761064ms | 1.487285371s | 492.583066ms | 10 | 0 |
consume: 1m2.153686448s
## Use in Docker
Use `atest` as server mode in Docker, then you could visit the UI from `8080`:
```bash
docker run --pull always -p 8080:8080 ghcr.io/linuxsuren/api-testing:master
```
Use `atest-collector` in Docker:
```bash
docker run -p 1234:8080 -v /var/tmp:/var/tmp \
ghcr.io/linuxsuren/api-testing atest-collector \
--filter-path /api \
-o /var/tmp/sample.yaml
# you could find the test cases file from /var/tmp/sample
# cat /var/tmp/sample
```
## Template
The following fields are templated with [sprig](https://masterminds.github.io/sprig/):
* API
* Request Body
* Request Header
### Functions
You could use all the common functions which comes from [sprig](https://masterminds.github.io/sprig/). Besides some specific functions are available:
| Name | Usage |
|---|---|
| `randomKubernetesName` | `{{randomKubernetesName}}` to generate Kubernetes resource name randomly, the name will have 8 chars |
| `sleep` | `{{sleep(1)}}` in the pre and post request handle |
## Verify against Kubernetes
It could verify any kinds of Kubernetes resources. Please set the environment variables before using it:
* `KUBERNETES_SERVER`
* `KUBERNETES_TOKEN`
See also the [example](sample/kubernetes.yaml).
## TODO
* Reduce the size of context.
* Support customized context.
## Limit
* Only support to parse the response body when it's a map or array.
## Community Exchange
Feel free to talk to us about any questions you may have about API Testing in the following ways.
### Mailing List
`api-testing-tech@googlegroups.com`, Feel free to discuss everything related to API Testing via this mailing list.
### `GitHub` discussion
[GitHub Discussion](https://github.com/LinuxSuRen/api-testing/discussions/new/choose)

File diff suppressed because it is too large Load Diff

View File

@ -83,6 +83,11 @@ func generate(testsuite *testing.TestSuite, testcase *testing.TestCase, template
}
}
}
if testcase != nil {
if err = testcase.Request.Render(nil, ""); err != nil {
return
}
}
var tpl *template.Template
if tpl, err = template.New(templateName).
Funcs(template.FuncMap{"safeString": safeString}).

View File

@ -1,5 +1,5 @@
/*
Copyright 2023 API Testing Authors.
Copyright 2023-2025 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.
@ -16,53 +16,56 @@ limitations under the License.
package generator
import (
"bytes"
_ "embed"
"net/http"
"strings"
"text/template"
"bytes"
_ "embed"
"net/http"
"strings"
"text/template"
"github.com/linuxsuren/api-testing/pkg/testing"
"github.com/linuxsuren/api-testing/pkg/testing"
)
type curlGenerator struct {
}
func NewCurlGenerator() CodeGenerator {
return &curlGenerator{}
return &curlGenerator{}
}
func (g *curlGenerator) Generate(testSuite *testing.TestSuite, testcase *testing.TestCase) (result string, err error) {
if testcase.Request.Method == "" {
testcase.Request.Method = http.MethodGet
}
if testcase.Request.Method == "" {
testcase.Request.Method = http.MethodGet
}
if !strings.HasSuffix(testcase.Request.API, "?") {
testcase.Request.API += "?"
}
if !strings.HasSuffix(testcase.Request.API, "?") {
testcase.Request.API += "?"
}
queryKeys := testcase.Request.Query.Keys()
for _, k := range queryKeys {
testcase.Request.API += k + "=" + testcase.Request.Query.GetValue(k) + "&"
}
queryKeys := testcase.Request.Query.Keys()
for _, k := range queryKeys {
testcase.Request.API += k + "=" + testcase.Request.Query.GetValue(k) + "&"
}
testcase.Request.API = strings.TrimSuffix(testcase.Request.API, "&")
testcase.Request.API = strings.TrimSuffix(testcase.Request.API, "?")
testcase.Request.API = strings.TrimSuffix(testcase.Request.API, "&")
testcase.Request.API = strings.TrimSuffix(testcase.Request.API, "?")
if err = testcase.Request.Render(nil, ""); err != nil {
return
}
var tpl *template.Template
if tpl, err = template.New("curl template").Parse(curlTemplate); err == nil {
buf := new(bytes.Buffer)
if err = tpl.Execute(buf, testcase); err == nil {
result = strings.TrimSpace(buf.String())
var tpl *template.Template
if tpl, err = template.New("curl template").Parse(curlTemplate); err == nil {
buf := new(bytes.Buffer)
if err = tpl.Execute(buf, testcase); err == nil {
result = strings.TrimSpace(buf.String())
result = strings.ReplaceAll(result, "\n", " \\\n")
}
}
return
result = strings.TrimSuffix(result, " \\")
}
}
return
}
func init() {
RegisterCodeGenerator("curl", NewCurlGenerator())
RegisterCodeGenerator("curl", NewCurlGenerator())
}
//go:embed data/curl.tpl

View File

@ -1,5 +1,5 @@
/*
Copyright 2023 API Testing Authors.
Copyright 2023-2025 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.
@ -35,7 +35,7 @@ func TestCurlGenerator(t *testing.T) {
API: fooForTest,
},
},
expect: `curl -X GET 'http://foo'`,
expect: `curl -k -X GET 'http://foo'`,
}, {
name: "has query string",
testCase: atest.TestCase{
@ -47,7 +47,7 @@ func TestCurlGenerator(t *testing.T) {
},
},
},
expect: `curl -X GET 'http://foo?page=1&size=10'`,
expect: `curl -k -X GET 'http://foo?page=1&size=10'`,
}, {
name: "basic HTTP POST",
testCase: atest.TestCase{
@ -56,7 +56,7 @@ func TestCurlGenerator(t *testing.T) {
Method: http.MethodPost,
},
},
expect: `curl -X POST 'http://foo'`,
expect: `curl -k -X POST 'http://foo'`,
}, {
name: "has header",
testCase: atest.TestCase{
@ -68,7 +68,7 @@ func TestCurlGenerator(t *testing.T) {
},
},
},
expect: `curl -X GET 'http://foo' \
expect: `curl -k -X GET 'http://foo' \
-H 'Connection: keep-alive' \
-H 'Content-Type: text/plain'`,
}, {
@ -79,8 +79,20 @@ func TestCurlGenerator(t *testing.T) {
Body: atest.NewRequestBody("hello"),
},
},
expect: `curl -X GET 'http://foo' \
expect: `curl -k -X GET 'http://foo' \
--data-raw 'hello'`,
}, {
name: "include golang template",
testCase: atest.TestCase{
Request: atest.Request{
API: fooForTest,
Header: map[string]string{
util.ContentType: `{{ base64 "test"}}`,
},
},
},
expect: `curl -k -X GET 'http://foo' \
-H 'Content-Type: dGVzdA=='`,
}}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

View File

@ -1,6 +1,6 @@
curl -X {{.Request.Method}} '{{.Request.API}}'
curl -k -X {{.Request.Method}} '{{.Request.API}}' \
{{- range $key, $val := .Request.Header}}
-H '{{$key}}: {{$val}}'
-H '{{$key}}: {{$val}}' \
{{- end}}
{{- if .Request.Body.String }}
--data-raw '{{.Request.Body.String}}'

View File

@ -1,5 +1,5 @@
'''
Copyright 2024 API Testing Authors.
Copyright 2024-2025 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.
You may obtain a copy of the License at
@ -23,7 +23,7 @@ def main():
{{- end}}
body = io.BytesIO(encoded_data.encode("utf-8"))
{{- else}}
body = io.BytesIO(b"{{.Request.Body.String}}")
body = io.BytesIO(b"""{{.Request.Body.String}}""")
{{- end}}
{{- if gt (len .Request.Header) 0 }}
{{- range $key, $val := .Request.Header}}
@ -49,7 +49,7 @@ def main():
raise e
{{- end}}
resp = requests.Session().send(req.prepare())
resp = requests.Session().send(req.prepare(), verify=False)
if resp.status_code != 200:
raise Exception("status code is not 200")

View File

@ -1,5 +1,5 @@
'''
Copyright 2024 API Testing Authors.
Copyright 2024-2025 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.
You may obtain a copy of the License at
@ -15,14 +15,14 @@ import requests
from urllib.parse import urlencode
def main():
body = io.BytesIO(b"")
body = io.BytesIO(b"""""")
headers = {"User-Agent": "atest"}
try:
req = requests.Request("GET", "https://www.baidu.com", headers=headers, data=body)
except requests.RequestException as e:
raise e
resp = requests.Session().send(req.prepare())
resp = requests.Session().send(req.prepare(), verify=False)
if resp.status_code != 200:
raise Exception("status code is not 200")

View File

@ -1,5 +1,5 @@
'''
Copyright 2024 API Testing Authors.
Copyright 2024-2025 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.
You may obtain a copy of the License at
@ -26,7 +26,7 @@ def main():
except requests.RequestException as e:
raise e
resp = requests.Session().send(req.prepare())
resp = requests.Session().send(req.prepare(), verify=False)
if resp.status_code != 200:
raise Exception("status code is not 200")

View File

@ -1,5 +1,5 @@
'''
Copyright 2024 API Testing Authors.
Copyright 2024-2025 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.
You may obtain a copy of the License at
@ -25,7 +25,7 @@ def main():
except requests.RequestException as e:
raise e
resp = requests.Session().send(req.prepare())
resp = requests.Session().send(req.prepare(), verify=False)
if resp.status_code != 200:
raise Exception("status code is not 200")

View File

@ -945,4 +945,4 @@ mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 h1:zCr3iRRgdk5eIikZNDphGcM6K
mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14/go.mod h1:ZzZjEpJDOmx8TdVU6umamY3Xy0UAQUI2DHbf05USVbI=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=