cut -f 3 -d, list.txt | awk '{print $1}' | myscript.sh | sort | uniq | gnuplot
swagger: '2.0' info: version: 0.1.0 title: Simple To Do List API securityDefinitions: key: type: apiKey in: header name: x-todolist-token security: - key: [] consumes: - application/io.swagger.examples.todo-list.v1+json produces: - application/io.swagger.examples.todo-list.v1+json schemes: - http - https x-schemes: - unix paths: /: get: tags: ["todos"] operationId: find parameters: - name: limit in: formData type: integer format: int32 required: true allowEmptyValue: true - name: "X-Rate-Limit" in: header type: integer format: int32 required: true - name: tags in: formData type: array collectionFormat: multi allowEmptyValue: true items: type: integer format: int32 required: true responses: '200': description: OK schema: type: array items: $ref: "#/definitions/item" default: description: error schema: $ref: "#/definitions/error" post: tags: ["todos"] operationId: addOne parameters: - name: body in: body schema: $ref: "#/definitions/item" responses: '201': description: Created schema: $ref: "#/definitions/item" default: description: error schema: $ref: "#/definitions/error" /{id}: parameters: - type: string name: id in: path required: true put: tags: ["todos"] operationId: updateOne parameters: - name: body in: body schema: $ref: "#/definitions/item" responses: '200': description: OK schema: $ref: "#/definitions/item" default: description: error schema: $ref: "#/definitions/error" delete: tags: ["todos"] operationId: destroyOne responses: '204': description: Deleted default: description: error schema: $ref: "#/definitions/error" definitions: item: type: object required: - description properties: id: type: integer format: int64 readOnly: true description: type: string minLength: 1 completed: type: boolean error: type: object required: - message properties: code: type: integer format: int64 message: type: string
--/---- main.go | +-- handler --+--- handler_middleware.go | +--- handler_todo.go | +--- handler_user.go | +--- handler_test.go
// handler 초기화 type Handler struct { DB *sql.DB Redis *redis.Client Logger *logging.Logger router *mux.Router // gorilla.mux } func (h *handler) Init() error { // DB, Redis, Logger 설정.. }
package handler import ( "net/http/httptest" "testing" "github.com/stretchr/testify/assert" ) var ( testServer string ) func Test_Init(t *testing.T) { /* handler := Handler{ Redis: redisCli, DB: mysqlCli, } */ handler.Init() server := httptest.NewServer(handlers.CombinedLoggingHandler(logfile, http.DefaultServeMux)) testServer = server.URL // ex. http://localhost:8193 } func Test_Todo(t *testing.T) { r, b, err := DoGet(testServer+"/todo/ping", Header, Body) assert.Nil(t, err) assert.Equal(t, http.StatusOK, res.StatusCode) json.Unmarshal(b, &response) assert.Equal(t, "pong", response.Text) }
func Test_Init(t *testing.T) { db, err := sql.Open("mysql", "root:gkwlak@tcp(semina:3306)/semina") if err != nil { panic(err) } _, err = db.Exec("DELETE FROM todo") if err != nil { panic(err) } _, err = db.Exec("DELETE FROM user") if err != nil { panic(err) } _, err = db.Exec("DELETE FROM job") if err != nil { panic(err) } _, err = db.Exec("DELETE FROM schedule") if err != nil { panic(err) }
testHeader = []map[string]string{ { "X-SERVICE-Name": "testService-01", "X-Service-Base-Version": "1.0", "X-Service-Version": "1.2", "X-TOKEN": "validtoken", "Content-Type": "text/plain", }, { "X-SERVICE-Name": "testService-01", "X-Service-Base-Version": "1.0", "X-Service-Version": "1.2", "X-TOKEN": "validtoken", "Content-Type": "text/plain", }, { "X-SERVICE-Name": "testService-01", "X-Service-Base-Version": "1.1", "X-Service-Version": "1.2", "X-TOKEN": "invalidtoken", "Content-Type": "application/json", }, { "X-SERVICE-Name": "testService-02", "X-Service-Base-Version": "1.1", "X-Service-Version": "1.3", "Content-Type": "application/json }, { "X-Service-Base-Version": "1.1", "X-Service-Version": "1.3", "Content-Type": "application/json },
package myauth type Handler struct { } func (h *Handler) Init() *mux.Router { h.router = mux.NewRouter() h.router.HandleFunc("/oauth2.0/token", h.TokenValidation).Methods("GET") h.router.HandleFunc("/user/agreement", h.TermsGet).Methods("GET") h.router.HandleFunc("/user/agreement", h.TermsUpdate).Methods("PUT") h.router.HandleFunc("/user/agreement", h.TermsDelete).Methods("DELETE") h.router.HandleFunc("/ping", h.Ping).Methods("GET") return h.router } func (h *Handler) TokenValidation(w http.ResponseWriter, r *http.Request) { token := r.Header.Get("Authorization") if len(token) < 10 { SendMessage(w, http.StatusNonAuthoritativeInfo, "FAIL") return } switch token { case "Bearer validToken-user01": profile := Profile{ ResponseEmail: "yundream@gmail.com", ResponseNickname: "yundream", ResponseName: "sangbae.yun", ResponseGender: "M", ResponseAge: "40", ResponseProfile_image: "http://www.example.com/test.png", ResponseId: "903890", ResponseBirthday: "19740208", } response := struct { ResultCode string `json:"resultcode"` Message string `json:"message"` Response Profile `json:"response"` }{"00", "success", profile} SendMessage(w, http.StatusOK, response) case "Bearer validToken-user02": profile := Profile{ ResponseEmail: "red3018@gmail.com", ResponseNickname: "red3018", ResponseName: "BoBs", ResponseGender: "M", ResponseAge: "42", ResponseProfile_image: "http://www.example.com/test.png", ResponseId: "18501287", ResponseBirthday: "19800512", } response := struct { ResultCode string `json:"resultcode"` Message string `json:"message"` Response Profile `json:"response"` }{"00", "success", profile} SendMessage(w, http.StatusOK, response) case "Bearer invalidToken": } response := struct { ResultCode string `json:"resultcode"` Message string `json:"message"` Response Profile `json:"response"` }{"80", "fail", profile} SendMessage(w, http.StatusOK, response) default: SendMessage(w, http.StatusNonAuthoritativeInfo, "FAIL") } }
--/---- main.go | +-- handler --+--- handler_middleware.go | | | +--- handler_todo.go | | | +--- handler_user.go | | | +--- handler_test.go | +-- myauth --+--- myauth.go
packate handler import "myauth" authHandler := myauth.Handler{} r := authHandler.Init() authServer := httptest.NewServer(handlers.CombinedLoggingHandler(logfile, r))
Copyrights © - Joinc, All Rights Reserved. Inherited From - Yundream Rebranded By - Joonphil
Contents
MSA환경에서의 Go 웹 애플리케이션 테스트 경험
소개
개발 환경
MSA
왜 ?
좋은 MSA 모델을 만들어보자.
API로 커뮤니케이션 하자
swagger
Swagger 문서 관리
문서로 부터 코드 생성
그냥 문서를 분리
REST API 테스트
테스트를 하는 이유
첫번째 안 : http client
두번째 안 : net/http/httptest
백엔드 연동 테스트
외부 API 서버
마무리
Recent Posts
Archive Posts
Tags