Pengertian pengujian

Saat menulis software, Anda dapat memastikan bahwa software tersebut berfungsi dengan benar melalui pengujian. Pengujian secara luas didefinisikan sebagai proses menjalankan software dengan cara tertentu untuk memastikan perilakunya sebagaimana yang dimaksudkan.

Pengujian yang berhasil dapat memberikan keyakinan bahwa saat Anda menambahkan kode baru, fitur, atau bahkan mengupgrade dependensi, software yang telah Anda tulis akan terus berfungsi seperti yang diharapkan. Pengujian juga dapat membantu melindungi software Anda dari skenario yang tidak mungkin atau input yang tidak terduga.

Beberapa contoh perilaku di web yang mungkin ingin Anda uji meliputi:

  • Memastikan bahwa fitur situs web beroperasi dengan benar saat tombol diklik.
  • Mengonfirmasi bahwa fungsi yang kompleks memberikan hasil yang benar.
  • Menyelesaikan tindakan yang memerlukan login pengguna.
  • Memeriksa apakah formulir melaporkan error dengan benar saat data yang salah dimasukkan.
  • Memastikan aplikasi web yang kompleks terus berfungsi saat pengguna memiliki bandwidth yang sangat rendah atau offline.

Pengujian otomatis versus manual

Anda dapat menguji software dengan dua cara umum: pengujian otomatis dan pengujian manual.

Pengujian manual melibatkan manusia yang menjalankan software secara langsung, seperti memuat situs di browser, dan mengonfirmasi bahwa software berfungsi seperti yang diharapkan. Pengujian manual mudah dibuat atau ditentukan. Misalnya, dapatkah situs Anda dimuat? Dapatkah Anda melakukan tindakan ini?—tetapi setiap sesi membutuhkan waktu yang sangat besar bagi manusia. Meskipun manusia sangat kreatif, yang dapat memungkinkan jenis pengujian yang dikenal sebagai pengujian eksplorasi, kita masih bisa buruk dalam mendeteksi kegagalan atau inkonsistensi, terutama saat melakukan tugas yang sama berkali-kali.

Pengujian otomatis adalah proses yang memungkinkan pengujian dikodifikasi dan dijalankan berulang kali oleh komputer untuk mengonfirmasi perilaku software yang diinginkan tanpa meminta manusia melakukan langkah berulang, seperti penyiapan atau memeriksa hasil. Yang penting, setelah pengujian otomatis dikonfigurasi, pengujian otomatis dapat sering dijalankan. Ini masih merupakan definisi yang sangat luas, dan perlu diperhatikan bahwa pengujian otomatis memiliki berbagai bentuk dan bentuk. Sebagian besar pelatihan ini berkaitan dengan pengujian otomatis sebagai praktik.

Pengujian manual memang ada di tempatnya, sering kali sebagai cikal bakal penulisan pengujian otomatis, tetapi juga saat pengujian otomatis menjadi terlalu tidak dapat diandalkan, memiliki cakupan yang luas, atau sulit untuk ditulis.

Dasar-dasar melalui contoh

Bagi kami, sebagai developer web yang menulis JavaScript atau bahasa terkait, pengujian otomatis yang ringkas dapat berupa skrip seperti ini yang Anda jalankan setiap hari, mungkin melalui Node, atau dengan memuatnya di browser:

import { fibonacci } from "../src/math.js";

if (fibonacci(0) !== 0) {
  throw new Error("Invalid 0th fibonacci result");
}
const fib13 = fibonacci(13);
if (fib13 !== 233) {
  throw new Error("Invalid 13th fibonacci result, was=${fib13} wanted=233");
}

