ionic2
Testen van een eenheid
Zoeken…
Invoering
Unit-testing geeft in het algemeen extra veiligheid aan een product om problemen te voorkomen bij het wijzigen / toevoegen van functies. Een vangnet dat zegt "ALLES NOG WERKT". Eenheidstests vervangen op geen enkele manier de daadwerkelijke gebruikerstests die een goede QA kan doen.
In dit document baseren we de voorbeelden op deze repository: https://github.com/driftyco/ionic-unit-testing-example
Eenheidstests met karma / jasmijn
Het testen van eenheden in ionen is hetzelfde als in elke hoekapp.
We zullen een paar frameworks gebruiken om dit te doen.
Karma - een raamwerk voor het uitvoeren van tests
Jasmine - een kader voor het schrijven van tests
PhantomJS - een applicatie die JavaScript zonder browser uitvoert
Laten we eerst alles installeren, dus zorg ervoor dat uw package.json deze regels in de dev-afhankelijkheden opneemt. Ik vind het belangrijk op te merken dat dev-afhankelijkheden helemaal geen invloed hebben op je app en er alleen zijn om de ontwikkelaar te helpen.
"@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"
Om een beetje over pakketten te gaan
"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.
We moeten dit script ook toevoegen aan onze package.json-scripts:
"test": "karma start ./test-config/karma.conf.js"
Merk ook op in tsconfig dat u de spec.ts-bestanden uitsluit van compilatie:
"exclude": [
"node_modules",
"src/**/*.spec.ts"
],
Ok, laten we nu de werkelijke testconfiguratie nemen. Maak een test-config
in uw projectmap. (Net zoals het werd vermeld in het script package.json) Maak in de map 3 bestanden:
webpack.test.js
- die de webpack vertelt welke bestanden moeten worden geladen voor het testproces
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
- die de karma-test-shim.js
bibliotheken, zoals zone- en karma-test-shim.js
, laadt en de te configureren module configureert.
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
- definieert de configuratie van hoe te testen met karma. Hier kunt u overschakelen van Chrome naar PhantomJS om dit proces onder andere onzichtbaar en sneller te maken.
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);
};
Nu we alles hebben geconfigureerd, kunnen we een echte test schrijven. Voor dit voorbeeld zullen we een app.component spec-bestand schrijven. Als u tests voor een pagina wilt zien en niet het hoofdonderdeel, kunt u hier kijken: https://github.com/driftyco/ionic-unit-testing-example/blob/master/src/pages/page1/page1. spec.ts
Wat we eerst moeten doen, is onze constructeur testen. Hiermee wordt de constructor van onze app.component gemaakt en uitgevoerd
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyApp],
imports: [
IonicModule.forRoot(MyApp)
],
providers: [
StatusBar,
SplashScreen
]
})
}));
De verklaring bevat onze belangrijkste ionische app. De invoer is de invoer die nodig is voor deze test. Niet alles.
De providers zullen de dingen opnemen die in de constructor zijn geïnjecteerd maar geen deel uitmaken van de import. Bijvoorbeeld, de app.component injecteert de Platform-service, maar omdat het een onderdeel is van de IonicModule, is het niet nodig om het in de providers te vermelden.
Voor de volgende tests moeten we een exemplaar van onze component krijgen:
beforeEach(() => {
fixture = TestBed.createComponent(MyApp);
component = fixture.componentInstance;
});
Vervolgens een paar tests om te zien dat alles in orde is:
it ('should be created', () => {
expect(component instanceof MyApp).toBe(true);
});
it ('should have two pages', () => {
expect(component.pages.length).toBe(2);
});
Dus uiteindelijk zullen we zoiets als dit hebben:
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);
});
});
Voer de tests uit door
npm run test
En dat is het ongeveer voor de basistests. Er zijn een paar manieren om het schrijven van de test te verkorten, zoals het schrijven van uw eigen TestBed en het overnemen van tests die u op de lange termijn kunnen helpen.