ember.js unit testing and integration testing - ember.js

I am exploring ember.js application testing. I came across following blog by Toran Billups
Integration testing your ember.js app with QUnit and Karma
When we do karma start it runs all the test found in test directory.
How can I run say tests in only one .js file?
thanks

As #bk11425 suggested, simply modify the 'files' section in your karma.conf.js file from this
module.exports = function(karma) {
karma.set({
basePath: 'js',
files: [
"vendor/jquery/jquery.min.js",
"vendor/handlebars/handlebars.js",
"vendor/ember/ember.js",
"vendor/jquery-mockjax/jquery.mockjax.js",
"app.js",
"tests/*.js",
"templates/*.handlebars"
]
To something like this instead
module.exports = function(karma) {
karma.set({
basePath: 'js',
files: [
"vendor/jquery/jquery.min.js",
"vendor/handlebars/handlebars.js",
"vendor/ember/ember.js",
"vendor/jquery-mockjax/jquery.mockjax.js",
"app.js",
"tests/mytestfile.js",
"templates/*.handlebars"
]
Note- if you are doing integration testing please include the integration helper just above this single test file I showed above

To run the test from just one JS file, specify the file name in the "files" array of your karma config file.
Here's a sample config file I used recently. My example runs 2 js files for the test portion (the last 2 in the list), but you could easily just do one.
Bryan

Related

ignore file extension with Jest

I'm using webpack resolve.extensions to "selectively" bundle my js files.
eg.
App.js
import MyComp from 'comp/myComp';
in comp/ folder I have:
MyComp.web.js
MyComp.ios.js
MyComp.android.js
Now I want to write test for App.js, to test how it render as web. But the problem is Jest keep resolving all 3 .js files and that causes dependency error because I'm not running the command in a mobile environment and most mobile modules will not work.
how can I tell jest to only resolve .js and .web.js files just like webpack?
I added this to my package.json and it keep resolving .ios.js and .android.js
"moduleFileExtensions": ["web.js", "js", "jsx"],
"moduleDirectories": [
"node_modules",
"main"]
I tried as suggested with:
"testPathIgnorePatterns": ["<rootDir>/node_modules/", "^.+\\.(android|ios)\\.js$"],
looks no effects :(
You can also remap files to an empty file
touch empty.js
In your jest config add following
moduleNameMapper: {
'\\.(css|jpg|png|scss|less|sass)$': '<rootDir>/empty.js',
},
Works perfect for me
You can add testPathIgnorePatterns to your package.json file. The value is an array of regex patterns. Any file/path that matches an expression will be ignored/skipped from testing.
See these Jest docs for more detail

Unit testing with Webpack, Jasmine (-core), typescript

I have a project that is using webpack to bundle all code into a single file. The project is using Typescript and it is working fine at the moment.
I've gone to add unit testing and jasmine seems to be the way (one of the many ways) forward. Its actually jasmine-core that is included in the package.json - not sure how much of a difference that makes.
So running a very simple test such as
it('true is true', function(){ expect(true).toEqual(true); });
works fine.
But when I add tests that require the use of an import - eg
import MyService = require('./MyServices');
then when I run the tests it complains as it doesn't know what 'require' is.
Uncaught ReferenceError: require is not defined
Now I'm guessing this is because I need to package up the test module in a similar way that I package up the main project.
So what is the best way to do this?
Should I have multiple entry points in the webpack.config.js file - one for each *.spec.ts file?
Or is there a way to have say accept an unknown number of spec files
entry:[ *.spec.ts ] and have it output a js file for each one - *.spec.js
You can use karma/karma-webpack to run all the tests using webpack for resolving the imports. You can take a look at this repository for a simple configuration.
You can also specify an index.spec.ts as en entry point and make this file require all the spec files if you don't want to make one entry point for each spec.ts in your webpack's configuration file.

Karma error: require is not defined

I use karma with qunit for test an emberjs application. The karma.conf.js file have this piece of code for link my project libraries
files: [
"app/bower_components/jquery/jquery.js",
"app/bower_components/mockjax/jquery.mockjax.js",
"app/bower_components/handlebars/handlebars.js",
"app/bower_components/ember/ember.js",
"app/bower_components/ember-data/ember-data.js",
"app/bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap.js",
"app/scripts/app.js",
"tests/test.js"
],
and my app.js is this:
var MyApp = window.MyApp = Ember.Application.create();
require('scripts/controllers/*');
require('scripts/store');
require('scripts/models/*');
require('scripts/routes/*');
require('scripts/components/*');
require('scripts/views/*');
require('scripts/router');
but when i start karma with the config file, it report this error
Firefox 30.0.0 (Ubuntu) ERROR
ReferenceError: require is not defined at ~/myApp/app/scripts/app.js:4
I've tried to change the order of the libraries in the karma.conf file but doesn't work.
Try installing requirejs and including it in the files section of karma.conf.js.
npm install requirejs
Running this command will create a node_modules folder, if one doesn't already exist. RequireJS will be probably be in:
node_modules/requirejs/require.js
So, you can try editing your files section like this:
files: [
"node_modules/requirejs/require.js",
...
]

grunt-karma not running the spec file when using shared config

I created a basic project to try and get Gruntjs, Karma and Jasmine to play together. When I setup the karma.conf.js file with all of the neccesary files, everything works and the tests pass.
When I try to split them up in Grunt though, I get problems.
Gruntfile.js
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
karma: {
options: {
configFile: 'karma.conf.js'
},
basicController: {
files: ['/basicController/scBasicControllerCtrl.js', '/basicController/test/ControllersSpec.js']
},
overworkedController: {
src: ['overworkedController/scOverworkedControllerCtrl.js', 'overworkedController/test/ControllersSpec.js']
}
}
});
The documentation at grunt-karma show to use "files:" when splitting up the modules. I did that under the basicController module and when I try to run $ grunt karma:basicController --verbose, I get an error saying
Warning: Cannot use 'in' operator to search for 'src' in /basicController/scBasicControllerCtrl.js Use --force to continue
Aborted due to warnings.
When I run $ grunt karma:overworkedControllers --verbose (using "src" instead of "files", it looks like everything is going to work and the Chrome browser launches but then is says it executed 0 of 0 ERROR.
There should be 3 tests.
Let me know if there's any more info I could post.
My understanding of grunt-karma was incorrect.
I thought I could have the base and source files in the karma.conf.js file. Then in each module, I'd just add the specific files needed for that module and test.
The way it actually works is that the files declared in each module completely overwrite the files property in the karma.conf.js file. Not append to them.
I ended up creating an array in Gruntfile.js that contains all of the source .js files and just concat the necessary files to it in each module.

Testing a non-trivial AngularJS app with Jasmine & Karma

I'm working on a non-trivial application, with the following folder structure:
build (required files such as angular.js)
Gruntfile.js
karma.conf.js
logs/
node_modules/
src/
- app/
- app.js
- module_name/
- module.js
- controllers/
- controller1.js
- controller2.js
- views/
- view1.html
- assets/
- 1.jpg
- styler.css
- components/ (plugged in modules [angular-ui, etc])
- index.html
My controllers are each attached to their parent module. That module is then required in my app.js file.
I have tried writing some unit tests, but I seem to keep having trouble with dependancies, since the controller I try to test requires it's module, then that module requires another one, etc.
My question has a few parts:
How do I go about structuring my karma.conf.js file to include the necessary files?
Specifically this part of the configuration:
files: [
'files_to_be_tested.js',
]
Using Jasmine, how do I write up a unit test with all the proper dependancies? As an example, I run the following test
Javascript
using 'strict'
describe('my Module', function() {
describe('myController', function() {
var ctrl, scope;
beforeEach(module('myModule'));
beforeEach(inject(function ($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('myController', { $scope: scope });
}));
it('should work', function() {
// Execute functionality
})
})
})
but I keep getting the error: Unknown provider: $stateProvider, which I think is coming from the loaded module's route configuration.
I'm beginning to wonder whether I've been separating out my controllers properly?
To answer the second question:
Unknown provider: $stateProvider is caused by the ui.router module not being loaded. To solve the problem, add beforeEach(module('ui.router'))
The problem arises because the controller you are loading is trying to inject $state
Make sure that the ui.router Javascript file is in the files list in karma.conf.js or the module will not be available to karma.
Here is the answer to your first question. Configuring the files section;
// list of files / patterns to load in the browser
files = [
JASMINE,
JASMINE_ADAPTER,
'components/angular/angular.js', //path to your angular.js file
'components/angular-mocks/angular-mocks.js',//path to your angular-mocks.js file
'components/angular-resource/angular-resource.js',//path to your angular-resource.js file
'app/*.js',
'app/**/*.js',
'test/mock/**/*.js',
'test/spec/**/*.js'
];
Try this change in your karma.conf.js and carry out your test. Hope it helps.
Same files/patterns as your application, in the same order, then angular-mock, then your specs.
If you're loading a module, it should be already loaded with all its dependent modules. Since you're missing a provider and your example is calling only a controller, it could be missing from the injected controller dependencies in $controller('myController', { $scope: scope });.