Unit Testing

Pada Go kita dapat melakukan unit test menggunakan built-in package yang sudah disediakan Go yaitu testing . Selain internal package, kita juga dapat menggunakan external package untuk proses unit testing pada Go. Salah satunya adalah testify.

Hello Testing

Kita akan mencoba membuat testing untuk mengecek apakah suatu fungsi mengembalikan sebuah string Hello, Go Testing . Pada file main.go kita akan membuat fungsi sayHello untuk mengembalikan string Hello, Go Testing dan memanggilnya pada fungsi main .

package main

import "fmt"

func sayHello() string {
	return "Hello, Go Testing"
}

func main() {
	fmt.Println(sayHello())
}

Untuk melakukan testing, pada Go ada beberapa rules yang perlu kita perhatikan:

  1. Kita harus membuat file baru dengan format nama file xxxx_test.go . Contoh main_test.go

  2. Nama pada fungsi testing harus berawalan Test . Contoh TestSayHello .

  3. Parameter pada fungsi testing hanya memiliki 1 parameter yaitu t *testing.T

  4. Untuk menggunakan *testing.T kita perlu melakukan import package testing

Sekarang mari kita membuat file yang digunakan untuk melakukan testing. Kita akan membuat file bernama main_test.go . Kita masih membuat dalam package yang sama yaitu pada package main . Lalu kita melakukan import package testing .

Nama fungsi untuk testing yang kita buat adalah TestSayHello . Statement di dalam fungsi ini berisi beberapa hal. Kita membuat variabel baru got yang berperan untuk menyimpan hasil dari fungsi yang ingin kita testing.

got := sayHello()

Lalu kita membuat 1 variabel baru want yang berperan untuk menyimpan suatu kondisi testing yang diharapkan.

want := "Hello, Go Testing"

Jadi dari sini kita bisa melakukan sebuah kondisi menggunakan if untuk mengecek apakah fungsu sayHello yang telah kita buat sesuai ekpektasi hasilnya. Jika tidak maka akan menampilkan error.

if got != want {
		t.Errorf("Got %s, but want %s", got, want)
	}

Kode lengkapnya dapat kamu lihat di bawah ini:

package main

import "testing"

func TestSayHello(t *testing.T) {
	got := sayHello()
	want := "Hello, Go Testing"

	t.Logf("Text: %s", want)

	if got != want {
		t.Errorf("Got %s, but want %s", got, want)
	}
}

Untuk menjalankan testing pada Go, kita menggunakan perintah berikut ini pada command line:

go test

atau jika kita ingin menjalankan spesifik file tertentu dan ingin menampilkan output secara lengkap dapat menggunakan perintah berikut ini:

go test main.go main_test.go -v

Argument -v atau verbose digunakan menampilkan semua output log pada saat pengujian.

Jika kita jalankan program diatas maka hasilnya akan seperti berikut ini:

Status testing diatas adalah PASS yang berarti lolos uji tes.

Kita akan membuat skenario jika hasil uji tes gagal yaitu dengan mengganti nilai dari variabel want

package main

import "testing"

func TestSayHello(t *testing.T) {
	got := sayHello()
	want := "Hello, world"

	t.Logf("Text: %s", want)

	if got != want {
		t.Errorf("Got %s, but want %s", got, want)
	}
}

Jika testing dilakukan kembali, maka akan terlihat seperti berikut ini:

Maka hasilnya akan FAIL karena hasil uji test gagal memenuhi kriteria.

Method Test

Kamu bisa melihat method lengkapnya yang dapat digunakan pada Go di tabel ini:

Method

Kegunaan

Log()

Menampilkan log

Logf()

Menampilkan log menggunakan format

Fail()

Menandakan terjadi Fail() dan proses testing fungsi tetap diteruskan

FailNow()

Menandakan terjadi Fail() dan proses testing fungsi dihentikan

Failed()

Menampilkan laporan fail

Error()

