Table of Contents

10 – Unit Test

Pengenalan

Unit testing adalah pekerjaan yang tidak boleh dilewatkan kala mengembangkan sebuah software.

Pasalnya, pekerjaan ini sangat penting untuk memastikan kualitas komponen-komponen yang ada.

Biasanya, unit testing dilakukan oleh seorang software developer atau software tester.

Persiapan

Pertama siapkan terlebih dahulu sebuah struct Kubus. Variabel object hasil struct ini nantinya kita gunakan sebagai bahan testing.

				
					package main

import "math"

type Kubus struct {
	Sisi float64
}

func (k Kubus) Volume() float64 {
	return math.Pow(k.Sisi, 3)
}

func (k Kubus) Luas() float64 {
	return math.Pow(k.Sisi, 2) * 6
}

func (k Kubus) Keliling() float64 {
	return k.Sisi * 12
}

				
			
Testing

File untuk keperluan testing dipisah dengan file utama, namanya harus berakhiran _test.go, dan package-nya harus sama. Pada chapter ini, file utama adalah bab55.go, maka file testing harus bernama bab55_test.go.

Unit test di Go dituliskan dalam bentuk fungsi, yang memiliki parameter yang bertipe *testing.T, dengan nama fungsi harus diawali kata Test (pastikan sudah meng-import package testing sebelumnya). Lewat parameter tersebut, kita bisa mengakses method-method untuk keperluan testing.

Pada contoh di bawah ini disiapkan 3 buah fungsi test, yang masing-masing digunakan untuk mengecek apakah hasil kalkulasi volume, luas, dan keliling kubus adalah benar.

				
					package main

import "testing"

var (
    kubus              Kubus   = Kubus{4}
    volumeSeharusnya   float64 = 64
    luasSeharusnya     float64 = 96
    kelilingSeharusnya float64 = 48
)

func TestHitungVolume(t *testing.T) {
    t.Logf("Volume : %.2f", kubus.Volume())

    if kubus.Volume() != volumeSeharusnya {
        t.Errorf("SALAH! harusnya %.2f", volumeSeharusnya)
    }
}

func TestHitungLuas(t *testing.T) {
    t.Logf("Luas : %.2f", kubus.Luas())

    if kubus.Luas() != luasSeharusnya {
        t.Errorf("SALAH! harusnya %.2f", luasSeharusnya)
    }
}

func TestHitungKeliling(t *testing.T) {
    t.Logf("Keliling : %.2f", kubus.Keliling())

    if kubus.Keliling() != kelilingSeharusnya {
        t.Errorf("SALAH! harusnya %.2f", kelilingSeharusnya)
    }
}
				
			

Method t.Logf() digunakan untuk memunculkan log. Method ini equivalen dengan fmt.Printf().

Method Errorf() digunakan untuk memunculkan log dengan diikuti keterangan bahwa terjadi fail pada saat testing.

Cara eksekusi testing adalah menggunakan command go test. Karena struct yang diuji berada dalam file kubus.go, maka pada saat eksekusi test menggunakan go test, nama file kubus_test.go dan kubus.go perlu dituliskan sebagai argument.

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

Jalankan aplikasi seperti gambar di bawah ini, terlihat bahwa tidak ada test yang fail.

				
					func (k Kubus) Keliling() float64 {
    return k.Sisi * 15
}
				
			

Setelah itu jalankan lagi test.

Method Test

Table berikut berisikan method standar testing yang bisa digunakan di Go.

MethodKegunaan
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
Benchmark

Package testing selain berisikan tools untuk testing juga berisikan tools untuk benchmarking. Cara pembuatan benchmark sendiri cukup mudah yaitu dengan membuat fungsi yang namanya diawali dengan Benchmark dan parameternya bertipe *testing.B.

Sebagai contoh, kita akan mengetes performa perhitungan luas kubus. Siapkan fungsi dengan nama BenchmarkHitungLuas() dengan isi adalah kode berikut.

				
					func BenchmarkHitungLuas(b *testing.B) {
    for i := 0; i < b.N; i++ {
        kubus.Luas()
    }
}
				
			

Jalankan test menggunakan argument -bench=., argumen ini digunakan untuk menandai bahwa selain testing terdapat juga benchmark yang perlu diuji.

				
					go test -bench=.
				
			

Arti dari 28549812 51.1 ns/op adalah, fungsi di atas di-test sebanyak 28.549.812  kali, hasilnya membutuhkan waktu rata-rata 51.1 nano detik untuk run satu fungsi.

Testing Menggunakan testify

Package testify berisikan banyak sekali tools yang bisa dimanfaatkan untuk keperluan testing di Go.

Testify bisa di-download pada github.com/stretchr/testify menggunakan go get.

Di dalam testify terdapat 5 package dengan kegunaan berbeda-beda satu dengan lainnya. Detailnya bisa dilihat pada tabel berikut.

PackageKegunaan
assertBerisikan tools standar untuk testing
httpBerisikan tools untuk keperluan testing http
mockBerisikan tools untuk mocking object
requireSama seperti assert, hanya saja jika terjadi fail pada saat test akan menghentikan eksekusi program
suiteBerisikan tools testing yang berhubungan dengan struct dan method

Pada chapter ini akan kita contohkan bagaimana penggunaan package assert. Silakan perhatikan contoh berikut. Ubah isi kubus_test.go

				
					package main

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

var (
	kubus              Kubus   = Kubus{4}
	volumeSeharusnya   float64 = 64
	luasSeharusnya     float64 = 96
	kelilingSeharusnya float64 = 48
)

func TestHitungVolume(t *testing.T) {
	assert.Equal(t, kubus.Volume(), volumeSeharusnya, "perhitungan volume salah")
}

func TestHitungLuas(t *testing.T) {
	assert.Equal(t, kubus.Luas(), luasSeharusnya, "perhitungan luas salah")
}

func TestHitungKeliling(t *testing.T) {
	assert.Equal(t, kubus.Keliling(), kelilingSeharusnya, "perhitungan keliling salah")
}

				
			

Fungsi assert.Equal() digunakan untuk uji perbandingan. Parameter ke-2 dibandingkan nilainya dengan parameter ke-3. Jika tidak sama, maka pesan parameter ke-3 akan dimunculkan.