Melakukan integration test untuk API setidaknya kita harus bisa menjalankan aplikasi-nya terlebih dahulu agar bisa dilakukan pengetesan secara terintegrasi.
Hal ini perlu kita siapkan beberapa case, test case yang mencakup kebutuhan dari integration Test tersebut. Misalkan dari API Endpoint
kita yang sudah dikerjakan itu memiliki resource database
, cache
ataupun eksternal lain yang berhubungan dengan keberlangsungannya suatu API Endpoint tersebut.
Maka, kita akan simulasikan bagaimana cara melakukan integration test API. Tahapan yang pertama yaitu kita buat API Service yang mana API tersebut digunakan untuk operasi penjumlahan angka.
Membuat Program API
Berikut program API Endpoint yang akan diuji atau dibuat integration test-nya.
package main
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
)
func main() {
http.HandleFunc("/add", HandleAddInts)
address := ":9000"
fmt.Printf("Memulai server at %s\n", address)
fmt.Println()
fmt.Println("contoh query: /add?a=2&b=2&authtoken=abcdef123")
fmt.Println("tokennya adalah 'abcdef123'")
err := http.ListenAndServe(address, nil)
if err != nil {
fmt.Printf("error ketika start server: %v", err)
}
}
type TambahResponse struct {
Result int `json:"result"`
}
func HandleAddInts(w http.ResponseWriter, r *http.Request) {
params := r.URL.Query()
paramA := params.Get("a")
paramB := params.Get("b")
token := params.Get("authtoken")
if paramA == "" || paramB == "" || token == "" {
http.Error(w, "tidak ada parameters", http.StatusBadRequest)
return
}
if token != "abcdef123" {
http.Error(w, "token tidak valid", http.StatusUnauthorized)
return
}
intA, err := strconv.Atoi(paramA)
if err != nil {
http.Error(w, "parameter 'a' harus integer", http.StatusBadRequest)
return
}
intB, err := strconv.Atoi(paramB)
if err != nil {
http.Error(w, "parameter 'b' harus integer", http.StatusBadRequest)
return
}
response := TambahResponse{
Result: intA + intB,
}
json, err := json.MarshalIndent(&response, "", " ")
if err != nil {
http.Error(w, "error while marshalling", http.StatusInternalServerError)
return
}
fmt.Fprint(w, string(json))
}
Di dalam program ini ada beberapa validasi jika saat program dijalankan, yaitu * Parameter yg diinput wajib integer
- Tidak mengisi parameter
a
danb
maka akan menjadi - Mengujian jika tidak mengirimkan
authToken
Setelah program diatas selesai maka kita jalankan dengan perintah
➜ integration-test git:(main) ✗ go run app/main.go
Memulai server at :9000
contoh query: /add?a=2&b=2&authtoken=abcdef123
tokennya adalah 'abcdef123'
Jika program sudah sukses berjalan maka akan terlihat atau bisa diakses menggunakan postman dan curl
dengan endpoint dan port :9000
.
➜ materi curl 'http://localhost:9000/add?a=2&b=2&authtoken=abcdef123'
{
"result": 4
}%
Jika program berhasil seperti diatas maka, kita sudah menjalankan program API untuk menambah angka menggunakan protokol http
.
Membuat Test Integration
Selanjutnya, kita kan membuat test integration API yg tadi sudah kita buat itu dengan beberapa case yang sudah disebutkan diatas.
Siapkan program atau file main.go
untuk membuat API Testing.
package integrationtest
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type MathClient struct {
Token string
Host string
}
type AddResult struct {
Result int `json:"result"`
}
func (c *MathClient) APISum(i, j int) (int, error) {
query := fmt.Sprintf("http://%s/add?a=%v&b=%v&authtoken=%v", c.Host, i, j, c.Token)
response, err := http.Get(query)
if err != nil {
return 0, err
}
defer response.Body.Close()
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return 0, err
}
a := AddResult{}
err = json.Unmarshal(data, &a)
if err != nil {
return 0, err
}
return a.Result, nil
}
Method APISum
ini akan kita gunakan untuk mengakses http
API yang sudah kita buat sebagai main server yang akan kita test menggunakan integration test ini.
Membuat Struct Client
Buat struct untuk struktur API dan responsenya seperti ini.
type MathClient struct {
Token string
Host string
}
type AddResult struct {
Result int `json:"result"`
}
Membuat Method Akses API Sum
lalu kita akan buat method untuk ambil data penjumlahan API.
func (c *MathClient) APISum(i, j string) (int, int, error) {
query := fmt.Sprintf("http://%s/add?a=%s&b=%s&authtoken=%v", c.Host, i, j, c.Token)
var statusCode int = http.StatusBadRequest
response, err := http.Get(query)
if err != nil {
return 0, statusCode, err
}
defer response.Body.Close()
statusCode = response.StatusCode
data, err := ioutil.ReadAll(response.Body)
if err != nil {
return 0, statusCode, err
}
a := AddResult{}
err = json.Unmarshal(data, &a)
if err != nil {
return 0, statusCode, err
}
return a.Result, statusCode, nil
}
Membuat Unit Test yang dijadikan Integration Test
Selanjutnya, kita akan membuat API Integration testing ini di method yang ini. Bisa kita buat program seperti ini atau generate
saja pada method APISum
.
func TestMathClient_APISum(t *testing.T) {
type fields struct {
Token string
Host string
}
type args struct {
i string
j string
}
tests := []struct {
name string
fields fields
args args
want int
wantErr bool
wantCode int
}{
// testing test case
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &MathClient{
Token: tt.fields.Token,
Host: tt.fields.Host,
}
got, gotCode, err := c.APISum(tt.args.i, tt.args.j)
if (err != nil) != tt.wantErr {
t.Errorf("MathClient.APISum() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("MathClient.APISum() = %v, want %v", gotCode, tt.wantCode)
}
if gotCode != tt.wantCode {
t.Errorf("MathClient.APISum() = %v, want %v", gotCode, tt.wantCode)
}
})
}
}
Tambahkan Test Case
Lalu agar kita bisa melakukan pengujian case by case
kita perlu isi berapa tesitng case pada kurung kurawal diatas dengan isi seperti ini.
{
name: "case sukses jumlah data",
fields: fields{
Token: "abcdef123",
Host: "localhost:9000",
},
args: args{
i: "2",
j: "2",
},
want: 4,
wantErr: false,
wantCode: http.StatusOK,
},
{
name: "token tidak diset",
fields: fields{
Token: "abc",
Host: "localhost:9000",
},
args: args{
i: "2",
j: "2",
},
want: 0,
wantErr: true,
wantCode: http.StatusUnauthorized,
},
{
name: "host tidak sesuai",
fields: fields{
Token: "abcdef123",
Host: "localhost:500",
},
args: args{
i: "2",
j: "2",
},
want: 0,
wantErr: true,
wantCode: http.StatusBadRequest,
},
{
name: "case parameter kosong",
fields: fields{
Token: "abcdef123",
Host: "localhost:9000",
},
args: args{
i: "",
j: "",
},
want: 0,
wantErr: true,
wantCode: http.StatusBadRequest,
},
{
name: "case parameter bukan integer",
fields: fields{
Token: "abcdef123",
Host: "localhost:9000",
},
args: args{
i: "a",
j: "a",
},
want: 0,
wantErr: true,
wantCode: http.StatusBadRequest,
},
Jalankan Integration Test
Semua sudah selesai untuk pengujian dan pembuatan testing jangan lupa karena ini adalah code integration test
maka kita perlu ada penambahan agar saat melakukan go test -v
bisa kita tambahkan code diatas seperti ini.
//go:build integration
Kita lanjut dengan menjalankan go test dengan parameter integration
$ go test -v -tags=integration
Pastikan juga program API Endpoint berjalan dengan
➜ integration-test git:(main) ✗ go run app/main.go
Memulai server at :9000
contoh query: /add?a=2&b=2&authtoken=abcdef123
tokennya adalah 'abcdef123'