mirror of
https://github.com/httprunner/httprunner.git
synced 2026-09-05 07:26:55 +08:00
refactor: move uixt pkg
This commit is contained in:
+230
@@ -0,0 +1,230 @@
|
||||
package convert
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
|
||||
hrp "github.com/httprunner/httprunner/v5"
|
||||
"github.com/httprunner/httprunner/v5/internal/builtin"
|
||||
"github.com/httprunner/httprunner/v5/internal/sdk"
|
||||
)
|
||||
|
||||
// target testcase format extensions
|
||||
const (
|
||||
suffixJSON = ".json"
|
||||
suffixYAML = ".yaml"
|
||||
suffixGoTest = ".go"
|
||||
suffixPyTest = ".py"
|
||||
suffixHAR = ".har"
|
||||
)
|
||||
|
||||
type FromType int
|
||||
|
||||
const (
|
||||
FromTypeJSON FromType = iota
|
||||
FromTypeYAML
|
||||
FromTypeHAR
|
||||
FromTypePostman
|
||||
FromTypeCurl
|
||||
FromTypeSwagger
|
||||
FromTypePyest
|
||||
FromTypeGotest
|
||||
)
|
||||
|
||||
func (fromType FromType) String() string {
|
||||
switch fromType {
|
||||
case FromTypeYAML:
|
||||
return "yaml"
|
||||
case FromTypeHAR:
|
||||
return "har"
|
||||
case FromTypePostman:
|
||||
return "postman"
|
||||
case FromTypeSwagger:
|
||||
return "swagger"
|
||||
case FromTypeCurl:
|
||||
return "curl"
|
||||
case FromTypeGotest:
|
||||
return "gotest"
|
||||
case FromTypePyest:
|
||||
return "pytest"
|
||||
default:
|
||||
return "json"
|
||||
}
|
||||
}
|
||||
|
||||
func (fromType FromType) Extensions() []string {
|
||||
switch fromType {
|
||||
case FromTypeYAML:
|
||||
return []string{suffixYAML, ".yml"}
|
||||
case FromTypeHAR:
|
||||
return []string{suffixHAR}
|
||||
case FromTypePostman, FromTypeSwagger:
|
||||
return []string{suffixJSON}
|
||||
case FromTypeCurl:
|
||||
return []string{".txt", ".curl"}
|
||||
case FromTypeGotest:
|
||||
return []string{suffixGoTest}
|
||||
case FromTypePyest:
|
||||
return []string{suffixPyTest}
|
||||
default:
|
||||
return []string{suffixJSON}
|
||||
}
|
||||
}
|
||||
|
||||
type OutputType int
|
||||
|
||||
const (
|
||||
OutputTypeJSON OutputType = iota // default output type: JSON
|
||||
OutputTypeYAML
|
||||
OutputTypeGoTest
|
||||
OutputTypePyTest
|
||||
)
|
||||
|
||||
func (outputType OutputType) String() string {
|
||||
switch outputType {
|
||||
case OutputTypeYAML:
|
||||
return "yaml"
|
||||
case OutputTypeGoTest:
|
||||
return "gotest"
|
||||
case OutputTypePyTest:
|
||||
return "pytest"
|
||||
default:
|
||||
return "json"
|
||||
}
|
||||
}
|
||||
|
||||
// Profile is used to override or update(create if not existed) original headers and cookies
|
||||
type Profile struct {
|
||||
Override bool `json:"override" yaml:"override"`
|
||||
Headers map[string]string `json:"headers" yaml:"headers"`
|
||||
Cookies map[string]string `json:"cookies" yaml:"cookies"`
|
||||
}
|
||||
|
||||
func NewConverter(outputDir, profilePath string) *TCaseConverter {
|
||||
return &TCaseConverter{
|
||||
profilePath: profilePath,
|
||||
outputDir: outputDir,
|
||||
}
|
||||
}
|
||||
|
||||
// TCaseConverter holds the common properties of case converter
|
||||
type TCaseConverter struct {
|
||||
fromFile string
|
||||
profilePath string
|
||||
outputDir string
|
||||
tCase *hrp.TestCaseDef
|
||||
}
|
||||
|
||||
// LoadCase loads source file and convert to TCase type
|
||||
func (c *TCaseConverter) loadCase(casePath string, fromType FromType) error {
|
||||
c.fromFile = casePath
|
||||
var err error
|
||||
switch fromType {
|
||||
case FromTypeJSON:
|
||||
c.tCase, err = LoadJSONCase(casePath)
|
||||
case FromTypeYAML:
|
||||
c.tCase, err = LoadYAMLCase(casePath)
|
||||
case FromTypeHAR:
|
||||
c.tCase, err = LoadHARCase(casePath)
|
||||
case FromTypePostman:
|
||||
c.tCase, err = LoadPostmanCase(casePath)
|
||||
case FromTypeSwagger:
|
||||
c.tCase, err = LoadSwaggerCase(casePath)
|
||||
case FromTypeCurl:
|
||||
c.tCase, err = LoadCurlCase(casePath)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *TCaseConverter) Convert(casePath string, fromType FromType, outputType OutputType) (err error) {
|
||||
// report GA event
|
||||
startTime := time.Now()
|
||||
defer func() {
|
||||
sdk.SendGA4Event("hrp_convert", map[string]interface{}{
|
||||
"from": fromType.String(),
|
||||
"to": outputType.String(),
|
||||
"success": err == nil,
|
||||
"engagement_time_msec": time.Since(startTime).Milliseconds(),
|
||||
})
|
||||
}()
|
||||
|
||||
log.Info().Str("path", casePath).
|
||||
Str("fromType", fromType.String()).
|
||||
Str("outputType", outputType.String()).
|
||||
Msg("convert testcase")
|
||||
|
||||
// load source file
|
||||
err = c.loadCase(casePath, fromType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// override TCase with profile
|
||||
if c.profilePath != "" {
|
||||
c.overrideWithProfile(c.profilePath)
|
||||
}
|
||||
|
||||
// convert to target format
|
||||
var outputFile string
|
||||
switch outputType {
|
||||
case OutputTypeYAML:
|
||||
outputFile, err = c.toYAML()
|
||||
case OutputTypeGoTest:
|
||||
outputFile, err = c.toGoTest()
|
||||
case OutputTypePyTest:
|
||||
outputFile, err = c.toPyTest()
|
||||
default:
|
||||
outputFile, err = c.toJSON()
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Str("outputFile", outputFile).Msg("conversion completed")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *TCaseConverter) genOutputPath(suffix string) string {
|
||||
outFileFullName := builtin.GetFileNameWithoutExtension(c.fromFile) + "_test" + suffix
|
||||
if c.outputDir != "" {
|
||||
return filepath.Join(c.outputDir, outFileFullName)
|
||||
} else {
|
||||
return filepath.Join(filepath.Dir(c.fromFile), outFileFullName)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *TCaseConverter) overrideWithProfile(path string) error {
|
||||
log.Info().Str("path", path).Msg("load profile")
|
||||
profile := new(Profile)
|
||||
err := hrp.LoadFileObject(path, profile)
|
||||
if err != nil {
|
||||
log.Warn().Str("path", path).
|
||||
Msg("failed to load profile, ignore!")
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info().Interface("profile", profile).Msg("override with profile")
|
||||
for _, step := range c.tCase.Steps {
|
||||
// override original headers and cookies
|
||||
if profile.Override {
|
||||
step.Request.Headers = make(map[string]string)
|
||||
step.Request.Cookies = make(map[string]string)
|
||||
}
|
||||
// update (create if not existed) original headers and cookies
|
||||
if step.Request.Headers == nil {
|
||||
step.Request.Headers = make(map[string]string)
|
||||
}
|
||||
if step.Request.Cookies == nil {
|
||||
step.Request.Cookies = make(map[string]string)
|
||||
}
|
||||
for k, v := range profile.Headers {
|
||||
step.Request.Headers[k] = v
|
||||
}
|
||||
for k, v := range profile.Cookies {
|
||||
step.Request.Cookies[k] = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user