Pengujian Unit AngularJS dengan Karma & Jasmine
โก Ringkasan Cerdas
AngularJS Unit Testing with Karma and Jasmine verifies controllers, directives, and services in isolation. Karma runs specifications inside real browsers, Jasmine supplies the assertion syntax, and angular-mocks injects dependencies without a live server.

One of the most brilliant features of AngularJS is the pengujian aspek. Ketika para pengembang di Google Saat mengembangkan AngularJS, mereka selalu mempertimbangkan pengujian dan memastikan bahwa seluruh kerangka kerja AngularJS dapat diuji.
In AngularJS, testing is normally carried out using Karma (framework). AngularJS testing can be carried out without Karma, but the Karma framework has such a brilliant functionality for testing AngularJS code, that it makes sense to use this framework.
- Di AngularJS, kita bisa melakukan Pengujian Unit secara terpisah untuk pengontrol dan arahan.
- Kita juga bisa tampil end to end testing of AngularJS, which is testing from a user perspective.
โ ๏ธ Catatan versi: AngularJS (version 1.x) reached official end of life on 31 December 2021, and Protractor was retired in August 2023. The workflow on this page remains valid for maintaining existing AngularJS 1.x applications. New projects should use modern Angular with a currently supported runner.
Pengenalan & Pemasangan kerangka Karma
Karma adalah a pengujian alat otomasi created by the AngularJS team at GoogleLangkah pertama untuk menggunakan Karma adalah menginstal Karma. Karma diinstal melalui npm (yaitu pengelola paket yang digunakan untuk memudahkan instalasi modul pada mesin lokal).
Pemasangan Karma
Instalasi Karma melalui npm dilakukan dalam proses dua langkah.
Langkah 1) Jalankan baris di bawah ini dari dalam baris perintah
npm install karma karma-chrome-launcher karma-jasmine --save-dev
Di mana,
- npm is the command line utility for the node package manager used for installing custom modules on any machine. It ships with Node.js.
- Parameter install menginstruksikan utilitas baris perintah npm bahwa instalasi diperlukan.
- Ada 3 perpustakaan yang ditentukan di baris perintah yang diperlukan untuk bekerja dengan karma.
- karma adalah perpustakaan inti yang akan digunakan untuk tujuan pengujian.
- karma-chrome-launcher adalah perpustakaan terpisah yang memungkinkan perintah karma dikenali oleh browser chrome.
- karma-jasmine โ Ini menginstal melati yang merupakan kerangka dependen untuk Karma.
Langkah 2) Langkah selanjutnya adalah menginstal utilitas baris perintah karma. Ini diperlukan untuk menjalankan perintah garis karma. Utilitas jalur karma akan digunakan untuk menginisialisasi lingkungan karma untuk pengujian.
Untuk menginstal utilitas baris perintah, jalankan baris di bawah ini dari dalam baris perintah
npm install -g karma-cli
- karma-cli is used to install the command line interface for karma which will be used to write the karma commands in the command line interface. The -g flag installs it globally so that the karma command is available from any folder.
Konfigurasi kerangka Karma
Langkah selanjutnya adalah mengkonfigurasi karma yang dapat dilakukan melalui perintah
karma init
Setelah langkah di atas dijalankan, karma akan membuat file karma.conf.js. File tersebut mungkin akan terlihat seperti cuplikan di bawah ini
files: [ 'node_modules/angular/angular.js', 'node_modules/angular-mocks/angular-mocks.js', 'lib/app.js', 'tests/*.js' ]
File konfigurasi di atas memberi tahu mesin runtime karma hal-hal berikut
- sudut.js โ This tells karma that your application depends on the core modules in AngularJS.
- angular-mocks.js โ This tells karma to use the Unit Testing functionality for AngularJS from the angular-mocks.js file.
- Semua aplikasi utama atau file logika bisnis ada di folder lib aplikasi Anda.
- Folder tes akan berisi semua tes unit.
๐ก Kiat: Order matters inside the files array. angular.js must load before angular-mocks.js, and both must load before your application code, otherwise the injector is not available when the specifications run.
Untuk memeriksa apakah karma berfungsi, buat file bernama Sample.js, masukkan kode di bawah ini dan letakkan di direktori pengujian.
describe('Sample test', function() { it('Condition is true', function() { expect('AngularJS').toBe('AngularJS'); }); });
Kode di atas memiliki aspek-aspek berikut
- Fungsi deskripsikan digunakan untuk memberikan deskripsi tes. Dalam kasus kami, kami memberikan deskripsi 'Tes sampel' untuk pengujian kami.
- Fungsi 'it' digunakan untuk memberi nama pada pengujian. Dalam kasus kami, kami memberi nama pengujian kami sebagai 'Kondisi benar'. Nama tesnya harus bermakna.
- Kombinasi kata kunci 'expect' dan 'toBe' menyatakan berapa nilai yang diharapkan dan sebenarnya dari hasil tes. Jika nilai sebenarnya dan nilai yang diharapkan sama, maka pengujian akan lulus, jika tidak maka akan gagal.
Ketika Anda menjalankan baris berikut pada command prompt, maka akan menjalankan file pengujian di atas
karma start
Output di bawah ini diambil dari IDE Webstorm di mana langkah-langkah di atas dilakukan.
- Outputnya berasal dari penjelajah Karma di dalamnya Webstorm. Jendela ini menunjukkan pelaksanaan semua pengujian yang ditentukan dalam kerangka karma.
- Di sini Anda dapat melihat bahwa deskripsi pengujian yang dijalankan ditampilkan yaitu "Tes sampel".
- Selanjutnya, Anda dapat melihat bahwa pengujian itu sendiri yang diberi nama โKondisi benarโ dijalankan.
- Perhatikan bahwa karena semua tes memiliki ikon hijau โOkโ di sebelahnya yang melambangkan bahwa semua tes lulus.
What is Jasmine in AngularJS Unit Testing?
Karma decides where tests run, while Jasmine decides how they are written. Jasmine is a behaviour driven specification framework that supplies the vocabulary used in every example on this page, which is why the karma-jasmine adapter is installed alongside the runner.
Jasmine contributes four building blocks:
- describe(): Groups related specifications into a suite and accepts a readable description of the unit under test.
- it(): Declares a single specification. The name should state the behaviour being verified rather than the method being called.
- expect() with matchers: Compares an actual value against an expected one. Common matchers include toBe, toEqual, toContain, and toBeDefined.
- beforeEach() and afterEach(): Run setup and teardown before and after every specification, which keeps each test independent.
Jasmine also provides spies. A spy replaces a real function with a recorded stand in, so a controller can be tested without calling a live HTTP endpoint. Because Jasmine needs no DOM and no assertion library of its own, the combination of Karma and Jasmine remains the lightest way to run AngularJS JavaScript unit tests.
Menguji Pengontrol AngularJS
Kerangka pengujian karma juga memiliki fungsi untuk menguji Pengendali secara menyeluruh. Ini termasuk pengujian objek $scope yang digunakan dalam Pengendali.
Mari kita lihat contoh bagaimana kita dapat mencapai hal ini.
Dalam contoh kita,
Pertama-tama kita perlu mendefinisikan pengontrol. Pengontrol ini akan melakukan langkah-langkah yang disebutkan di bawah
- Buat variabel ID dan berikan nilai 5 padanya.
- Tetapkan variabel ID ke objek $scope.
Pengujian kita akan menguji keberadaan pengontrol ini dan juga menguji apakah variabel ID objek $scope disetel ke 5.
Pertama-tama kita perlu memastikan prasyarat berikut sudah ada
Install the angular-mocks library via npm. This can be done by executing the below line in the command prompt
npm install angular-mocks --save-dev
Berikutnya adalah memodifikasi file karma.conf.js untuk memastikan file yang tepat disertakan untuk pengujian. Segmen di bawah ini hanya menampilkan bagian file karma.conf.js yang perlu dimodifikasi
files: ['lib/angular.js', 'lib/angular-mocks.js', 'lib/index.js', 'test/*.js']
- Parameter 'files' pada dasarnya memberitahu Karma semua file yang diperlukan dalam menjalankan pengujian.
- The angular.js and angular-mocks.js file are required to run AngularJS unit tests
- File index.js akan berisi kode kita untuk pengontrol
- Folder test akan berisi semua tes AngularJS kami
Below is our AngularJS code which will be stored as a file Index.js in the test folder of our application.
Kode di bawah ini hanya melakukan hal-hal berikut
- Buat Modul AngularJS disebut sampleApp
- Buat pengontrol bernama AngularJSController
- Buat variabel bernama ID, berikan nilai 5 dan tetapkan ke objek $scope
var sampleApp = angular.module('sampleApp', []); sampleApp.controller('AngularJSController', function($scope) { $scope.ID = 5; });
Setelah kode di atas berhasil dijalankan, langkah selanjutnya adalah membuat a Uji Kasus untuk memastikan kode telah ditulis dan dijalankan dengan benar.
Kode untuk pengujian kami akan seperti yang ditunjukkan di bawah ini.
Kode tersebut akan berada dalam file terpisah yang disebut ControllerTest.js, yang akan ditempatkan di folder pengujian. Kode di bawah ini hanya melakukan hal-hal penting berikut
- beforeEach function โ This function is used to load our AngularJS module called โsampleAppโ before the test run. Note that this is the name of the module in an index.js file.
- The $controller object is created as a mockup object for the controller โAngularJSControllerโ which is defined in our index.js file. In any sort of Unit Testing, a mock object represents a dummy object which will actually be used for the testing. This mock object will actually simulate the behavior of our controller.
- beforeEach(inject(function(_$controller_) โ Ini digunakan untuk menginjeksi objek tiruan dalam pengujian kita sehingga berperilaku seperti pengontrol sebenarnya.
- var $ruang lingkup = {}; Ini adalah objek tiruan yang dibuat untuk objek $scope.
- var controller = $controller(โAngularJSControllerโ, { $scope: $scope }); โ Here we are checking for the existence of a controller named โAngularJSControllerโ. In here we are also assigning all variables from our $scope object in our controller in the Index.js file to the $scope object in our test file
- Terakhir, kami membandingkan $scope.ID dengan 5
describe('AngularJSController', function() { beforeEach(module('sampleApp')); var $controller; beforeEach(inject(function(_$controller_){ $controller = _$controller_; })); describe('$scope.ID', function() { it('Check the scope object', function() { var $scope = {}; var controller = $controller('AngularJSController', { $scope: $scope }); expect($scope.ID).toEqual(5); }); }); });
Tes di atas akan dijalankan di browser karma dan memberikan hasil kelulusan yang sama seperti yang ditunjukkan pada topik sebelumnya.
Menguji Direktif AngularJS
Kerangka pengujian Karma juga memiliki fungsionalitas untuk menguji arahan khusus. Ini termasuk templat.URLyang digunakan dalam arahan khusus.
Mari kita lihat contoh bagaimana kita dapat mencapai hal ini.
Dalam contoh kita, pertama-tama kita akan mendefinisikan sebuah arahan khusus yang melakukan hal-hal berikut ini
- Buat modul AngularJS bernama sampleApp
- Create a custom directive with the name โ guru99
- Buat fungsi yang mengembalikan templat dengan tag header yang menampilkan teks โIni adalah Pengujian AngularJS.โ
var sampleApp = angular.module('sampleApp', []); sampleApp.directive('guru99', function () { return { restrict: 'E', replace: true, template: '<h1>This is AngularJS Testing</h1>' }; });
Setelah kode di atas berhasil dieksekusi, langkah selanjutnya adalah membuat test case untuk memastikan kode telah ditulis dan dieksekusi dengan benar. Kode untuk pengujian kami akan seperti yang ditunjukkan di bawah ini
Kode tersebut akan berada dalam file terpisah yang disebut DirectiveTest.js, yang akan ditempatkan di folder pengujian. Kode di bawah ini hanya melakukan hal-hal penting berikut
- beforeEach function โ This function is used to load our AngularJS module called โsampleAppโ before the test run.
- The $compile service is used to compile the directive. This service is mandatory and needs to be declared so that AngularJS can use it to compile our custom directive.
- The $rootScope is the primary scope of any AngularJS application. We have seen the $scope object of the controller in earlier chapters. Well, the $scope object is the child object of the $rootScope object. The reason this is declared here is because we are making a change to an actual HTML tag in the DOM via our custom directive. Hence, we need to use the $rootScope service which actually listens or knows when any change happens from within an HTML document.
- var element = $compile(โ<guru99></guru99>โ)($rootScope) โ This is used to check whether our directive gets injected as it should. The directive is registered with the camel case name guru99, so AngularJS matches the lowercase element <guru99> in the markup. Hence this statement is used to make that check.
- expect(element.html()).toContain(โThis is AngularJS Testingโ) โ This is used to instruct the expect function that it should find the element(in our case the h1 tag) to contain the innerHTML text of โThis is AngularJS Testingโ.
describe('Unit testing directives', function() { var $compile, $rootScope; beforeEach(module('sampleApp')); beforeEach(inject(function(_$compile_, _$rootScope_){ $compile = _$compile_; $rootScope = _$rootScope_; })); it('Check the directive', function() { // Compile a piece of HTML containing the directive var element = $compile("<guru99></guru99>")($rootScope); $rootScope.$digest(); expect(element.html()).toContain("This is AngularJS Testing"); }); });
Tes di atas akan dijalankan di browser karma dan memberikan hasil kelulusan yang sama seperti yang ditunjukkan pada topik sebelumnya.
End to End Testing AngularJS applications
Kerangka kerja pengujian karma beserta kerangka kerja yang disebut ProtracTor memiliki fungsionalitas untuk menguji aplikasi web secara menyeluruh (end-to-end).
Jadi ini tidak hanya menguji arahan dan pengontrol, tetapi juga menguji hal lain yang mungkin muncul pada halaman HTML.
Mari kita lihat contoh bagaimana kita dapat mencapai hal ini.
Dalam contoh di bawah ini, kita akan memiliki aplikasi AngularJS yang membuat tabel data menggunakan direktif ng-repeat.
- Pertama-tama kita membuat variabel bernama "tutorial" dan menugaskannya beberapa pasangan nilai kunci dalam satu langkah. Setiap pasangan nilai kunci akan digunakan sebagai data saat menampilkan tabel. Variabel tutorial kemudian ditugaskan ke objek lingkup sehingga dapat diakses dari tampilan kita.
- Untuk setiap baris data dalam tabel, kami menggunakan direktif ng-repeat. Arahan ini melewati setiap pasangan nilai kunci dalam objek lingkup tutorial dengan menggunakan variabel ptutor.
- Akhirnya, kami menggunakan tag bersama dengan pasangan nilai kunci (ptutor.Name dan ptutor.Description) untuk menampilkan data tabel.
<table> <tr ng-repeat="ptutor in tutorial"> <td>{{ ptutor.Name }}</td> <td>{{ ptutor.Description }}</td> </tr> </table> </div> <script type="text/javascript"> var app = angular.module('DemoApp', []); app.controller('DemoController', function($scope) { $scope.tutorial = [ {Name: "Controllers", Description: "Controllers in action"}, {Name: "Models", Description: "Models and binding data"}, {Name: "Directives", Description: "Flexibility of Directives"} ]; });
Setelah kode di atas berhasil dieksekusi, langkah selanjutnya adalah membuat test case untuk memastikan kode telah ditulis dan dieksekusi dengan benar. Kode untuk pengujian kami akan seperti yang ditunjukkan di bawah ini
Pengujian kami sebenarnya akan menguji direktif ng-repeat dan memastikan bahwa direktif tersebut berisi 3 baris data sebagaimana mestinya dari contoh di atas.
Pertama-tama kita perlu memastikan prasyarat berikut sudah ada
Instal versi protracMenginstal pustaka Tor melalui npm. Ini dapat dilakukan dengan menjalankan baris berikut di command prompt.
npm install -g protractor
Kode untuk pengujian kami akan seperti yang ditunjukkan di bawah ini.
Kode tersebut akan berada dalam file terpisah yang disebut CompleteTest.js, yang akan ditempatkan di folder pengujian. Kode di bawah ini hanya melakukan hal-hal penting berikut
- Fungsi peramban disediakan oleh protracPustaka Tor dan mengasumsikan bahwa aplikasi AngularJS kita (dengan kode yang ditunjukkan di atas) berjalan di situs kita. URL โ http://localhost:8080/Guru99 /
- var list = element.all(by.repeater(โptutor in tutorialโ)); -This line of code is actually fetching the ng-repeat directive which is populated by the code โptutor in tutorialโ. The element and by.repeater are special keywords provided by the protracPustaka Tor yang memungkinkan kita untuk mendapatkan detail dari direktif ng-repeat.
- harapkan(daftar.hitungan()).toEqual(3); โ Terakhir, kita menggunakan fungsi ekspektasi untuk melihat bahwa kita memang mendapatkan 3 item yang diisi di tabel kita sebagai hasil dari direktif ng-repeat.
describe('Unit testing end to end', function() { beforeEach(function() { browser.get('http://localhost:8080/Guru99/'); }); it('Check the ng directive', function() { var list = element.all(by.repeater('ptutor in tutorial')); expect(list.count()).toEqual(3); }); });
Tes di atas akan dijalankan di browser karma dan memberikan hasil kelulusan yang sama seperti yang ditunjukkan pada topik sebelumnya.
Karma vs Jasmine vs Protractor: Key Differences
The three tools used across this page are often confused because they appear in the same command line. Each one occupies a different layer of the testing stack, as the table below makes clear.
| Parameter | Karma | Melati | pertractor |
| Kategori | Test runner | Specification framework | End to end automation framework |
| Pekerjaan utama | Launches browsers and reports results | Provides describe, it, and expect | Drives a live application in a real browser |
| Tingkat tes | Unit dan integrasi | Unit and integration | Dari ujung ke ujung |
| Needs a running server | Tidak | Tidak | Ya |
| konfigurasi file | karma.conf.js | None, it runs inside a runner | untuktractor.conf.js |
| Status terkini | Deprecated, maintenance only | Dipelihara secara aktif | Retired in August 2023 |
In short, Jasmine writes the test, Karma executes it, and Protractor extends the same Jasmine syntax to a fully rendered page.
Best Practices for AngularJS Unit Testing
A small set of habits keeps an AngularJS suite fast and trustworthy as the application grows.
- Test one unit at a time. Load only the module under test inside beforeEach, and mock every collaborator so a failure points at a single file.
- Never call a real backend. Use the $httpBackend service from angular-mocks to return canned responses. Tests then run offline and produce identical results on every machine.
- Keep specification names behavioural. A name such as โreturns 5 when the controller initialisesโ reads better in a report than โtest1โ.
- Always flush the digest cycle. Call $rootScope.$digest() after changing scope data, otherwise bindings and watchers never update and assertions fail for the wrong reason.
- Measure coverage, but judge it carefully. Add karma-coverage to see untested branches. High coverage with weak assertions still hides defects.
- Run the suite in continuous integration. Use a headless Chrome launcher so the same specifications execute on every commit rather than only on a developer machine.
Applying these rules turns the examples above from isolated demonstrations into a regression safety net for a legacy AngularJS codebase. For the wider picture, see the AngularJS tutorial series.

