Golang 첫 Unit 테스트 #golang
Golang의 단위 테스트란?
철저히 조사한 느낌이라면, 다음과 같은 느낌으로 만들어 보면 좋을 것 같습니다.
(테스트 케이스를 실패시키고 싶을 때는 「testing.T.Error」나 「testing.T.Fatal」을 이용한다)
테스트 코드 기재
테스트 대상 코드
apichecker.gopackage main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"time"
)
func main() {
var endpoint = flag.String("endpoint", "", "check target Endpoint URL")
var lineToken = flag.String("token", "", "LINE notify token")
flag.Parse()
var apiResult = getAPI(*endpoint)
var result = postLINE(*lineToken, apiResult)
fmt.Printf("LINE Post result [%t]\n", result)
}
func getAPI(endpoint string) string {
if endpoint == "" {
log.Println("not endpoint")
return "not endpoint"
}
var result = ""
resp, err := http.Get(endpoint)
if err != nil {
result = fmt.Sprintf("NG\n%s", err)
} else {
defer resp.Body.Close()
expire := "-"
if len(resp.TLS.PeerCertificates) > 0 {
expireUTCTime := resp.TLS.PeerCertificates[0].NotAfter
expireJSTTime := expireUTCTime.In(time.FixedZone("Asia/Tokyo", 9*60*60))
expire = expireJSTTime.Format("06/01/02 15:04")
}
result = fmt.Sprintf("OK (expire=%s)\n%s", expire, endpoint)
}
return result
}
func postLINE(token string, message string) bool {
if token == "" {
log.Println("not token")
return false
} else if message == "" {
log.Println("not text")
return false
}
data := url.Values{"message": {message}}
r, _ := http.NewRequest("POST", "https://notify-api.line.me/api/notify", strings.NewReader(data.Encode()))
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
resp, err := http.DefaultClient.Do(r)
if err != nil {
log.Println(err)
return false
}
defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
return false
}
return true
}
getAPI 테스트 코드 작성
동일한 패키지이므로 private 함수도 테스트 할 수있어 편리합니다.
다음 패턴 테스트 케이스 준비
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"time"
)
func main() {
var endpoint = flag.String("endpoint", "", "check target Endpoint URL")
var lineToken = flag.String("token", "", "LINE notify token")
flag.Parse()
var apiResult = getAPI(*endpoint)
var result = postLINE(*lineToken, apiResult)
fmt.Printf("LINE Post result [%t]\n", result)
}
func getAPI(endpoint string) string {
if endpoint == "" {
log.Println("not endpoint")
return "not endpoint"
}
var result = ""
resp, err := http.Get(endpoint)
if err != nil {
result = fmt.Sprintf("NG\n%s", err)
} else {
defer resp.Body.Close()
expire := "-"
if len(resp.TLS.PeerCertificates) > 0 {
expireUTCTime := resp.TLS.PeerCertificates[0].NotAfter
expireJSTTime := expireUTCTime.In(time.FixedZone("Asia/Tokyo", 9*60*60))
expire = expireJSTTime.Format("06/01/02 15:04")
}
result = fmt.Sprintf("OK (expire=%s)\n%s", expire, endpoint)
}
return result
}
func postLINE(token string, message string) bool {
if token == "" {
log.Println("not token")
return false
} else if message == "" {
log.Println("not text")
return false
}
data := url.Values{"message": {message}}
r, _ := http.NewRequest("POST", "https://notify-api.line.me/api/notify", strings.NewReader(data.Encode()))
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
resp, err := http.DefaultClient.Do(r)
if err != nil {
log.Println(err)
return false
}
defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
return false
}
return true
}
apichecker_test.go
package main
import (
"regexp"
"testing"
)
func TestGetAPI_パラメーターエラー(t *testing.T) {
if getAPI("") != "not endpoint" {
t.Error("failed validation check")
}
}
func TestGetAPI_正常(t *testing.T) {
r := regexp.MustCompile("OK \\(expire=[0-9]{2}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2}\\)\nhttps://www.yahoo.co.jp")
if !r.MatchString(getAPI("https://www.yahoo.co.jp")) {
t.Error("function format error")
}
}
func TestGetAPI_証明書エラー(t *testing.T) {
r := regexp.MustCompile("NG\n.+")
if !r.MatchString(getAPI("https://www.yahoo.jp")) {
t.Error("function format error")
}
}
테스트 실행
$ go test .
ok github.com/ynozue/apichecker 0.684s
CI에도 적용
구성 파일에 테스트 실행 추가
travis.yamllanguage: go
install:
- go get -u golang.org/x/tools/cmd/goimports
- go get -u github.com/golang/lint/golint
script:
- go vet ./...
- diff <(goimports -d .) <(printf "")
- diff <(golint ./...) <(printf "")
- go test .
수정된 내용을 Git으로 Push
$ go vet ./...
The command "go vet ./..." exited with 0.
$ diff <(goimports -d .) <(printf "")
The command "diff <(goimports -d .) <(printf "")" exited with 0.
$ diff <(golint ./...) <(printf "")
The command "diff <(golint ./...) <(printf "")" exited with 0.
$ go test .
ok github.com/ynozue/apichecker 2.600s
The command "go test ." exited with 0.
Appendix
language: go
install:
- go get -u golang.org/x/tools/cmd/goimports
- go get -u github.com/golang/lint/golint
script:
- go vet ./...
- diff <(goimports -d .) <(printf "")
- diff <(golint ./...) <(printf "")
- go test .
$ go vet ./...
The command "go vet ./..." exited with 0.
$ diff <(goimports -d .) <(printf "")
The command "diff <(goimports -d .) <(printf "")" exited with 0.
$ diff <(golint ./...) <(printf "")
The command "diff <(golint ./...) <(printf "")" exited with 0.
$ go test .
ok github.com/ynozue/apichecker 2.600s
The command "go test ." exited with 0.
Reference
이 문제에 관하여(Golang 첫 Unit 테스트 #golang), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ynozue/items/0c25f5391d2e22121f86텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)