Using Karma to scenario test an AngularJS controller? - angularjs

Here is what I have tried:
$ git clone https://github.com/angular/angular-seed my_project && cd my_project
$ rm -rf app update_angular.js test/e2e/scenarios.js
$ touch test/e2e/scenarios.js
I then pasted code from AngularJS's official ngMock.$httpBackend docs into:
test/e2e/scenarios.js
'use strict'; // Line 1
function MyController($scope, $http) {...} // Lines 3-22
describe('MyController', function() {...} // Lines 24-87
Error
Unfortunately when I run the tests using config/karma-e2e.conf, I get:
ReferenceError: inject is not defined at
http://localhost:9876/base/test/e2e/scenarios.js?1387679134000:31

inject is defined in angular-mocks file, and is intended for unit tests only. If you're using Karma just add it to the files array.
e2e tests are on top of the browser, and run by angular-scenario. you can't inject any Angular components there.
BTW the Angular team are in the process of migrating their functional testing to protractor which is based on Selenium. I'd catch up with that instead of the angular-scenario testing framework. Protractor is a lot better.

Related

Is it possible to use Jasmine without Karma for testing Angular/Node based Nw.js apps?

I've read ton's of tutorials, but I must admit that this testing stuff is still very confusing to me. I have a Nw.js app which (of course) uses NodeJS and also Angular. I've installed the Jasmine test framework globally via npm and wrote an example test which starts with the following lines, and placed it in the spec sub-directory:
describe ( 'Test for my controller', function () {
beforeEach ( module ('module_under_test') );
... and so on ...
});
When running the test by typing jasmine on the cmd line (from the root folder of the app), I get the following error message:
TypeError: module is not a function
I know that I have to include the Angular library somehow. But where? In a normal browser application, it is included in the HTML <script> tag, but I don't have this possibility. I also know that I could write a HTML file, which shows the Jasmine result page after tests have finished, but I would prefer to start Jasmine on the cmd line.
First I thought about adding the angular library to the "helpers" entry in jasmine.json. But it didn't work. The documentation of this file is unfortunately very poor. In the Angular documentation and tutorials it is always mentioned to use Karma. But my understanding is that Karma is only useful for testing with browsers, since it spawns an own webserver. This does not make sense in my case.
Would be great if somebody could give me a hint, thanks!

Usage of spec.js file in AngularJS

This might sound a stupid question, but I want to know its answer. What is the spec.js file in AngularJS and what is its use? Is it used for testing purpose?
EDIT- Below is the code of file phone-detail.component.spec.js
'use strict';
describe('phoneDetail', function() {
// Load the module that contains the `phoneDetail` component before each test
beforeEach(module('phoneDetail'));
// Test the controller
describe('PhoneDetailController', function() {
var $httpBackend, ctrl;
var xyzPhoneData = {
name: 'phone xyz',
images: ['image/url1.png', 'image/url2.png']
};
beforeEach(inject(function($componentController, _$httpBackend_, $routeParams) {
$httpBackend = _$httpBackend_;
$httpBackend.expectGET('phones/xyz.json').respond(xyzPhoneData);
$routeParams.phoneId = 'xyz';
ctrl = $componentController('phoneDetail');
}));
it('should fetch the phone details', function() {
jasmine.addCustomEqualityTester(angular.equals);
expect(ctrl.phone).toEqual({});
$httpBackend.flush();
expect(ctrl.phone).toEqual(xyzPhoneData);
});
});
});
Use of spec.js is for writing you unit test cases for your angular application.
We write test cases in angular using Jasmine & Karma.
Jasmine is a Behavior Driven Development testing framework for JavaScript. It does not rely on browsers, DOM, or any JavaScript framework. Thus it's suited for websites, Node.js projects, or anywhere that JavaScript can run.
https://github.com/jasmine/jasmine
Karma is essentially a tool which spawns a web server that executes source code against test code for each of the browsers connected. The results of each test against each browser are examined and displayed via the command line to the developer such that they can see which browsers and tests passed or failed.
https://karma-runner.github.io/1.0/index.html
Question - What is the spec.js file in AngularJS ?
Answer - AngularJS uses Jasmine as a testing framework and tests written in Jasmine are called specs. Filename written related to Jasmine must be .spec.ts, the filename extension convention is adhered by configuration of
karma( the test runner tool ).
Question - what is its use? Is it used for testing purpose?
Answer - Karma the test runner gets the specifications for testing from this file. yes, it is used for testing :)
Reference https://angular.io/guide/testing

Sails + Angular + Jasmine

