lab8-unit test and CI
Tags: opensource
Published: 2020-11-28 04:50:58

## Overview

This week we practiced unit tests and continuous integration using Github action. This is the first time I write a unit test and with the help of go document and `go test`. I feel more confident to write the test first and then write the logic code.

## Set up testing framework

Go program language has a standard testing package built-in. It's easy to test and benchmark with the standard library. After I learn some basic concepts, I started my work with `git checkout -b testing`.

## My first test

```go
func Test_removeDuplicate(t *testing.T) {
	type args struct {
		urls []string
	}
	tests := []struct {
		name string
		args args
		want []string
	}{
		// TODO: Add test cases.
		{"name", args{[]string{"http://www.google.ca", "http://www.google.ca"}}, []string{"http://www.google.ca"}},
		{"name", args{[]string{"http://www.google.ca", "http://zyang.ca", "http://www.google.ca"}}, []string{"http://www.google.ca", "http://zyang.ca"}},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if got := removeDuplicate(tt.args.urls); !reflect.DeepEqual(got, tt.want) {
				t.Errorf("removeDuplicate() = %v, want %v", got, tt.want)
			}
		})
	}
}
```

It looks complicated, but to be honest, most of the code is generated by vscode.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/00ol27jmduog2w1vrd86.png)


## Mock the HTTP server

I spend a longer time searching for the right syntax to mocking in go. I found mocking a HTTP server is also built in the Go language. `"net/http/httptest"`

```go
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(404)
		w.Write([]byte("Not Found"))
	}))
	defer ts.Close()
	url := ts.UR
```

## run the test
we can run all the test
```
go test -v .
```
or we can just run one test file
```
go test filename
```

## test coverage

```
go test cover
```

## git rebase

I forgot to do the rebase in the testing branch. After commit to the master with all the commit history. Instead of `git rebase master -i`, I found the commit number from `git log` and did a rebase on the master branch. `git rebase 312ef0446a -i`

## Github action

Actually, I added the GitHub action a month ago. I already make some contributions to the CI/CD area. 

```yaml
name: Go

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:

  build:
    name: Build
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.13

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2

    - name: Build
      run: go build -v .

    - name: Test
      run: go test -v .

  lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.13

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2
    - run: go get -u golang.org/x/lint/golint
    - name: lint
      run: golint .
  fmt:
    name: Fmt
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.13

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2
    - name: fmt
      run: gofmt .
```

## Test Pull Request

To test the pull request and github action. I make this PR [https://github.com/yzwdroid/goURL/pull/12](https://github.com/yzwdroid/goURL/pull/12). All the tests passed, and I merged the PR to the master branch.

## Update contibuting.md

```markdown
## Tests

You are welcome to add tests to this project.

go test filename
// or 
go test .
Test coverage
go test -cover
```

## Add tests to another project

## integrate linter
```yaml
lint:
    name: Lint
    runs-on: ubuntu-latest
    steps:

    - name: Set up Go 1.x
      uses: actions/setup-go@v2
      with:
        go-version: ^1.13

    - name: Check out code into the Go module directory
      uses: actions/checkout@v2
    - run: go get -u golang.org/x/lint/golint
    - name: lint
      run: golint .
```

## Integrated test into VS Code

Install the `Go` plugin, generate the simple test as mentioned above.