diff --git a/doc/things_about_e2e_test.md b/doc/things_about_e2e_test.md new file mode 100644 index 0000000..d14a5d5 --- /dev/null +++ b/doc/things_about_e2e_test.md @@ -0,0 +1,19 @@ +# v2 版本的集成测试设计 + +## 回顾 v1 + +在 v1 版本中,我们选用了 [bats](https://github.com/sstephenson/bats) 这个框架来做集成测试。当时这么做有如下原因: + +1. bats 框架是基于 bash 的,在 case 里面调用命令贴合 goc 实际的使用方法,非常直观。 + +但是实际编写有如下难度: + +1. bats 中运行并行的任务时非常难受,同时运行的两个进程属于前后台关系,实测对 bats 的 case 有破坏性。 +2. 由于有双进程,又受限于 bash 的表达能力,实际 case 编写并不容易,其它维护者难以上手。 +3. 无法跨平台,或者跨平台叫麻烦。 + +## 思考 v2 + +v2 版本中要支持多平台,包括 Windows,基于这一点就可以否定继续使用 bats 了。 + +剩下就是 Python 或者 Go 的测试框架了。考虑到内部团队的技术栈,这里就选用了 ginkgo。 \ No newline at end of file diff --git a/tests/README.md b/tests/README.md index 532cd4c..93196cb 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1 +1,27 @@ -# How to run e2e test \ No newline at end of file +# How to run e2e test + +## 如何运行集成测试 + +``` +make e2e +``` + +## 如何添加 sample + +为了不让 case 之间执行时互相干扰,集测设计了 samples 管理系统。 + +在 `tests/e2e/samples` 目录中,按如下格式在 `meta.yaml` 中添加 sample 的元信息: + +```yaml +samples: + basic: + dir: basic-project + description: a basic project only print hello world + gomod: + dir: invalidmod-project + description: a project which contains invalid go.mod +``` + +其中 basic 是键值,dir 是目录名,description 你可以添加一些说明,让大家一目了然这个 sample 的特点。 + +然后就按照 `meta.yaml` 填写的信息在 samples 目录内添加相应的工程目录即可。 \ No newline at end of file diff --git a/tests/e2e/cmd.go b/tests/e2e/cmd.go index 2ade2f0..49590b3 100644 --- a/tests/e2e/cmd.go +++ b/tests/e2e/cmd.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "os" "os/exec" "time" ) @@ -18,10 +19,15 @@ type LongRunCmd struct { done bool } -func NewLongRunCmd(dir string, args []string) *LongRunCmd { +// NewLongRunCmd defines a command which will be run forever +// +// You can specify the whole command arg list, the directory where the command +// will be run in, and the env list. +func NewLongRunCmd(args []string, dir string, envs []string) *LongRunCmd { ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, args[0], args[1:]...) cmd.Dir = dir + cmd.Env = append(os.Environ(), envs...) var stderrBuf bytes.Buffer var stdoutBuf bytes.Buffer @@ -71,12 +77,13 @@ func (l *LongRunCmd) GetStdoutStdErr() (string, string) { } // RunShortRunCmd defines a cmd which run and exits immediately -func RunShortRunCmd(dir string, args []string) (string, error) { +func RunShortRunCmd(args []string, dir string, envs []string) (string, error) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) defer cancel() cmd := exec.CommandContext(ctx, args[0], args[1:]...) cmd.Dir = dir + cmd.Env = append(os.Environ(), envs...) output, err := cmd.CombinedOutput() return string(output), err diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index db9108f..522d493 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -20,7 +20,7 @@ var _ = Describe("1 [基础测试]", func() { Expect(err).To(BeNil(), "找不到 sample") By("使用 goc build 命令编译") - _, err = RunShortRunCmd(dir, []string{"goc", "build", "."}) + _, err = RunShortRunCmd([]string{"goc", "build", "."}, dir, nil) Expect(err).To(BeNil(), "goc build 运行错误") }) }) @@ -31,12 +31,12 @@ var _ = Describe("1 [基础测试]", func() { Expect(err).To(BeNil(), "找不到 sample") By("启动 goc server") - lc := NewLongRunCmd(dir, []string{"goc", "server", "."}) + lc := NewLongRunCmd([]string{"goc", "server", "."}, dir, nil) lc.Run() defer lc.Stop() By("使用 goc list 获取服务列表") - output, err := RunShortRunCmd(dir, []string{"goc", "list"}) + output, err := RunShortRunCmd([]string{"goc", "list"}, dir, nil) Expect(err).To(BeNil(), "goc list 运行错误") Expect(output).To(ContainSubstring("REMOTEIP"), "goc list 输出应该包含 REMOTEIP") })