Ini adalah contoh sederhana yang memberikan wawasan berikut:

  • Ini adalah pengujian karena menjalankan beberapa software (fungsi Fibonacci) dan memastikan perilakunya berfungsi sesuai harapan dengan memeriksa hasilnya terhadap nilai yang diharapkan. Jika perilaku tidak benar, hal ini akan menyebabkan error, yang dinyatakan oleh JavaScript dengan menampilkan Error.

  • Meskipun Anda mungkin menjalankan skrip ini secara manual di terminal atau browser, ini masih merupakan pengujian otomatis karena dapat dijalankan berulang kali tanpa Anda harus melakukan setiap langkah. Halaman berikutnya, tempat pengujian dijalankan, akan menjelaskan lebih lanjut.

  • Meskipun pengujian ini tidak menggunakan library apa pun, melainkan JavaScript yang dapat berjalan di mana saja, namun pengujian ini tetap merupakan pengujian. Ada banyak alat yang dapat membantu Anda menulis pengujian, termasuk alat yang akan dibahas nanti dalam kursus ini, tetapi semua alat tersebut tetap berfungsi berdasarkan prinsip dasar yang menyebabkan error jika terjadi kesalahan.

Menguji library dalam praktik

Sebagian besar library atau framework pengujian bawaan menyediakan dua primitif utama yang membuat pengujian lebih mudah ditulis: pernyataan dan cara untuk menentukan pengujian independen. Hal ini akan dibahas secara mendetail sebagai bagian dari bagian berikutnya, pernyataan dan primitif lainnya. Namun, pada tingkat tinggi, penting untuk diingat bahwa hampir semua pengujian yang Anda lihat atau tulis akan menggunakan jenis primitif ini.

Pernyataan adalah cara untuk menggabungkan pemeriksaan hasil dan menyebabkan error jika terjadi kesalahan. Misalnya, Anda dapat membuat pengujian sebelumnya lebih ringkas dengan memperkenalkan assert:

import { fibonacci } from "../src/math.js";
import { assert } from "a-made-up-testing-library";

assert.equal(fibonacci(0), 0, "Invalid 0th fibonacci result");
assert.equal(fibonacci(13), 233, "Invalid 13th fibonacci result");

Anda dapat meningkatkan pengujian ini lebih lanjut dengan menentukan pengujian independen, yang secara opsional dikelompokkan ke dalam suite. Rangkaian berikut ini menguji fungsi Fibonacci dan fungsi Catalan secara independen:

import { fibonacci, catalan } from "../src/math.js";
import { assert, test, suite } from "a-made-up-testing-library";

suite("math tests", () => {
  test("fibonacci function", () => {
    assert.equal(fibonacci(0), 0, "Invalid 0th fibonacci result");
    assert.equal(fibonacci(13), 233, "Invalid 13th fibonacci result");
  });
  test("relationship between sequences", () => {
    const numberToCheck = 4;
    const fib = fibonacci(numberToCheck);
    const cat = catalan(numberToCheck);
    assert.isAbove(fib, cat);
  });
});

Dalam konteks pengujian software ini, test sebagai kata benda mengacu pada kasus pengujian: skenario tunggal yang independen dan dapat ditangani, seperti kasus pengujian "hubungan antar urutan" dalam contoh sebelumnya.

Pengujian yang diberi nama satu per satu berguna untuk tugas berikut, antara lain:

  • Menentukan bagaimana pengujian berhasil atau gagal dari waktu ke waktu.
  • Menyoroti bug atau skenario berdasarkan nama sehingga Anda dapat lebih mudah menguji apakah skenario telah diselesaikan.
  • Menjalankan beberapa pengujian secara terpisah dari yang lain, seperti melalui filter glob.

Salah satu cara untuk menggambarkan kasus pengujian adalah menggunakan "tiga A" pengujian unit: mengatur, bertindak, dan menyatakan. Setiap kasus pengujian, pada intinya, akan:

  • Susun beberapa nilai atau status (ini dapat berupa data input hard code).
  • Melakukan tindakan, seperti memanggil metode.
  • Nyatakan nilai output atau status yang diperbarui (menggunakan assert).

