mirror of
https://github.com/httprunner/httprunner.git
synced 2026-06-25 17:44:02 +08:00
refactor: move LoadFile to hrp/loader
This commit is contained in:
2
go.mod
2
go.mod
@@ -30,6 +30,7 @@ require (
|
||||
golang.org/x/oauth2 v0.8.0
|
||||
google.golang.org/grpc v1.57.0
|
||||
google.golang.org/protobuf v1.32.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
howett.net/plist v1.0.0
|
||||
)
|
||||
@@ -77,7 +78,6 @@ require (
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
// replace github.com/httprunner/funplugin => ../funplugin
|
||||
|
||||
@@ -235,70 +235,6 @@ func InterfaceType(raw interface{}) string {
|
||||
return reflect.TypeOf(raw).String()
|
||||
}
|
||||
|
||||
// LoadFile loads file content with file extension and assigns to structObj
|
||||
func LoadFile(path string, structObj interface{}) (err error) {
|
||||
log.Info().Str("path", path).Msg("load file")
|
||||
file, err := ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read file failed")
|
||||
}
|
||||
// remove BOM at the beginning of file
|
||||
file = bytes.TrimLeft(file, "\xef\xbb\xbf")
|
||||
ext := filepath.Ext(path)
|
||||
switch ext {
|
||||
case ".json", ".har":
|
||||
decoder := json.NewDecoder(bytes.NewReader(file))
|
||||
decoder.UseNumber()
|
||||
err = decoder.Decode(structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadJSONError, err.Error())
|
||||
}
|
||||
case ".yaml", ".yml":
|
||||
err = yaml.Unmarshal(file, structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadYAMLError, err.Error())
|
||||
}
|
||||
case ".env":
|
||||
err = parseEnvContent(file, structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadEnvError, err.Error())
|
||||
}
|
||||
default:
|
||||
err = code.UnsupportedFileExtension
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func parseEnvContent(file []byte, obj interface{}) error {
|
||||
envMap := obj.(map[string]string)
|
||||
lines := strings.Split(string(file), "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
// empty line or comment line
|
||||
continue
|
||||
}
|
||||
var kv []string
|
||||
if strings.Contains(line, "=") {
|
||||
kv = strings.SplitN(line, "=", 2)
|
||||
} else if strings.Contains(line, ":") {
|
||||
kv = strings.SplitN(line, ":", 2)
|
||||
}
|
||||
if len(kv) != 2 {
|
||||
return errors.New(".env format error")
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(kv[0])
|
||||
value := strings.TrimSpace(kv[1])
|
||||
envMap[key] = value
|
||||
|
||||
// set env
|
||||
log.Info().Str("key", key).Msg("set env")
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadFromCSV(path string) []map[string]interface{} {
|
||||
log.Info().Str("path", path).Msg("load csv file")
|
||||
file, err := ReadFile(path)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package hrp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -8,6 +9,11 @@ import (
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/code"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/json"
|
||||
)
|
||||
|
||||
// LoadTestCases load testcases from TestCasePath or TestCase
|
||||
@@ -63,3 +69,67 @@ func LoadTestCases(tests ...ITestCase) ([]*TestCase, error) {
|
||||
log.Info().Int("count", len(testCases)).Msg("load testcases successfully")
|
||||
return testCases, nil
|
||||
}
|
||||
|
||||
// LoadFile loads file content with file extension and assigns to structObj
|
||||
func LoadFile(path string, structObj interface{}) (err error) {
|
||||
log.Info().Str("path", path).Msg("load file")
|
||||
file, err := builtin.ReadFile(path)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "read file failed")
|
||||
}
|
||||
// remove BOM at the beginning of file
|
||||
file = bytes.TrimLeft(file, "\xef\xbb\xbf")
|
||||
ext := filepath.Ext(path)
|
||||
switch ext {
|
||||
case ".json", ".har":
|
||||
decoder := json.NewDecoder(bytes.NewReader(file))
|
||||
decoder.UseNumber()
|
||||
err = decoder.Decode(structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadJSONError, err.Error())
|
||||
}
|
||||
case ".yaml", ".yml":
|
||||
err = yaml.Unmarshal(file, structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadYAMLError, err.Error())
|
||||
}
|
||||
case ".env":
|
||||
err = parseEnvContent(file, structObj)
|
||||
if err != nil {
|
||||
err = errors.Wrap(code.LoadEnvError, err.Error())
|
||||
}
|
||||
default:
|
||||
err = code.UnsupportedFileExtension
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func parseEnvContent(file []byte, obj interface{}) error {
|
||||
envMap := obj.(map[string]string)
|
||||
lines := strings.Split(string(file), "\n")
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
// empty line or comment line
|
||||
continue
|
||||
}
|
||||
var kv []string
|
||||
if strings.Contains(line, "=") {
|
||||
kv = strings.SplitN(line, "=", 2)
|
||||
} else if strings.Contains(line, ":") {
|
||||
kv = strings.SplitN(line, ":", 2)
|
||||
}
|
||||
if len(kv) != 2 {
|
||||
return errors.New(".env format error")
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(kv[0])
|
||||
value := strings.TrimSpace(kv[1])
|
||||
envMap[key] = value
|
||||
|
||||
// set env
|
||||
log.Info().Str("key", key).Msg("set env")
|
||||
os.Setenv(key, value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -49,3 +49,29 @@ func TestLoadTestCases(t *testing.T) {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadCase(t *testing.T) {
|
||||
tcJSON := &TestCase{}
|
||||
tcYAML := &TestCase{}
|
||||
err := LoadFile(demoTestCaseWithPluginJSONPath, tcJSON)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
err = LoadFile(demoTestCaseWithPluginYAMLPath, tcYAML)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
if !assert.Equal(t, tcJSON.Config.Name, tcYAML.Config.Name) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Config.BaseURL, tcYAML.Config.BaseURL) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Steps[1].Name, tcYAML.Steps[1].Name) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Steps[1].Request, tcYAML.Steps[1].Request) {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/json"
|
||||
)
|
||||
|
||||
@@ -371,7 +370,7 @@ func LoadHARCase(path string) (*hrp.TestCase, error) {
|
||||
|
||||
func loadCaseHAR(path string) (*CaseHar, error) {
|
||||
caseHAR := new(CaseHar)
|
||||
err := builtin.LoadFile(path, caseHAR)
|
||||
err := hrp.LoadFile(path, caseHAR)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "load har file failed")
|
||||
}
|
||||
|
||||
@@ -5,13 +5,12 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
func LoadJSONCase(path string) (*hrp.TestCase, error) {
|
||||
log.Info().Str("path", path).Msg("load json case file")
|
||||
caseJSON := new(hrp.TestCase)
|
||||
err := builtin.LoadFile(path, caseJSON)
|
||||
err := hrp.LoadFile(path, caseJSON)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "load json file failed")
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/json"
|
||||
)
|
||||
|
||||
@@ -125,7 +124,7 @@ func LoadPostmanCase(path string) (*hrp.TestCase, error) {
|
||||
|
||||
func loadCasePostman(path string) (*CasePostman, error) {
|
||||
casePostman := new(CasePostman)
|
||||
err := builtin.LoadFile(path, casePostman)
|
||||
err := hrp.LoadFile(path, casePostman)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "load postman file failed")
|
||||
}
|
||||
|
||||
@@ -5,13 +5,12 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
func LoadSwaggerCase(path string) (*hrp.TestCase, error) {
|
||||
// load swagger file
|
||||
caseSwagger := new(spec.Swagger)
|
||||
err := builtin.LoadFile(path, caseSwagger)
|
||||
err := hrp.LoadFile(path, caseSwagger)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "load swagger file failed")
|
||||
}
|
||||
|
||||
@@ -6,13 +6,12 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp"
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
func LoadYAMLCase(path string) (*hrp.TestCase, error) {
|
||||
// load yaml case file
|
||||
caseJSON := new(hrp.TestCase)
|
||||
err := builtin.LoadFile(path, caseJSON)
|
||||
err := hrp.LoadFile(path, caseJSON)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "load yaml file failed")
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ func (c *TCaseConverter) genOutputPath(suffix string) string {
|
||||
func (c *TCaseConverter) overrideWithProfile(path string) error {
|
||||
log.Info().Str("path", path).Msg("load profile")
|
||||
profile := new(Profile)
|
||||
err := builtin.LoadFile(path, profile)
|
||||
err := hrp.LoadFile(path, profile)
|
||||
if err != nil {
|
||||
log.Warn().Str("path", path).
|
||||
Msg("failed to load profile, ignore!")
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
// IAPI represents interface for api,
|
||||
@@ -46,7 +44,7 @@ func (path *APIPath) GetPath() string {
|
||||
func (path *APIPath) ToAPI() (*API, error) {
|
||||
api := &API{}
|
||||
apiPath := path.GetPath()
|
||||
err := builtin.LoadFile(apiPath, api)
|
||||
err := LoadFile(apiPath, api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ type TestCasePath string
|
||||
func (path *TestCasePath) GetTestCase() (*TestCase, error) {
|
||||
tc := &TestCase{}
|
||||
casePath := string(*path)
|
||||
err := builtin.LoadFile(casePath, tc)
|
||||
err := LoadFile(casePath, tc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +137,7 @@ func (tc *TestCase) loadISteps() (*TestCase, error) {
|
||||
dotEnvPath := filepath.Join(projectRootDir, ".env")
|
||||
if builtin.IsFilePathExists(dotEnvPath) {
|
||||
envVars := make(map[string]string)
|
||||
err = builtin.LoadFile(dotEnvPath, envVars)
|
||||
err = LoadFile(dotEnvPath, envVars)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to load .env file")
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/httprunner/httprunner/v4/hrp/internal/builtin"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -175,32 +173,6 @@ func TestGenDemoTestCase(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadCase(t *testing.T) {
|
||||
tcJSON := &TestCase{}
|
||||
tcYAML := &TestCase{}
|
||||
err := builtin.LoadFile(demoTestCaseWithPluginJSONPath, tcJSON)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
err = builtin.LoadFile(demoTestCaseWithPluginYAMLPath, tcYAML)
|
||||
if !assert.NoError(t, err) {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
if !assert.Equal(t, tcJSON.Config.Name, tcYAML.Config.Name) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Config.BaseURL, tcYAML.Config.BaseURL) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Steps[1].Name, tcYAML.Steps[1].Name) {
|
||||
t.Fatal()
|
||||
}
|
||||
if !assert.Equal(t, tcJSON.Steps[1].Request, tcYAML.Steps[1].Request) {
|
||||
t.Fatal()
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertCheckExpr(t *testing.T) {
|
||||
exprs := []struct {
|
||||
before string
|
||||
|
||||
Reference in New Issue
Block a user