Test yang baik butuh lingkungan yang sama setiap kali dijalankan: berkas data tertentu, variabel dengan isi tertentu, atau folder kerja yang bersih. Jika kita menyalin-tempel kode persiapan itu ke dalam setiap test, satu perubahan kecil pada data uji harus diperbaiki di banyak tempat. Test fixture menyelesaikan masalah ini dengan memisahkan persiapan (setup) dan pembersihan (teardown) dari isi test itu sendiri. Chapter ini membahas konsep fixture, implementasinya di matlab.unittest, dan padanan manual yang dapat diuji di Octave:

  • Konsep setup sebelum test dan teardown sesudah test.
  • Empat blok fixture di matlab.unittest (TestMethodSetup hingga TestClassTeardown).
  • Jaminan state segar untuk setiap test.
  • Padanan manual portabel dengan try/catch dan onCleanup.

Konsep Fixture: Setup dan Teardown #

Fixture adalah kesepakatan tentang state bersama: setup menyiapkan keadaan awal sebelum test berjalan, teardown mengembalikan keadaan bersih setelah test selesai. Aturan praktisnya: apapun yang dibuat setup — berkas sementara, variabel global, koneksi data — harus dihapus atau ditutup oleh teardown, baik test lulus maupun gagal.

Mekanisme di balik layar: framework pengujian menjalankan setiap test di dalam “bingkai” setup → test → teardown. Jika test melempar galat, framework menangkap galat tersebut terlebih dahulu, menjalankan teardown, baru melaporkan kegagalan. Tanpa bingkai ini, test yang gagal di tengah proses akan meninggalkan berkas sementara yang menumpuk dan mengotori eksekusi berikutnya.

Fixture di matlab.unittest (MATLAB-ONLY) #

Framework matlab.unittest menyediakan empat blok terpisah untuk fixture. Verifikasi ke dokumentasi resmi R2026b menunjukkan nama blok yang benar adalah TestMethodSetup/TestMethodTeardown (per test) dan TestClassSetup/TestClassTeardown (per class) — bukan TestSetup/TestTeardown:

Blok methodsDijalankanKegunaan tipikal
(TestMethodSetup)sebelum setiap metode Testmembuat berkas/folder sementara per test
(TestMethodTeardown)sesudah setiap metode Testmenghapus berkas sementara
(TestClassSetup)sekali sebelum semua testmemuat data besar yang bersifat read-only
(TestClassTeardown)sekali sesudah semua testmenutup koneksi/figur bersama

Contoh berikut menguji fungsi yang membaca berkas CSV kecil. Setup membuat berkas sementara; teardown menghapusnya:

matlab
% Berkas: BerkasNilaiTest.m (MATLAB-ONLY, butuh matlab.unittest)
classdef BerkasNilaiTest < matlab.unittest.TestCase
    properties
        NamaFile
    end

    methods (TestMethodSetup)
        function buatBerkas(testCase)
            testCase.NamaFile = 'nilai_fixture.csv';
            fid = fopen(testCase.NamaFile, 'w');
            fprintf(fid, 'Budi,90\nSiti,85\nAni,88\n');
            fclose(fid);
            testCase.addTeardown(@() delete(testCase.NamaFile));
        end
    end

    methods (Test)
        function testJumlahBaris(testCase)
            fid = fopen(testCase.NamaFile, 'r');
            C = textscan(fid, '%s%d', 'Delimiter', ',');
            fclose(fid);
            testCase.verifyNumElements(C{2}, 3)
        end
    end
end

Mari kita bedah baris-baris kode di atas:

  1. Baris 3-5 (properties ... end): property NamaFile menjadi wadah state fixture; setiap test mengisinya lewat setup.
  2. Baris 7 (methods (TestMethodSetup)): semua fungsi di blok ini dijalankan framework sebelum setiap metode Test.
  3. Baris 9-12 (testCase.NamaFile ... fclose): setup menulis berkas CSV tiga baris yang dibutuhkan test.
  4. Baris 13 (addTeardown): testCase.addTeardown(@() delete(...)) menjadwalkan pembersihan; framework menjalankannya otomatis setelah test selesai, lulus maupun gagal — padanan pola cleanup terjadwal.
  5. Baris 17-22 (methods (Test) … verifyNumElements): test membaca berkas dan memverifikasi tiga baris nilai; test tidak perlu tahu bagaimana berkas dibuat.

