AngularJS Unit Testing with Karma & Jasmine
โก Pametni saลพetak
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 Ispitivanje aspekt. Kada programeri na Google Razvili su AngularJS, imajuฤi na umu testiranje i osigurali su da je cijeli AngularJS framework testiran.
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.
- U AngularJS-u moลพemo izvesti Ispitivanje jedinice odvojeno za kontrolere i direktive.
- Takoฤer moลพemo izvesti end to end testing of AngularJS, which is testing from a user perspective.
โ ๏ธ Napomena o verziji: 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.
Uvod i instalacija okvira Karma
Karma je a alat za automatizaciju testiranja created by the AngularJS team at GooglePrvi korak za koriลกtenje Karme je instalacija Karme. Karma se instalira putem npm-a (koji je upravitelj paketa koji se koristi za jednostavnu instalaciju modula na lokalnom raฤunalu).
Instalacija Karme
Instalacija Karme putem npm-a odvija se u dva koraka.
Korak 1) Izvrลกite donji redak iz naredbenog retka
npm install karma karma-chrome-launcher karma-jasmine --save-dev
pri ฤemu,
- npm is the command line utility for the node package manager used for installing custom modules on any machine. It ships with Node.js.
- Parametar instalacija upuฤuje pomoฤni program naredbenog retka npm da je potrebna instalacija.
- Postoje 3 biblioteke navedene u naredbenom retku koje su potrebne za rad s karmom.
- karma je temeljna biblioteka koja ฤe se koristiti u svrhe testiranja.
- karma-chrome-launcher je zasebna biblioteka koja omoguฤuje da chrome preglednik prepozna karma naredbe.
- karma-jasmine โ Ovo instalira jasmine koji je ovisan okvir za Karmu.
Korak 2) Sljedeฤi korak je instalacija usluลพnog programa naredbenog retka karma. Ovo je potrebno za izvrลกavanje naredbi karma linije. Pomoฤni program karma line koristit ฤe se za pokretanje karma okruลพenja za testiranje.
Za instalaciju usluลพnog programa naredbenog retka izvrลกite donji redak iz naredbenog retka
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.
Konfiguracija okvira Karma
Sljedeฤi korak je konfiguriranje karme ลกto se moลพe uฤiniti putem naredbe
karma init
Nakon izvrลกenja gornjeg koraka, karma ฤe stvoriti datoteku karma.conf.js. Datoteka ฤe vjerojatno izgledati kao isjeฤak prikazan u nastavku
files: [ 'node_modules/angular/angular.js', 'node_modules/angular-mocks/angular-mocks.js', 'lib/app.js', 'tests/*.js' ]
Gornje konfiguracijske datoteke govore karma runtime motoru sljedeฤe stvari
- kutni.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.
- Sve glavne aplikacije ili datoteke poslovne logike prisutne su u mapi lib vaลกe aplikacije.
- Mapa testova sadrลพavat ฤe sve jediniฤne testove.
๐ก Savjet: 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.
Da biste provjerili radi li karma, kreirajte datoteku pod nazivom Sample.js, stavite donji kod i smjestite je u testni direktorij.
describe('Sample test', function() { it('Condition is true', function() { expect('AngularJS').toBe('AngularJS'); }); });
Gornji kod ima sljedeฤe aspekte
- Funkcija describe koristi se za opis testa. U naลกem sluฤaju, naลกem testu dajemo opis 'Uzorak testa'.
- Funkcija 'it' koristi se za davanje naziva testu. U naลกem sluฤaju, naลกem testu dajemo naziv 'Uvjet je istinit'. Naziv testa mora biti smislen.
- Kombinacija kljuฤnih rijeฤi 'expect' i 'toBe' govori o oฤekivanoj i stvarnoj vrijednosti rezultata testa. Ako su stvarna i oฤekivana vrijednost iste, test ฤe proฤi inaฤe neฤe uspjeti.
Kada izvrลกite sljedeฤi redak u naredbenom retku, on ฤe izvrลกiti gornju testnu datoteku
karma start
Ispis u nastavku preuzet je iz IDE-a Webstorm u kojem su provedeni gore navedeni koraci.
- Rezultat dolazi u Karma explorer unutar Webstorm. Ovaj prozor prikazuje izvrลกenje svih testova koji su definirani u okviru karme.
- Ovdje moลพete vidjeti da je prikazan opis izvrลกenog testa koji je "Uzorak testa".
- Zatim moลพete vidjeti da se sam test koji ima naziv "Uvjet je istinit" izvrลกava.
- Imajte na umu da buduฤi da svi testovi imaju zelenu ikonu "Ok" pored sebe koja simbolizira da su svi testovi proลกli.
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.
Testiranje AngularJS kontrolera
Okvir za testiranje karme takoฤer ima funkcionalnost testiranja Kontrolora od kraja do kraja. To ukljuฤuje testiranje objekta $scope koji se koristi unutar kontrolera.
Pogledajmo primjer kako to moลพemo postiฤi.
U naลกem primjeru,
Prvo bismo trebali definirati kontroler. Ovaj upravljaฤ bi izvrลกio dolje navedene korake
- Napravite ID varijablu i dodijelite joj vrijednost 5.
- Dodijelite varijablu ID objektu $scope.
Naลก test ฤe testirati postojanje ovog kontrolera i takoฤer testirati je li ID varijabla objekta $scope postavljena na 5.
Prvo moramo osigurati da su sljedeฤi preduvjeti na mjestu
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
Sljedeฤe je modificiranje datoteke karma.conf.js kako bi se osiguralo da su prave datoteke ukljuฤene u test. Donji segment samo prikazuje dio datoteke karma.conf.js koji treba modificirati
files: ['lib/angular.js', 'lib/angular-mocks.js', 'lib/index.js', 'test/*.js']
- Parametar 'files' u osnovi govori Karmi sve datoteke koje su potrebne za izvoฤenje testova.
- The angular.js and angular-mocks.js file are required to run AngularJS unit tests
- Datoteka index.js sadrลพavat ฤe naลก kod za kontroler
- Testna mapa sadrลพavat ฤe sve naลกe AngularJS testove
Below is our AngularJS code which will be stored as a file Index.js in the test folder of our application.
Donji kod radi samo sljedeฤe stvari
- Napravite AngularJS modul pod nazivom sampleApp
- Napravite kontroler pod nazivom AngularJSController
- Napravite varijablu pod nazivom ID, dajte joj vrijednost 5 i dodijelite je objektu $scope
var sampleApp = angular.module('sampleApp', []); sampleApp.controller('AngularJSController', function($scope) { $scope.ID = 5; });
Nakon ลกto se gornji kod uspjeลกno izvrลกi, sljedeฤi korak bio bi stvaranje a Testni sluฤaj kako bi se osiguralo da je kรดd ispravno napisan i izveden.
Kod za naลก test bit ฤe prikazan u nastavku.
Kod ฤe biti u zasebnoj datoteci pod nazivom ControllerTest.js, koja ฤe biti smjeลกtena u testnu mapu. Donji kod radi samo sljedeฤe kljuฤne stvari
- 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_) โ Ovo se koristi za ubacivanje laลพnog objekta u naลกem testu tako da se ponaลกa kao stvarni kontroler.
- var $scope = {}; Ovo je laลพni objekt koji se stvara za objekt $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
- Na kraju, usporeฤujemo $scope.ID s 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); }); }); });
Gore navedeni test pokrenut ฤe se u karma pregledniku i dati ฤe isti prolazni rezultat kao ลกto je prikazano u prethodnoj temi.
Testiranje AngularJS direktiva
Okvir za testiranje karme takoฤer ima funkcionalnost za testiranje prilagoฤenih direktiva. To ukljuฤuje predloลพakURLkoji se koriste unutar prilagoฤenih direktiva.
Pogledajmo primjer kako to moลพemo postiฤi.
U naลกem primjeru, prvo ฤemo definirati prilagoฤenu direktivu koja radi sljedeฤe stvari
- Napravite AngularJS modul pod nazivom sampleApp
- Create a custom directive with the name โ guru99
- Napravite funkciju koja vraฤa predloลพak s oznakom zaglavlja koja prikazuje tekst "Ovo je AngularJS testiranje."
var sampleApp = angular.module('sampleApp', []); sampleApp.directive('guru99', function () { return { restrict: 'E', replace: true, template: '<h1>This is AngularJS Testing</h1>' }; });
Nakon ลกto se gornji kod uspjeลกno izvrลกi, sljedeฤi korak bio bi stvaranje testnog sluฤaja kako bi se osiguralo da je kod ispravno napisan i izvrลกen. Kod za naลก test bit ฤe prikazan u nastavku
Kod ฤe biti u zasebnoj datoteci pod nazivom DirectiveTest.js, koja ฤe biti smjeลกtena u testnu mapu. Donji kod radi samo sljedeฤe kljuฤne stvari
- 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"); }); });
Gore navedeni test pokrenut ฤe se u karma pregledniku i dati ฤe isti prolazni rezultat kao ลกto je prikazano u prethodnoj temi.
End to End Testing AngularJS applications
Okvir za testiranje karme zajedno s okvirom pod nazivom ProtracTor ima funkcionalnost testiranja web aplikacije od poฤetka do kraja.
Dakle, to nije samo testiranje direktiva i kontrolera, veฤ i testiranje bilo ฤega drugog ลกto se moลพe pojaviti na HTML stranici.
Pogledajmo primjer kako to moลพemo postiฤi.
U naลกem primjeru u nastavku, imat ฤemo AngularJS aplikaciju koja stvara podatkovnu tablicu pomoฤu direktive ng-repeat.
- Prvo stvaramo varijablu pod nazivom "tutorial" i dodjeljujemo joj parove kljuฤ-vrijednost u jednom koraku. Svaki par kljuฤ-vrijednost koristit ฤe se kao podatak prilikom prikaza tablice. Varijabla vodiฤa se zatim dodjeljuje objektu opsega tako da mu se moลพe pristupiti iz naลกeg pogleda.
- Za svaki redak podataka u tablici koristimo direktivu ng-repeat. Ova direktiva prolazi kroz svaki par kljuฤ-vrijednost u objektu opsega vodiฤa pomoฤu varijable ptutor.
- Konaฤno, koristimo se oznaku zajedno s parovima vrijednosti kljuฤa (ptutor.Name i ptutor.Description) za prikaz podataka tablice.
<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"} ]; });
Nakon ลกto se gornji kod uspjeลกno izvrลกi, sljedeฤi korak bio bi stvaranje testnog sluฤaja kako bi se osiguralo da je kod ispravno napisan i izvrลกen. Kod za naลก test bit ฤe prikazan u nastavku
Naลก test zapravo ฤe testirati direktivu ng-repeat i osigurati da sadrลพi 3 retka podataka kao ลกto bi trebalo iz gornjeg primjera.
Prvo moramo osigurati da su sljedeฤi preduvjeti na mjestu
Instalirajte profesionalcatractor biblioteku putem npm-a. To se moลพe uฤiniti izvrลกavanjem donje linije u naredbenom retku
npm install -g protractor
Kod za naลก test bit ฤe prikazan u nastavku.
Kod ฤe biti u zasebnoj datoteci pod nazivom CompleteTest.js, koja ฤe biti smjeลกtena u testnu mapu. Donji kod radi samo sljedeฤe kljuฤne stvari
- Funkciju preglednika osigurava protractor biblioteku i pretpostavlja da naลกa AngularJS aplikacija (s gore prikazanim kodom) radi na naลกoj web stranici 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 protractor biblioteka koja nam omoguฤuje dobivanje detalja o direktivi ng-repeat.
- oฤekuj(list.count()).toEqual(3); โ Na kraju, koristimo funkciju expect da bismo vidjeli da doista dobivamo 3 stavke koje se popunjavaju u naลกoj tablici kao rezultat direktive 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); }); });
Gore navedeni test pokrenut ฤe se u karma pregledniku i dati ฤe isti prolazni rezultat kao ลกto je prikazano u prethodnoj temi.
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.
| Parametar | Karma | Jasmin | PROtrachumka |
| Kategorija | Test runner | Specification framework | End to end automation framework |
| Glavni posao | Launches browsers and reports results | Provides describe, it, and expect | Drives a live application in a real browser |
| Razina testa | Jedinica i integracija | Unit and integration | Kraj do kraja |
| Needs a running server | Ne | Ne | Da |
| Konfiguracijska datoteka | karma.conf.js | None, it runs inside a runner | zatractor.conf.js |
| Trenutni status | Deprecated, maintenance only | Aktivno odrลพavano | 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 Serija.

