Setelah mengubah atau menambahkan kode, Anda harus menjalankan pengujian unit yang ada dan mempertimbangkan untuk menulis lebih banyak. Semua pengujian dijalankan pada versi kode yang tidak dikompresi.
Ada dua kumpulan pengujian unit: pengujian JS dan pengujian generator blok.
Pengujian JS
Pengujian JS mengonfirmasi pengoperasian fungsi JavaScript internal di core Blockly. Kita menggunakan Mocha untuk menjalankan pengujian unit, Sinon untuk membuat stub dependensi, dan Chai untuk membuat pernyataan tentang kode.
Menjalankan Pengujian
Di blockly dan blockly-samples, npm run test
akan menjalankan pengujian unit. Di
blockly, tindakan ini juga akan menjalankan pengujian lain seperti linting dan kompilasi. Anda juga dapat membuka tests/mocha/index.html
di browser untuk menjalankan semua pengujian mocha secara interaktif.
Menulis Pengujian
Kita menggunakan antarmuka TDD Mocha untuk menjalankan pengujian. Pengujian disusun ke dalam suite,
yang dapat berisi sub-suite dan/atau pengujian tambahan. Umumnya, setiap
komponen Blockly (seperti toolbox
atau workspace
) memiliki file pengujiannya sendiri
yang berisi satu atau beberapa suite. Setiap suite dapat memiliki metode setup
dan teardown
yang masing-masing akan dipanggil sebelum dan sesudah, setiap pengujian dalam
rangkaian tersebut.
Helper Pengujian
Kami memiliki sejumlah fungsi bantuan khusus untuk Blockly yang mungkin berguna saat menulis pengujian. Ini dapat ditemukan di core dan di blockly-samples.
Fungsi helper mencakup sharedTestSetup
dan sharedTestTeardown
yang
diperlukan untuk dipanggil sebelum dan sesudah pengujian (lihat bagian
Persyaratan).
sharedTestSetup
:
- Menyiapkan timer palsu sinon (dalam beberapa pengujian, Anda harus menggunakan
this.clock.runAll
). - Stubly.Events.fire akan segera diaktifkan (dapat dikonfigurasi).
- Menyiapkan pembersihan otomatis blockTypes yang ditentukan melalui
defineBlocksWithJsonArray
. - Mendeklarasikan beberapa properti pada konteks
this
yang dimaksudkan untuk dapat diakses:this.clock
(tetapi tidak boleh dipulihkan karena akan menyebabkan masalah disharedTestTeardown
)this.eventsFireStub
this.sharedCleanup
(untuk digunakan denganaddMessageToCleanup
danaddBlockTypeToCleanup
) (CATATAN: Anda tidak perlu menggunakanaddBlockTypeToCleanup
jika menentukan blok menggunakandefineBlocksWithJsonArray
)
Fungsi ini memiliki satu parameter options
opsional untuk mengonfigurasi penyiapan. Saat ini,
hanya digunakan untuk menentukan apakah akan membuat stub Blockly.Events.fire
untuk segera diaktifkan (akan membuat stub secara default).
sharedTestTeardown
:
- Menghapus ruang kerja
this.workspace
(bergantung pada tempatnya ditentukan, lihat bagian Persyaratan Pengujian untuk mengetahui informasi selengkapnya). - Memulihkan semua stub.
- Membersihkan semua jenis blok yang ditambahkan melalui
defineBlocksWithJsonArray
danaddBlockTypeToCleanup
. - Menghapus semua pesan yang ditambahkan melalui
addMessageToCleanup
.
Persyaratan Pengujian
- Setiap pengujian harus memanggil
sharedTestSetup.call(this);
sebagai baris pertama dalam penyiapan suite terluar dansharedTestTeardown.call(this);
sebagai baris terakhir dalam penghapusan suite terluar untuk file. - Jika memerlukan ruang kerja dengan toolbox umum, Anda dapat menggunakan salah satu toolbox preset pada
index.html
pengujian. Lihat contoh di bawah. - Anda harus membuang
this.workspace
dengan benar. Pada sebagian besar pengujian, Anda akan menentukanthis.workspace
di suite terluar dan menggunakannya untuk semua pengujian berikutnya, tetapi dalam beberapa kasus, Anda mungkin menentukan atau menentukan ulang kode tersebut di rangkaian dalam (misalnya, salah satu pengujian Anda memerlukan ruang kerja dengan opsi yang berbeda dari yang awalnya Anda siapkan). Alat ini harus dibuang di akhir pengujian.- Jika Anda menentukan
this.workspace
di suite terluar dan tidak pernah menentukan ulang, Anda tidak perlu melakukan tindakan lebih lanjut. Data tersebut akan otomatis dihapus olehsharedTestTeardown
. - Jika Anda menentukan
this.workspace
untuk pertama kalinya di suite dalam (yaitu Anda tidak menentukannya di suite terluar), Anda harus membuangnya secara manual dengan memanggilworkspaceTeardown.call(this, this.workspace)
dalam penghapusan suite tersebut. - Jika Anda menentukan
this.workpace
di suite terluar, tetapi kemudian menentukannya ulang di suite pengujian dalam, Anda harus terlebih dahulu memanggilworkspaceTeardown.call(this, this.workspace)
sebelum menentukan ulang untuk menghilangkan ruang kerja asli yang ditentukan di suite tingkat atas. Anda juga harus membuang nilai baru secara manual dengan memanggilworkspaceTeardown.call(this, this.workspace)
lagi dalam penghapusan suite dalam ini.
- Jika Anda menentukan
Struktur Pengujian
Pengujian unit umumnya mengikuti struktur yang ditetapkan, yang dapat diringkas sebagai mengatur, bertindak, menyatakan.
- Arrange: Menyiapkan status dunia dan kondisi yang diperlukan untuk perilaku yang sedang diuji.
- Bertindak: Panggil kode yang sedang diuji untuk memicu perilaku yang sedang diuji.
- Assert: Buat pernyataan tentang nilai yang ditampilkan atau interaksi dengan objek tiruan untuk memverifikasi kebenarannya.
Dalam pengujian sederhana, mungkin tidak ada perilaku yang perlu diatur, dan tahap tindakan dan pernyataan dapat digabungkan dengan menyisipkan panggilan ke kode yang sedang diuji dalam pernyataan. Untuk kasus yang lebih kompleks, pengujian akan lebih mudah dibaca jika Anda mengikuti 3 tahap ini.
Berikut adalah contoh file pengujian (disederhanakan dari aslinya).
suite('Flyout', function() {
setup(function() {
sharedTestSetup.call(this);
this.toolboxXml = document.getElementById('toolbox-simple');
this.workspace = Blockly.inject('blocklyDiv',
{
toolbox: this.toolboxXml
});
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('simple flyout', function() {
setup(function() {
this.flyout = this.workspace.getFlyout();
});
test('y is always 0', function() {
// Act and assert stages combined for simple test case
chai.assert.equal(this.flyout.getY(), 0, 'y coordinate in vertical flyout is 0');
});
test('x is right of workspace if flyout at right', function() {
// Arrange
sinon.stub(this.flyout.targetWorkspace, 'getMetrics').returns({
viewWidth: 100,
});
this.flyout.targetWorkspace.toolboxPosition = Blockly.TOOLBOX_AT_RIGHT;
this.flyout.toolboxPosition_ = Blockly.TOOLBOX_AT_RIGHT;
// Act
var x = this.flyout.getX();
// Assert
chai.assert.equal(x, 100, 'x is right of workspace');
});
});
});
Hal-hal yang perlu diperhatikan dari contoh ini:
- Suite dapat berisi suite lain yang memiliki metode
setup
danteardown
tambahan. - Setiap suite dan pengujian memiliki nama deskriptif.
- Pernyataan Chai digunakan untuk membuat pernyataan tentang kode.
- Anda dapat memberikan argumen string opsional yang akan ditampilkan jika pengujian gagal. Hal ini mempermudah proses debug pengujian yang rusak.
- Urutan parameternya adalah
chai.assert.equal(actualValue, expectedValue, optionalMessage)
. Jika Anda menukaractual
danexpected
, pesan error tidak akan masuk akal.
- Sinon digunakan untuk membuat stub metode saat Anda tidak ingin memanggil kode yang sebenarnya. Dalam
contoh ini, kita tidak ingin memanggil fungsi metrik yang sebenarnya karena
tidak relevan dengan pengujian ini. Kita hanya peduli dengan cara hasil digunakan oleh
metode yang sedang diuji. Sinon membuat stub fungsi
getMetrics
untuk menampilkan respons standar yang dapat kita periksa dengan mudah dalam pernyataan pengujian. - Metode
setup
untuk setiap suite hanya boleh berisi penyiapan umum yang berlaku untuk semua pengujian. Jika pengujian untuk perilaku tertentu bergantung pada kondisi tertentu, kondisi tersebut harus dinyatakan dengan jelas dalam pengujian yang relevan.
Pengujian Proses Debug
- Anda dapat membuka pengujian di browser dan menggunakan alat developer untuk menetapkan titik henti sementara dan menyelidiki apakah pengujian Anda gagal secara tidak terduga (atau lulus secara tidak terduga).
Tetapkan
.only()
atau.skip()
pada pengujian atau rangkaian pengujian untuk hanya menjalankan kumpulan pengujian tersebut, atau lewati pengujian. Contoh:suite.only('Workspace', function () { suite('updateToolbox', function () { test('test name', function () { // ... }); test.skip('test I don’t care about', function () { // ... }); }); });
Jangan lupa untuk menghapusnya sebelum melakukan commit pada kode Anda.
Pengujian Pembuat Blok
Setiap blok memiliki pengujian unitnya sendiri. Pengujian ini memverifikasi bahwa blok menghasilkan kode daripada berfungsi sebagaimana mestinya.
- Muat
tests/generators/index.html
di Firefox atau Safari. Perlu diketahui bahwa Chrome dan Opera memiliki batasan keamanan yang mencegah pemuatan pengujian dari sistem "file://" lokal (Masalah 41024 dan 47416). - Pilih bagian sistem yang relevan untuk diuji dari menu drop-down, lalu klik "Muat". Blok akan muncul di ruang kerja.
- Klik "JavaScript".
Salin dan jalankan kode yang dihasilkan dalam konsol JavaScript. Jika output diakhiri dengan "OK", berarti pengujian telah lulus. - Klik "Python".
Salin dan jalankan kode yang dihasilkan di penafsir Python. Jika output diakhiri dengan "OK", pengujian telah lulus. - Klik "PHP".
Salin dan jalankan kode yang dihasilkan di penafsir PHP. Jika output diakhiri dengan "OK", pengujian telah lulus. - Klik "Lua".
Salin dan jalankan kode yang dihasilkan dalam penafsir Lua. Jika output diakhiri dengan "OK", pengujian telah lulus. - Klik "Dart".
Salin dan jalankan kode yang dihasilkan di interpreter Dart. Jika output diakhiri dengan "OK", pengujian telah lulus.
Mengedit Pengujian Generator Blok
- Muat
tests/generators/index.html
di browser. - Pilih bagian sistem yang relevan dari menu drop-down, lalu klik "Muat". Blok akan muncul di ruang kerja.
- Buat perubahan atau penambahan pada blok.
- Klik "XML".
- Salin XML yang dihasilkan ke file yang sesuai di
tests/generators/
.