Log() diikuti dengan Fail()

Errorf()

Logf() diikuti dengan Fail()

Fatal()

Log() diikuti dengan failNow()

Fatalf()

Logf() diikuti dengan failNow()

Skip()

Log() diikuti dengan SkipNow()

Skipf()

Logf() diikuti dengan SkipNow()

SkipNow()

Menghentikan proses testing fungsi, dilanjutkan ke testing fungsi setelahnya

Skiped()

Menampilkan laporan skip

Parallel()

Menge-set bahwa eksekusi testing adalah parallel

Test Scenario

Kita akan membuat contoh lain dalam bentuk skenario. Anggaplah aplikasi Go kita ingin memiliki 2 fitur:

  1. Aplikasi menampilkan teks Hello, David dimana David adalah nama dari seseorang yang akan kita kirim melalui argumen fungsi.

  2. Jika saat memanggil fungsi tidak terdapat argumen nama seseorang, maka program harus menggantinya dengan teks friend .

Dari fitur di atas maka kita dapat membuat test case untuk 2 skenario tersebut.

Pertama, kita akan membuat test case terlebih dahulu pada file main_test.go :

package main

import "testing"

func TestSayHello(t *testing.T) {
	t.Run("saying hello to people", func(t *testing.T) {
		got := sayHello("David")
		want := "Hello, David"

		t.Logf("Text: %s", want)

		if got != want {
			t.Errorf("Got %s, but want %s", got, want)
		}
	})

	t.Run("say 'Hello, Friend' when an empty string is supplied", func(t *testing.T) {
		got := sayHello("")
		want := "Hello, friend"

		t.Logf("Text: %s", want)

		if got != want {
			t.Errorf("Got %s, but want %s", got, want)
		}
	})
}

Kita bisa lihat dari kode di atas untuk melakukan Subtest, dapat menggunakan method Run .

Lalu kita akan coba membuat program berdasarkan skenario tes di atas. Kita akan membuat program utama pada file main.go :

package main

import "fmt"

func sayHello(name string) string {
	if name == "" {
		return "Hello, friend"
	}
	return "Hello, " + name
}

func main() {
	fmt.Println("Go Testing")
}

Jika kita jalankan testing pada kode di atas maka akan menampilkan hasil berikut ini:

Benchmark

Saat kita membuat program atau fungsi, tentunya kita ingin memastikan program yang kita buat sudah memiliki performa yang baik. Kita dapat melakukan testing performa fungsi pada program Go dengan cara benchmarking.

Untuk melakukan Benchmark, pada Go ada beberapa rules yang perlu yaitu nama pada fungsi benchmark testing harus berawalan Benchmark . Contoh BenchmarkSayHello .

Kita akan membuat fungsi sederhana pada file main.go

package main

import (
	"fmt"
)

func Calculate(x int) (result int) {
	result = x + 2
	return result
}

func main() {
	fmt.Println("Hello Benchmark Testing")
}

Kita akan mengecek performa fungsi Calculate menggunakan benchmark testing. Selanjutnya kita akan membuat testing pada file main_test.go

package main

import (
    "testing"
)

func BenchmarkCalculate(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Calculate(2)
    }
}

Untuk menjalankan benchmark testing agak sedikit berbeda yaitu dengan menjalankan perintah berikut ini pada command line

go test -bench=.

Maka hasil yang kita dapatkan

Kita bisa melihat bahwa kita mengeksekusi fungsi Calculate sebanyak 1000,000,000 kali , pada kecepatan 0.3069 per operation, dan untuk keseluruhan pada kecepatan 1.462 detik untuk menjalankan fungsi tersebut.

Tentu saja nantinya makin kompleks sebuah fungsi maka akan mengalami peningkatan dari segi waktu. Dengan kita melakukan benchmark testing ini, kita akan lebih mengetahui bagaimana performa dari fungsi yang kita buat dan dapat meningkatkannya kembali.

Last updated