diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 83e6aa11..a9a7b702 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -6,6 +6,7 @@ **go version** +- fix #1308: load `.env` file as environment variables - fix #1309: locate plugin file upward recursively until system root dir ## v4.1.0-beta (2022-05-21) diff --git a/examples/demo-with-go-plugin/proj.json b/examples/demo-with-go-plugin/proj.json new file mode 100644 index 00000000..b8ac381a --- /dev/null +++ b/examples/demo-with-go-plugin/proj.json @@ -0,0 +1,6 @@ +{ + "project_name": "demo-with-go-plugin", + "project_path": "/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner/examples/demo-with-go-plugin", + "create_time": "2022-05-24T11:10:10.127839+08:00", + "hrp_version": "v4.1.0-beta" +} \ No newline at end of file diff --git a/examples/demo-with-go-plugin/testcases/requests.json b/examples/demo-with-go-plugin/testcases/requests.json index b13f3837..9b4214d7 100644 --- a/examples/demo-with-go-plugin/testcases/requests.json +++ b/examples/demo-with-go-plugin/testcases/requests.json @@ -17,7 +17,7 @@ { "name": "get with params", "variables": { - "foo1": "bar11", + "foo1": "${ENV(USERNAME)}", "foo2": "bar21", "sum_v": "${sum_two_int(1, 2)}" }, @@ -46,7 +46,7 @@ { "eq": [ "body.args.foo1", - "bar11" + "debugtalk" ] }, { diff --git a/examples/demo-with-go-plugin/testcases/requests.yml b/examples/demo-with-go-plugin/testcases/requests.yml index 86d1b9cc..5ed53dd8 100644 --- a/examples/demo-with-go-plugin/testcases/requests.yml +++ b/examples/demo-with-go-plugin/testcases/requests.yml @@ -13,7 +13,7 @@ teststeps: - name: get with params variables: - foo1: bar11 + foo1: ${ENV(USERNAME)} foo2: bar21 sum_v: "${sum_two_int(1, 2)}" request: @@ -29,7 +29,7 @@ teststeps: foo3: "body.args.foo2" validate: - eq: ["status_code", 200] - - eq: ["body.args.foo1", "bar11"] + - eq: ["body.args.foo1", "debugtalk"] - eq: ["body.args.sum_v", "3"] - eq: ["body.args.foo2", "bar21"] - diff --git a/examples/demo-with-py-plugin/proj.json b/examples/demo-with-py-plugin/proj.json new file mode 100644 index 00000000..fd0b8628 --- /dev/null +++ b/examples/demo-with-py-plugin/proj.json @@ -0,0 +1,6 @@ +{ + "project_name": "demo-with-py-plugin", + "project_path": "/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner/examples/demo-with-py-plugin", + "create_time": "2022-05-24T11:10:15.544763+08:00", + "hrp_version": "v4.1.0-beta" +} \ No newline at end of file diff --git a/examples/demo-with-py-plugin/testcases/requests.json b/examples/demo-with-py-plugin/testcases/requests.json index b13f3837..9b4214d7 100644 --- a/examples/demo-with-py-plugin/testcases/requests.json +++ b/examples/demo-with-py-plugin/testcases/requests.json @@ -17,7 +17,7 @@ { "name": "get with params", "variables": { - "foo1": "bar11", + "foo1": "${ENV(USERNAME)}", "foo2": "bar21", "sum_v": "${sum_two_int(1, 2)}" }, @@ -46,7 +46,7 @@ { "eq": [ "body.args.foo1", - "bar11" + "debugtalk" ] }, { diff --git a/examples/demo-with-py-plugin/testcases/requests.yml b/examples/demo-with-py-plugin/testcases/requests.yml index 86d1b9cc..5ed53dd8 100644 --- a/examples/demo-with-py-plugin/testcases/requests.yml +++ b/examples/demo-with-py-plugin/testcases/requests.yml @@ -13,7 +13,7 @@ teststeps: - name: get with params variables: - foo1: bar11 + foo1: ${ENV(USERNAME)} foo2: bar21 sum_v: "${sum_two_int(1, 2)}" request: @@ -29,7 +29,7 @@ teststeps: foo3: "body.args.foo2" validate: - eq: ["status_code", 200] - - eq: ["body.args.foo1", "bar11"] + - eq: ["body.args.foo1", "debugtalk"] - eq: ["body.args.sum_v", "3"] - eq: ["body.args.foo2", "bar21"] - diff --git a/examples/demo-without-plugin/proj.json b/examples/demo-without-plugin/proj.json new file mode 100644 index 00000000..c6eef7d9 --- /dev/null +++ b/examples/demo-without-plugin/proj.json @@ -0,0 +1,6 @@ +{ + "project_name": "demo-without-plugin", + "project_path": "/Users/debugtalk/MyProjects/HttpRunner-dev/httprunner/examples/demo-without-plugin", + "create_time": "2022-05-24T11:10:16.993462+08:00", + "hrp_version": "v4.1.0-beta" +} \ No newline at end of file diff --git a/hrp/config.go b/hrp/config.go index af903bc5..76912aa7 100644 --- a/hrp/config.go +++ b/hrp/config.go @@ -10,6 +10,7 @@ import ( func NewConfig(name string) *TConfig { return &TConfig{ Name: name, + Env: make(map[string]string), Variables: make(map[string]interface{}), } } @@ -21,6 +22,7 @@ type TConfig struct { Verify bool `json:"verify,omitempty" yaml:"verify,omitempty"` BaseURL string `json:"base_url,omitempty" yaml:"base_url,omitempty"` Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` + Env map[string]string `json:"env,omitempty" yaml:"env,omitempty"` Variables map[string]interface{} `json:"variables,omitempty" yaml:"variables,omitempty"` Parameters map[string]interface{} `json:"parameters,omitempty" yaml:"parameters,omitempty"` ParametersSetting *TParamsConfig `json:"parameters_setting,omitempty" yaml:"parameters_setting,omitempty"` diff --git a/hrp/internal/builtin/utils.go b/hrp/internal/builtin/utils.go index cacad024..8bdc661d 100644 --- a/hrp/internal/builtin/utils.go +++ b/hrp/internal/builtin/utils.go @@ -294,12 +294,45 @@ func LoadFile(path string, structObj interface{}) (err error) { err = decoder.Decode(structObj) case ".yaml", ".yml": err = yaml.Unmarshal(file, structObj) + case ".env": + err = parseEnvContent(file, structObj) default: err = ErrUnsupportedFileExt } 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) + } + 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) diff --git a/hrp/internal/scaffold/main.go b/hrp/internal/scaffold/main.go index a0fe5efa..3392d960 100644 --- a/hrp/internal/scaffold/main.go +++ b/hrp/internal/scaffold/main.go @@ -104,7 +104,7 @@ func CreateScaffold(projectName string, pluginType PluginType, force bool) error } projectInfo := &ProjectInfo{ - ProjectName: projectName, + ProjectName: filepath.Base(projectName), ProjectPath: projectPath, CreateTime: time.Now(), Version: version.VERSION, diff --git a/hrp/internal/scaffold/templates/testcases/demo_requests.json b/hrp/internal/scaffold/templates/testcases/demo_requests.json index b13f3837..9b4214d7 100644 --- a/hrp/internal/scaffold/templates/testcases/demo_requests.json +++ b/hrp/internal/scaffold/templates/testcases/demo_requests.json @@ -17,7 +17,7 @@ { "name": "get with params", "variables": { - "foo1": "bar11", + "foo1": "${ENV(USERNAME)}", "foo2": "bar21", "sum_v": "${sum_two_int(1, 2)}" }, @@ -46,7 +46,7 @@ { "eq": [ "body.args.foo1", - "bar11" + "debugtalk" ] }, { diff --git a/hrp/internal/scaffold/templates/testcases/demo_requests.yml b/hrp/internal/scaffold/templates/testcases/demo_requests.yml index 86d1b9cc..5ed53dd8 100644 --- a/hrp/internal/scaffold/templates/testcases/demo_requests.yml +++ b/hrp/internal/scaffold/templates/testcases/demo_requests.yml @@ -13,7 +13,7 @@ teststeps: - name: get with params variables: - foo1: bar11 + foo1: ${ENV(USERNAME)} foo2: bar21 sum_v: "${sum_two_int(1, 2)}" request: @@ -29,7 +29,7 @@ teststeps: foo3: "body.args.foo2" validate: - eq: ["status_code", 200] - - eq: ["body.args.foo1", "bar11"] + - eq: ["body.args.foo1", "debugtalk"] - eq: ["body.args.sum_v", "3"] - eq: ["body.args.foo2", "bar21"] - diff --git a/hrp/testcase.go b/hrp/testcase.go index 2a4e589c..0aa548ec 100644 --- a/hrp/testcase.go +++ b/hrp/testcase.go @@ -80,6 +80,16 @@ func (path *TestCasePath) ToTestCase() (*TestCase, error) { return nil, errors.Wrap(err, "failed to get project root dir") } + // load .env file + dotEnvPath := filepath.Join(projectRootDir, ".env") + if builtin.IsFilePathExists(dotEnvPath) { + testCase.Config.Env = make(map[string]string) + err = builtin.LoadFile(dotEnvPath, testCase.Config.Env) + if err != nil { + return nil, errors.Wrap(err, "failed to load .env file") + } + } + for _, step := range tc.TestSteps { if step.API != nil { apiPath, ok := step.API.(string)