Dua perilaku penting framework ini:

  • Instance segar per test. Test runner membuat instance TestCase yang baru untuk setiap metode Test. Variabel yang diisi setup pada test A tidak otomatis terlihat di test B — keduanya memperoleh instance (dan setup) sendiri. Perilaku ini menjaga test tetap terisolasi.
  • Fixture bersama lintas class. Atribut classdef SharedTestFixtures menerima cell array objek matlab.unittest.fixtures.Fixture — class fixture khusus dengan metode setup/teardown yang dipakai ulang antar test class bila isCompatible menganggap keadaannya sama. Untuk folder sementara per test, metode praktis createTemporaryFolder (sejak R2022a) menghapus foldernya secara otomatis saat test case selesai.

Padanan Manual yang Portabel #

Tanpa matlab.unittest, kita meniru bingkai setup → test → teardown dengan loop, try/catch, dan onCleanup. Berkas uji_fixture.m di bawah halaman ini memakai pola tersebut; berikut potongan intinya:

matlab
for k = 1:numel(daftarTest)
    % --- SETUP: state segar untuk setiap test (padanan TestMethodSetup) ---
    fixture = buatFixture();
    jumlahSetup = jumlahSetup + 1;

    try
        daftarTest{k}(fixture);
        fprintf('PASS: %s\n', daftarNama{k});
        jumlahLolos = jumlahLolos + 1;
    catch err
        % kegagalan dicatat, TEARDOWN di bawah tetap berjalan
        fprintf('FAIL: %s -> %s\n', daftarNama{k}, err.message);
    end

    % --- TEARDOWN: bersihkan state setiap test (padanan TestMethodTeardown) ---
    hapusFixture(fixture.namaFile);
    jumlahTeardown = jumlahTeardown + 1;
end

Output yang Dihasilkan (dari uji_fixture.m lengkap):

text
Menjalankan 4 test dengan fixture manual...
PASS: testBerkasAda
PASS: testTambahBaris
PASS: testIsiSegar
FAIL: testSengajaGagal -> total nilai tidak cocok: 263
Setup dijalankan   : 4 kali (1x per test)
Teardown dijalankan: 4 kali (1x per test)
Sisa berkas fixture: 0 (0 = semua bersih)
Ringkasan: 3/4 test lolos (1 FAIL memang disengaja)
Perhatikan: test-3 tetap melihat 3 baris walau test-2
menambah baris -> setup membuat state segar per test.
--- demo onCleanup (padanan addTeardown) ---
   [teardown onCleanup] berkas dihapus: sisa = 0
Galat ditangkap : galat sengaja di tengah test
Pembersihan sudah terjadi SEBELUM baris ini tercetak

Mari kita bedah baris-baris kode di atas:

  1. Baris 3 (fixture = buatFixture()): padanan TestMethodSetup — berkas data_fixture_uji.txt tiga baris dibuat ulang untuk setiap iterasi.
  2. Baris 6-13 (try ... catch err ... end): kegagalan assert ditangkap agar loop tidak berhenti; testSengajaGagal memang gagal untuk membuktikan teardown tetap berjalan.
  3. Baris 16 (hapusFixture(...)): padanan TestMethodTeardown — berada di luar try/catch sehingga selalu tereksekusi; hitungan teardown sama dengan hitungan setup (4 kali).
  4. Output testIsiSegar: test sebelumnya menambah satu baris, tetapi test ini masih melihat 3 baris — bukti state tidak bocor antar test karena setup membuat ulang fixture.
  5. Demo onCleanup: objek pembersih dibuat di dalam fungsi test; saat galat terlempar dan fungsi keluar, objek tersebut dihancurkan dan callback pembersihnya berjalan sebelum pemanggil menangkap galat — persis semantik addTeardown.

Ringkasan #

Fixture memisahkan persiapan dari isi test: TestMethodSetup menyiapkan state segar sebelum setiap test, TestMethodTeardown membersihkannya sesudahnya, dan addTeardown/onCleanup menjadwalkan pembersihan yang tetap berjalan saat test gagal. Framework membuat instance TestCase baru per test sehingga variabel setup tidak bocor antar test. Padanan manual — loop test + try/catch + pembersihan eksplisit — memberi jaminan yang sama tanpa matlab.unittest, seperti ditunjukkan uji_fixture.m.