I use SailsJS for backend and Angular for front End. So far, they work well. SailsJS backend logic has tests in Mocha. I am trying to add some tests for front end Angular.
Angular's documentation on testing is cryptic to me. After reading its documentation for quite some time, I still have no idea about where to start.
1) Where should I put the unit test code for Angular in a SailsJS project? Now Angular code lives under assets/js. Should I put the test under the same directory, like the following?
assets/js/MyAngularCode.js
assets/js/MyAngularCode_test.js
MyAngularCode.js
(function(){
var myApp = angular.module('myApp', []);
myApp.controller('FirstController', [$scope, function($scope){
//blah blah
}]);
})();
What should I write in MyAngularCode_test.js to test any logic in FirstController?
2) How to run Jasmine tests for any given file directory structure in a SailsJS + Angular project?
How to make "Jasmine init" and "Jasmine" work in such a project. I assume need a Jasmine.json file. But where should it be?
3) For example, I have a file,
FirstTest.js
'use strict';
describe("A suite", function() {
beforeEach(angular.mock.module('myApp'));
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
Where should I put it and what should I do so it will not show the following error
ReferenceError: angular is not defined
Since you want just any opinion...
You can use yeoman for scaffolding; this will help you create pages and directory structure.
Use generator-angular since you are working with angular
yo angular:controller foobar will create files for your controller as well as the test files.
It will create a package.json with a test command (grunt test) which works out of the box.
There is a tutorial here: http://yeoman.io/codelab.html
Just clone this github repo, it's a blank app and uses Angular for the front-end https://github.com/sgress454/angular-on-sails

Cordova + Angular: How to test?

I've just recently started fooling around with Cordova for a mobile App. For now the code base is quite small. I've also used AngularJS to drive my javascript. Now that I have reached a stable state, I would like to investigate ways to unit test the code I just wrote. Thing is, I'm not finding any useful resource for the pair. Angular suggests either Karma (unit) or Protractor (scenarios), but I'm finding quite hard to bootstrap them both with a Cordova App, since this is not supposed to run inside the browser, but within some kind of container where cordova can be loaded. Are there already some good test-driven approaches in the open source market regarding test driven development of hybrid apps?
I think that correct approach would be to have cordova.mocks.js included in tests that will mock out cordova dependencies. And then unittest as usual.
I think there is no way at the moment to test the parts of cordova that would call functionality from plugins.
But you could use Karma or Protractor as you would in the browser (eventually with some mocks for cordova and cordova plugins), which require some additional if conditionals to run the app without a physical device
Ie if (window.cordova && cordova.plugins.thePluginExample) { /* Code that uses plugins [...] */ }
You can use "phonegap server" even if you're using cordova, also you can run on the device with cordova run <platform> --device.
You can track issues on the CLI output of both methods.
To help others who get here with the same question as I did...
You probably don't need to bootstrap with Cordova. Use mocks as stand-ins.
Since Cordova attaches to window, you can write your app code to inject $window and mock cordova with with standard mocking.
Example with mocha / chai:
/**
* Test case for AngularJS module that does something when platform = 'ios'
*/
describe('platform = "ios"', function() {
var $window;
beforeEach('inject', inject(function(_$window_) {
$window = _$window_;
$window.cordova = {
platformId: 'ios',
}
}));
it('verifies cordova mock platform = "ios"', function() {
expect($window.cordova.platformId).to.equal('ios');
});
it('does something', function() {
// ...
});
});

AngularJS + Testacular / Jasmine unit tests: Executed 0 of 0 SUCCESS

I am trying to write unit tests for an AngularJS project. The project is based on angular-seed and uses Testacular to run tests. Every attempt to run test.sh script always ends up with "Executed 0 of 0 SUCCESS".
I tried this super-simple "test":
describe('Testing Jasmine', function() {
console.log('describe');
var test = 'test';
it('should be test', function() {
console.log('it');
expect(test).toEqual('test');
});
});
The result is that only 'describe' is logged, the 'it' part is skipped. When I try the same thing on clean angular-seed clone everything works - so I assume that the testing system itself with Testacular and Jasmine is working correctly.
Our project is based on Rails, but the clean angular-seed that I was testing for comparison is running on Apache so I thought that this might be the difference - messed up paths or something in that Rails project.
But there are no error messages, e2e tests work... and also I assume that if some files were missing or paths were incorrect it would not be able to log that 'describe' in tests - if I understand correctly this means that Jasmine is processing the right file (there are no other dependencies in this pseudo-test). How is it possible that the 'describe' part works just fine and only 'it' part seems to be skipped?
Any hint or help would be appreciated.
If you are doing unit tests, do not include the angular-scenario.js file in your testacular config file. That will break the unit tests.
e2e testing in testacular has a long way to go. I struggled with this for a while. It turns out that the left side of an expect must be one of the methods defined in the angular documentation: http://docs.angularjs.org/guide/dev_guide.e2e-testing.
the following is an example
describe('Testing Jasmine', function() {
it('should be test', function() {
expect(element('foo').count()).toEqual(1);
});
});
Remember, if you dont enter in one of the prescribed method calls into the expect, testacular will not run the 'it'
Also make sure that you have one of these attributes used on page you are testing:
'ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'
Because if function angularInit() won't find element with one of these arguments runner won't start.
This is espcially important if you would like to use angular test runner on webage that does not have ng-app - with current version it just won't work.
Please check the order of the Javascript files.
A similar issue was reported in Testacular and reordering the js files fixed the problem.

Resources