Panduan: Membuat dan menjalankan pengujian unit untuk kode terkelola
Artikel ini memandu Anda membuat, menjalankan, dan menyesuaikan serangkaian pengujian unit menggunakan kerangka kerja pengujian unit Microsoft untuk kode terkendali dan Test Explorer Visual Studio. Anda mulai dengan proyek C# yang sedang dalam pengembangan, membuat pengujian yang menjalankan kodenya, menjalankan pengujian, dan memeriksa hasilnya. Lalu Anda mengubah kode proyek dan menjalankan ulang pengujian. Jika Anda ingin ringkasan konseptual tugas-tugas ini sebelum melalui langkah-langkah ini, lihat Dasar-dasar pengujian unit. Jika Anda ingin membuat pengujian secara otomatis dari kode yang ada, lihat Membuat stub metode pengujian unit dari kode.
Membuat proyek untuk diuji
Buka Visual Studio.
Dari jendela awal, pilih Buat proyek baru.
Cari dan pilih templat proyek Aplikasi Konsol C# untuk .NET, lalu klik Berikutnya.
Catatan
Jika tidak melihat templat Aplikasi Konsol, Anda dapat menginstalnya dari jendela Buat proyek baru. Di pesan Tidak menemukan apa yang Anda cari?, pilih link Instal alat dan fitur lain. Kemudian, di Alat Penginstal Visual Studio, pilih beban kerja Pengembangan desktop .NET.
Beri nama proyek Bank, lalu klik Berikutnya.
Pilih kerangka kerja target yang direkomendasikan atau .NET 8, lalu pilih Buat.
Proyek Bank dibuat dan ditampilkan dalam Penjelajah Solusi dengan file Program.cs terbuka di editor kode.
Catatan
Jika Program.cs tidak terbuka di editor, klik dua kali file Program.cs di Penjelajah Solusi untuk membukanya.
Ganti isi Program.cs dengan kode C# berikut yang menentukan kelas, BankAccount:
using System; namespace BankAccountNS { /// <summary> /// Bank account demo class. /// </summary> public class BankAccount { private readonly string m_customerName; private double m_balance; private BankAccount() { } public BankAccount(string customerName, double balance) { m_customerName = customerName; m_balance = balance; } public string CustomerName { get { return m_customerName; } } public double Balance { get { return m_balance; } } public void Debit(double amount) { if (amount > m_balance) { throw new ArgumentOutOfRangeException("amount"); } if (amount < 0) { throw new ArgumentOutOfRangeException("amount"); } m_balance += amount; // intentionally incorrect code } public void Credit(double amount) { if (amount < 0) { throw new ArgumentOutOfRangeException("amount"); } m_balance += amount; } public static void Main() { BankAccount ba = new BankAccount("Mr. Bryan Walton", 11.99); ba.Credit(5.77); ba.Debit(11.22); Console.WriteLine("Current balance is ${0}", ba.Balance); } } }
Ubah nama file menjadi BankAccount.cs dengan mengeklik kanan dan memilih Ubah Nama di Penjelajah Solusi.
Pada menu Build, klik Build Solusi (atau tekan Ctrl + SHIFT + B).
Anda sekarang memiliki proyek dengan metode yang dapat Anda uji. Dalam artikel ini, pengujian berfokus pada metode Debit
. Metode Debit
dipanggil saat uang ditarik dari akun.
Membuat proyek pengujian unit
Pada menu File, pilih Tambahkan>Proyek Baru.
Tip
Anda juga dapat mengeklik kanan solusi di Penjelajah Solusi dan memilih Tambahkan>Proyek Baru.
Ketik pengujian di kotak pencarian, pilih C# sebagai bahasa, lalu pilih C# MSTest Unit Test Project untuk templat .NET, lalu klik Berikutnya.
Catatan
Di Visual Studio 2019 versi 16.9, templat proyek MSTest adalah Proyek Uji Unit.
Beri nama proyek BankTests dan klik Berikutnya.
Pilih kerangka kerja target yang direkomendasikan atau .NET 8, lalu pilih Buat.
Proyek BankTests ditambahkan ke solusi Bank.
Dalam proyek BankTests, tambahkan referensi ke proyek Bank.
Di Penjelajah Solusi, pilih Dependensi di bawah proyek BankTests lalu pilih Tambahkan Referensi (atau Tambahkan Referensi Proyek) dari menu klik kanan.
Di kotak dialog Pengelola Referensi, luaskan Proyek, pilih Solusi, lalu centang item Bank.
Pilih OK.
Membuat kelas pengujian
Buat kelas pengujian untuk memverifikasi kelas BankAccount
. Anda dapat menggunakan file UnitTest1.cs yang dihasilkan oleh templat proyek, tetapi beri nama file dan kelas yang lebih deskriptif.
Mengubah nama file dan kelas
Untuk mengubah nama file, di Penjelajah Solusi, pilih file UnitTest1.cs di proyek BankTests. Dari menu klik kanan, pilih Ubah nama (atau tekan F2), lalu ubah nama file menjadi BankAccountTests.cs.
Untuk mengubah nama kelas, posisikan kursor pada
UnitTest1
di editor kode, klik kanan, lalu pilih Ubah nama (atau tekan F2). Ketik BankAccountTests lalu tekan Enter.
File BankAccountTests.cs sekarang berisi kode berikut:
// The 'using' statement for Test Tools is in GlobalUsings.cs
// using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BankTests
{
[TestClass]
public class BankAccountTests
{
[TestMethod]
public void TestMethod1()
{
}
}
}
Menambahkan pernyataan penggunaan
Tambahkan using
pernyataan ke kelas pengujian agar dapat dipanggil ke proyek yang sedang diuji tanpa menggunakan nama yang sepenuhnya memenuhi syarat. Di bagian atas file kelas, tambahkan:
using BankAccountNS;
Persyaratan kelas pengujian
Persyaratan minimum untuk kelas pengujian adalah:
Atribut
[TestClass]
diperlukan pada setiap kelas yang berisi metode pengujian unit yang ingin Anda jalankan di Test Explorer.Setiap metode pengujian yang ingin Anda kenali oleh Test Explorer harus memiliki atribut
[TestMethod]
.
Anda dapat memiliki kelas lain dalam proyek pengujian unit yang tidak memiliki atribut [TestClass]
, dan Anda dapat memiliki metode lain di kelas pengujian yang tidak memiliki atribut [TestMethod]
. Anda dapat memanggil kelas dan metode lain ini dari metode pengujian Anda.
Membuat metode pengujian pertama
Dalam prosedur ini, Anda menulis metode pengujian unit untuk memverifikasi perilaku Debit
metode BankAccount
kelas.
Setidaknya ada tiga perilaku yang perlu diperiksa:
Metode memunculkan ArgumentOutOfRangeException jika jumlah debit lebih besar dari saldo.
Metode ini memunculkan ArgumentOutOfRangeException jika jumlah debit kurang dari nol.
Jika jumlah debit valid, metode ini mengurangi jumlah debit dari saldo akun.
Tip
Anda dapat menghapus metode TestMethod1
default, karena Anda tidak akan menggunakannya dalam panduan ini.
Untuk membuat metode pengujian
Pengujian pertama memverifikasi bahwa jumlah yang valid (yaitu, yang kurang dari saldo akun dan lebih besar dari nol) menarik jumlah yang benar dari akun. Tambahkan metode berikut ke kelas BankAccountTests
itu:
[TestMethod]
public void Debit_WithValidAmount_UpdatesBalance()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 4.55;
double expected = 7.44;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
account.Debit(debitAmount);
// Assert
double actual = account.Balance;
Assert.AreEqual(expected, actual, 0.001, "Account not debited correctly");
}
Metodenya sederhana: metode ini menyiapkan objek BankAccount
baru dengan saldo awal lalu menarik jumlah yang valid. Ini menggunakan metode Assert.AreEqual untuk memverifikasi bahwa saldo akhir seperti yang diharapkan. Metode seperti Assert.AreEqual
, Assert.IsTrue, dan lainnya sering digunakan dalam pengujian unit. Untuk informasi konseptual selengkapnya tentang menulis pengujian unit, lihat Menulis pengujian Anda.
Persyaratan metode pengujian
Metode pengujian harus memenuhi persyaratan berikut:
Metode dilengkapi dengan atribut
[TestMethod]
.Hal ini mengembalikan
void
.Metode tidak dapat memiliki parameter.
Mem-build dan menjalankan pengujian
Pada menu Build, pilih Build Solusi (atau tekan Ctrl + SHIFT + B).
Jika Test Explorer tidak terbuka, buka dengan memilih Test>Explorer (atau Uji>Windows>Test Explorer) dari bilah menu atas (atau tekan Ctrl + E, T).
Pilih Jalankan Semua untuk menjalankan pengujian (atau tekan Ctrl + R, V).
Saat pengujian berjalan, bilah status di bagian atas jendela Test Explorer dianimasikan. Di akhir uji coba, bilah berubah menjadi hijau jika semua metode pengujian lulus, atau merah jika salah satu pengujian gagal.
Dalam hal ini, pengujian gagal.
Pilih metode di Test Explorer untuk melihat detail di bagian bawah jendela.
Memperbaiki kode Anda dan menjalankan ulang pengujian Anda
Hasil pengujian berisi pesan yang menjelaskan kegagalan. Anda mungkin perlu menelusuri paling detail untuk melihat pesan ini. Untuk metode AreEqual
, pesan menampilkan apa yang diharapkan dan apa yang sebenarnya diterima. Anda mengharapkan saldo berkurang, tetapi malah bertambah dengan jumlah penarikan.
Pengujian unit telah menemukan bug: jumlah penarikan ditambahkan ke saldo akun ketika harus dikurangi.
Memperbaiki bug
Untuk memperbaiki kesalahan, dalam file BankAccount.cs, ganti baris:
m_balance += amount;
dengan:
m_balance -= amount;
Menjalankan ulang pengujian
Di Test Explorer, pilih Jalankan Semua untuk menjalankan ulang pengujian (atau tekan Ctrl + R, V). Bilah merah/hijau berubah menjadi hijau untuk menunjukkan bahwa pengujian lulus.
Menggunakan pengujian unit untuk meningkatkan kode Anda
Bagian ini menjelaskan bagaimana proses analisis berulang, pengembangan pengujian unit, dan pemfaktoran ulang dapat membantu Anda membuat kode produksi lebih kuat dan efektif.
Analisis data
Anda telah membuat metode pengujian untuk mengonfirmasi bahwa jumlah yang valid telah dipotong dengan benar dalam metode Debit
. Sekarang, verifikasi bahwa metode tersebut memunculkan ArgumentOutOfRangeException jika jumlah debitnya adalah:
- lebih besar dari saldo, atau
- kurang dari nol.
Membuat dan menjalankan metode pengujian baru
Buat metode pengujian untuk memverifikasi perilaku yang benar ketika jumlah debit kurang dari nol:
[TestMethod]
public void Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = -100.00;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act and assert
Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => account.Debit(debitAmount));
}
Gunakan metode ThrowsException untuk menegaskan bahwa pengecualian yang benar telah dimunculkan. Metode ini menyebabkan pengujian gagal kecuali jika ArgumentOutOfRangeException dimunculkan. Jika Anda memodifikasi sementara metode yang sedang diuji untuk memunculkan ApplicationException yang lebih umum saat jumlah debit kurang dari nol, pengujian akan berjalan dengan benar—yaitu, gagal.
Untuk menguji kasus ketika jumlah yang ditarik lebih besar dari saldo, lakukan langkah-langkah berikut:
Buat metode pengujian baru bernama
Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
.Salin isi metode dari
Debit_WhenAmountIsLessThanZero_ShouldThrowArgumentOutOfRange
ke metode baru.Atur
debitAmount
ke angka yang lebih besar dari saldo.
Jalankan dua pengujian dan verifikasi bahwa pengujian tersebut lulus.
Melanjutkan analisis
Metode yang diuji dapat ditingkatkan lebih lanjut. Dengan implementasi saat ini, kita tidak memiliki cara untuk mengetahui kondisi mana (amount > m_balance
atau amount < 0
) yang menyebabkan pengecualian dimunculkan selama pengujian. Kita hanya tahu bahwa ArgumentOutOfRangeException
dimunculkan ke suatu tempat dalam metode ini. Akan lebih baik jika kita dapat mengetahui kondisi mana dalam BankAccount.Debit
yang menyebabkan pengecualian dimunculkan (amount > m_balance
atau amount < 0
) sehingga kita dapat yakin bahwa metode memeriksa argumennya dengan benar.
Lihat metode yang sedang diuji (BankAccount.Debit
) lagi, dan perhatikan bahwa kedua pernyataan kondisional menggunakan konstruktor ArgumentOutOfRangeException
yang hanya menggunakan nama argumen sebagai parameter:
throw new ArgumentOutOfRangeException("amount");
Ada konstruktor yang dapat Anda gunakan yang melaporkan informasi yang jauh lebih kaya: ArgumentOutOfRangeException(String, Object, String) menyertakan nama argumen, nilai argumen, dan pesan yang ditentukan pengguna. Anda dapat merefaktor metode yang sedang diuji untuk menggunakan konstruktor ini. Lebih baik lagi, Anda dapat menggunakan anggota jenis yang tersedia untuk umum untuk menentukan kesalahan.
Refaktor kode yang sedang diuji
Pertama, tentukan dua konstanta untuk pesan kesalahan di cakupan kelas. Tempatkan definisi di kelas di bawah pengujian, BankAccount
:
public const string DebitAmountExceedsBalanceMessage = "Debit amount exceeds balance";
public const string DebitAmountLessThanZeroMessage = "Debit amount is less than zero";
Lalu, ubah dua pernyataan kondisional dalam metode Debit
:
if (amount > m_balance)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountExceedsBalanceMessage);
}
if (amount < 0)
{
throw new System.ArgumentOutOfRangeException("amount", amount, DebitAmountLessThanZeroMessage);
}
Refaktor metode pengujian
Refaktor metode pengujian dengan menghapus panggilan ke Assert.ThrowsException. Tutup panggilan ke Debit()
dalam blok try/catch
, temukan pengecualian spesifik yang diharapkan, dan verifikasi pesan terkaitnya. Metode Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains menyediakan kemampuan untuk membandingkan dua string.
Sekarang, Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
mungkin terlihat seperti ini:
[TestMethod]
public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
try
{
account.Debit(debitAmount);
}
catch (System.ArgumentOutOfRangeException e)
{
// Assert
StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);
}
}
Coba lagi, tulis ulang, dan analisis ulang
Saat ini, metode pengujian tidak menangani semua kasus yang seharusnya. Jika metode yang diuji, metode Debit
, gagal memunculkan ArgumentOutOfRangeException ketika debitAmount
lebih besar dari saldo (atau kurang dari nol), metode pengujian akan lulus. Skenario ini tidak baik karena Anda ingin metode pengujian gagal jika tidak ada pengecualian yang dilemparkan.
Hasil ini adalah bug dalam metode pengujian. Untuk mengatasi masalah ini, tambahkan pernyataan Assert.Fail di akhir metode pengujian untuk menangani kasus di mana tidak ada pengecualian yang dimunculkan.
Menjalankan ulang pengujian menunjukkan bahwa pengujian sekarang gagal jika pengecualian yang benar ditemukan. Blok catch
menangkap pengecualian, tetapi metode terus dijalankan dan gagal pada pernyataan Assert.Fail baru. Untuk mengatasi masalah ini, tambahkan pernyataan return
setelah StringAssert
di blok catch
. Menjalankan ulang pengujian mengonfirmasi bahwa Anda telah memperbaiki masalah ini. Versi akhir dari Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange
terlihat seperti ini:
[TestMethod]
public void Debit_WhenAmountIsMoreThanBalance_ShouldThrowArgumentOutOfRange()
{
// Arrange
double beginningBalance = 11.99;
double debitAmount = 20.0;
BankAccount account = new BankAccount("Mr. Bryan Walton", beginningBalance);
// Act
try
{
account.Debit(debitAmount);
}
catch (System.ArgumentOutOfRangeException e)
{
// Assert
StringAssert.Contains(e.Message, BankAccount.DebitAmountExceedsBalanceMessage);
return;
}
Assert.Fail("The expected exception was not thrown.");
}
Kesimpulan
Perbaikan pada kode pengujian menghasilkan metode pengujian yang lebih kuat dan informatif. Tetapi yang lebih penting, metode pengujian juga memperbaiki kode yang sedang diuji.
Tip
Panduan ini menggunakan kerangka kerja pengujian unit Microsoft untuk kode terkendali. Test Explorer juga dapat menjalankan pengujian dari kerangka kerja pengujian unit pihak ketiga yang memiliki adapter untuk Test Explorer. Untuk informasi selengkapnya, lihat Menginstal kerangka kerja pengujian unit pihak ketiga.
Konten terkait
Untuk informasi tentang cara menjalankan pengujian dari baris perintah, lihat Opsi baris perintah VSTest.Console.exe.