ionic2
Test d'unité
Recherche…
Introduction
Les tests unitaires en général apportent une sécurité supplémentaire à un produit pour éviter des problèmes lors de la modification / ajout de fonctionnalités. Un filet de sécurité qui dit "TOUT FONCTIONNE ENCORE". Les tests unitaires ne remplacent en aucune manière les tests utilisateur réels qu'un AQ peut effectuer.
Dans ce document, nous baserons les exemples sur ce dépôt: https://github.com/driftyco/ionic-unit-testing-example
Tests unitaires avec Karma / Jasmine
Les tests unitaires en mode ionique sont les mêmes que dans toute application angulaire.
Nous utiliserons quelques frameworks pour cela.
Karma - un cadre pour l'exécution de tests
Jasmine - un cadre pour écrire des tests
PhantomJS - une application qui exécute javascript sans navigateur
Tout d'abord, tout installer, alors assurez-vous que votre package.json inclut ces lignes dans les dépendances de développement. Je pense qu'il est important de noter que les dépendances de développement n'affectent pas du tout votre application et sont juste là pour aider le développeur.
"@ionic/app-scripts": "1.1.4",
"@ionic/cli-build-ionic-angular": "0.0.3",
"@ionic/cli-plugin-cordova": "0.0.9",
"@types/jasmine": "^2.5.41",
"@types/node": "^7.0.8",
"angular2-template-loader": "^0.6.2",
"html-loader": "^0.4.5",
"jasmine": "^2.5.3",
"karma": "^1.5.0",
"karma-chrome-launcher": "^2.0.0",
"karma-jasmine": "^1.1.0",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.3",
"null-loader": "^0.1.1",
"ts-loader": "^2.0.3",
"typescript": "2.0.9"
Pour dépasser un peu les paquets
"angular2-template-loader": "^0.6.2", - will load and compile the angular2 html files.
"ts-loader": "^2.0.3", - will compile the actual typescript files
"null-loader": "^0.1.1", - will not load the assets that will be missing, such as fonts and images. We are testing, not image lurking.
Nous devrions également ajouter ce script à nos scripts package.json:
"test": "karma start ./test-config/karma.conf.js"
Notez également dans tsconfig que vous excluez les fichiers spec.ts de la compilation:
"exclude": [
"node_modules",
"src/**/*.spec.ts"
],
Ok, maintenant, prenons la configuration de test réelle. Créez un dossier test-config
dans votre dossier de projet. (Juste comme cela a été mentionné dans le script package.json) Dans le dossier, créez 3 fichiers:
webpack.test.js
- qui indiquera au Webpack les fichiers à charger pour le processus de test
var webpack = require('webpack');
var path = require('path');
module.exports = {
devtool: 'inline-source-map',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
loaders: [
{
loader: 'ts-loader'
} , 'angular2-template-loader'
]
},
{
test: /\.html$/,
loader: 'html-loader'
},
{
test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
loader: 'null-loader'
}
]
},
plugins: [
new webpack.ContextReplacementPlugin(
// The (\\|\/) piece accounts for path separators in *nix and Windows
/angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
root('./src'), // location of your src
{} // a map of your routes
)
]
};
function root(localPath) {
return path.resolve(__dirname, localPath);
}
karma-test-shim.js
- qui chargera les bibliothèques liées aux angles, telles que les bibliothèques de zones et de test, et configurera le module pour le test.
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
var appContext = require.context('../src', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
karma.conf.js
- définit la configuration du test avec le karma. Ici, vous pouvez passer de Chrome à PhantomJS pour rendre ce processus invisible et plus rapide, entre autres.
var webpackConfig = require('./webpack.test.js');
module.exports = function (config) {
var _config = {
basePath: '',
frameworks: ['jasmine'],
files: [
{pattern: './karma-test-shim.js', watched: true}
],
preprocessors: {
'./karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
browserConsoleLogOptions: {
level: 'log',
format: '%b %T: %m',
terminal: true
},
reporters: ['kjhtml', 'dots'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
};
config.set(_config);
};
Maintenant que nous avons configuré tout, nous allons écrire un test réel. Pour cet exemple, nous allons écrire un fichier de spécifications app.component. Si vous souhaitez voir des tests pour une page et non le composant principal, vous pouvez regarder ici: https://github.com/driftyco/ionic-unit-testing-example/blob/master/src/pages/page1/page1. spec.ts
Ce que nous devons faire d’abord, c’est tester notre constructeur. Cela va créer et exécuter le constructeur de notre app.component
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp],
imports: [
IonicModule.forRoot(MyApp)
],
providers: [
StatusBar,
SplashScreen
]
})
}));
La déclaration inclura notre application ionique principale. Les importations seront les importations nécessaires pour ce test. Pas tout.
Les fournisseurs incluront les éléments injectés dans le constructeur mais ne feront pas partie de l'importation. Par exemple, app.component injecte le service Platform, mais depuis qu'il fait partie de l'IonicModule, il n'est pas nécessaire de le mentionner dans les fournisseurs.
Pour les prochains tests, nous aurons besoin d'une instance de notre composant:
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
component = fixture.componentInstance;
});
Après quelques tests pour voir que tout est en ordre:
it ('should be created', () => {
expect(component instanceof MyApp).toBe(true);
});
it ('should have two pages', () => {
expect(component.pages.length).toBe(2);
});
Donc à la fin nous aurons quelque chose comme ça:
import { async, TestBed } from '@angular/core/testing';
import { IonicModule } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { MyApp } from './app.component';
describe('MyApp Component', () => {
let fixture;
let component;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp],
imports: [
IonicModule.forRoot(MyApp)
],
providers: [
StatusBar,
SplashScreen
]
})
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
component = fixture.componentInstance;
});
it ('should be created', () => {
expect(component instanceof MyApp).toBe(true);
});
it ('should have two pages', () => {
expect(component.pages.length).toBe(2);
});
});
Exécutez les tests par
npm run test
Et c'est à peu près tout pour les tests de base. Il y a plusieurs façons de raccourcir le test d'écriture, comme écrire votre propre TestBed et avoir l'héritage dans des tests qui pourraient vous aider à long terme.