Skala pengujian

Contoh kode di bagian sebelumnya menjelaskan pengujian unit, karena menguji bagian kecil software, yang sering kali berfokus pada satu file, dan dalam hal ini, hanya output dari fungsi tunggal. Kompleksitas pengujian tumbuh saat Anda mempertimbangkan kode dari beberapa file, komponen, atau bahkan sistem berbeda yang saling terhubung (terkadang berada di luar kendali Anda, seperti layanan jaringan atau perilaku dependensi eksternal). Oleh karena itu, jenis pengujian sering diberi nama berdasarkan cakupan atau skala.

Bersama dengan pengujian unit, beberapa contoh jenis pengujian lainnya mencakup pengujian komponen, pengujian visual, dan pengujian integrasi. Tak satu pun dari nama-nama tersebut yang memiliki definisi yang ketat, dan mungkin memiliki arti yang berbeda bergantung pada codebase Anda, jadi ingatlah untuk menggunakannya sebagai panduan dan temukan definisi yang sesuai untuk Anda. Misalnya, apa yang dimaksud dengan komponen yang sedang diuji di sistem Anda? Bagi developer React, hal ini mungkin benar-benar dipetakan ke "komponen React", tetapi mungkin memiliki arti yang berbeda bagi developer dalam konteks lain.

Skala pengujian individual dapat menempatkannya ke dalam konsep yang sering disebut sebagai "piramida pengujian", yang dapat menjadi aturan praktis untuk apa yang diperiksa oleh pengujian dan cara menjalankannya.

Piramida pengujian,
    dengan pengujian end-to-end (E2E) di bagian atas, pengujian integrasi di tengah, dan
    pengujian unit di bagian bawah.
Paramida pengujian.

Ide ini telah diiterasi, dan berbagai bentuk lainnya kini dipopulerkan, seperti berlian pengujian atau kerucut es pengujian. Prioritas penulisan pengujian Anda mungkin akan unik untuk codebase Anda. Namun, fitur umumnya adalah pengujian yang lebih sederhana, seperti pengujian unit, cenderung lebih cepat dijalankan, lebih mudah ditulis (sehingga Anda akan memilikinya lebih banyak), dan menguji cakupan terbatas, sedangkan pengujian kompleks seperti pengujian menyeluruh sulit ditulis, tetapi dapat menguji cakupan yang lebih luas. Faktanya, lapisan teratas dari banyak 'bentuk' pengujian cenderung merupakan pengujian manual, karena beberapa interaksi pengguna terlalu kompleks untuk dikodifikasi menjadi pengujian otomatis.

Jenis ini akan diperluas dalam jenis pengujian otomatis.

Menguji pemahaman Anda

Primitif apa yang disediakan oleh sebagian besar library dan framework pengujian?

Layanan runner yang menggunakan penyedia cloud.
Beberapa runner berbasis browser menawarkan cara untuk meng-outsource pengujian Anda, tetapi ini bukan fitur normal library pengujian.
Pernyataan yang menyebabkan pengecualian jika tidak terpenuhi.
Meskipun Anda dapat menampilkan error untuk menggagalkan pengujian, assert() dan variasinya cenderung disertakan karena membuat pemeriksaan lebih mudah ditulis.
Cara untuk mengategorikan pengujian ke dalam piramida pengujian.
Sebenarnya tidak ada cara standar untuk melakukan ini. Anda dapat mengawali nama pengujian, atau menempatkannya di file yang berbeda, tetapi kategorisasi tidak benar-benar disertakan dalam sebagian besar framework pengujian.
Kemampuan untuk menentukan pengujian independen berdasarkan fungsi.
Metode test() disertakan di hampir semua runner pengujian. Hal ini penting karena kode pengujian tidak berjalan di tingkat teratas file, yang memungkinkan runner pengujian memperlakukan setiap kasus pengujian sebagai unit independen.