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.

  • ๐Ÿงฑ Tooling Split: Karma is the test runner, Jasmine is the specification framework, and angular-mocks supplies dependency injection helpers.
  • ๏ธ Installation Path: Install karma, karma-chrome-launcher, karma-jasmine, and karma-cli through npm, then generate karma.conf.js.
  • ๐Ÿ“ Configuration Rule: The files array must list angular.js, angular-mocks.js, application sources, and the test folder in that order.
  • ๐ŸŽ›๏ธ Controller Testing: Inject the $controller service, pass a mock $scope object, then assert the values the controller assigns.
  • ๐Ÿงฉ Directive Testing: Use $compile with $rootScope, call $digest, and inspect the rendered markup returned by the directive.
  • ๐ŸŒ End to End Layer: PROtractor drives a running application and counts repeated rows produced by ng-repeat.
  • ๐Ÿ“Œ Status podrลกke: AngularJS reached end of life on 31 December 2021, so treat this workflow as legacy maintenance knowledge.

AngularJS Unit Testing with Karma and Jasmine

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,

  1. npm is the command line utility for the node package manager used for installing custom modules on any machine. It ships with Node.js.
  2. Parametar instalacija upuฤ‡uje pomoฤ‡ni program naredbenog retka npm da je potrebna instalacija.
  3. 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

  1. kutni.js โ€“ This tells karma that your application depends on the core modules in AngularJS.
  2. angular-mocks.js โ€“ This tells karma to use the Unit Testing functionality for AngularJS from the angular-mocks.js file.
  3. Sve glavne aplikacije ili datoteke poslovne logike prisutne su u mapi lib vaลกe aplikacije.
  4. 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

  1. Funkcija describe koristi se za opis testa. U naลกem sluฤaju, naลกem testu dajemo opis 'Uzorak testa'.
  2. 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.
  3. 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.

Konfiguracija okvira Karma

  1. Rezultat dolazi u Karma explorer unutar Webstorm. Ovaj prozor prikazuje izvrลกenje svih testova koji su definirani u okviru karme.
  2. Ovdje moลพete vidjeti da je prikazan opis izvrลกenog testa koji je "Uzorak testa".
  3. Zatim moลพete vidjeti da se sam test koji ima naziv "Uvjet je istinit" izvrลกava.
  4. 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

  1. Napravite ID varijablu i dodijelite joj vrijednost 5.
  2. 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

  1. Napravite AngularJS modul pod nazivom sampleApp
  2. Napravite kontroler pod nazivom AngularJSController
  3. 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

  1. 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.
  2. 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.
  3. beforeEach(inject(function(_$controller_) โ€“ Ovo se koristi za ubacivanje laลพnog objekta u naลกem testu tako da se ponaลกa kao stvarni kontroler.
  4. var $scope = {}; Ovo je laลพni objekt koji se stvara za objekt $scope.
  5. 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
  6. 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

  1. Napravite AngularJS modul pod nazivom sampleApp
  2. Create a custom directive with the name โ€“ guru99
  3. 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

  1. beforeEach function โ€“ This function is used to load our AngularJS module called โ€˜sampleAppโ€™ before the test run.
  2. 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.
  3. 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.
  4. 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.
  5. 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.

  1. 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.
  2. 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.
  3. 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

  1. 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 /
  2. 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.
  3. 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.

  1. 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.
  2. 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.
  3. Keep specification names behavioural. A name such as โ€œreturns 5 when the controller initialisesโ€ reads better in a report than โ€œtest1โ€.
  4. 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.
  5. Measure coverage, but judge it carefully. Add karma-coverage to see untested branches. High coverage with weak assertions still hides defects.
  6. 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.

Pitanja i odgovori

The module holding that provider was not loaded. Add it inside beforeEach(module(โ€˜yourModuleโ€™)) and confirm angular-mocks.js is listed in karma.conf.js after angular.js, otherwise the injector cannot resolve the dependency.

Install karma-chrome-launcher and set the browsers option to ChromeHeadless in karma.conf.js. The suite then runs inside continuous integration pipelines and containers where no display server is available.

Yes. AI coding assistants read a controller and draft Jasmine specifications with mock scopes and matchers. Review the output carefully, because generated assertions often restate the implementation instead of verifying the intended behaviour.

Yes. AI tools translate Jasmine specifications into Jest or Vitest syntax and flag angular-mocks calls that have no direct equivalent. Manual verification remains essential, since dependency injection patterns rarely convert cleanly.

Most teams target seventy to eighty percent statement coverage on controllers and services. Chasing a higher figure usually means testing templates and third party libraries, which adds maintenance cost without catching real defects.

Saลพmite ovu objavu uz: