Como testear una app con Ionic3

Como testear una app con Ionic3

Normalmente, todo el mundo suele realizar pruebas en su app de una u otra manera, aquí te enseñaré cómo configurar y ejecutar tests unitarios en nuestra app Ionic3. Para la mayoría esto significa hacer pruebas en múltiples dispositivos y, en muchas ocasiones, realizando manualmente algunas partes de las funcionalidades. Sin embargo, este proceso es de prueba y error, eso significa invertir mucho tiempo y puede que olvidemos algo por hacer.

Los tests unitarios son aquellos que se realizan sobre partes muy pequeñas de nuestro código, normalmente sobre un método.  De esta manera se puede hacer una prueba sobre de funcionalidad sin tener que esperar a que se ejecute la aplicación en un dispositivo, simplemente debes ejecutar los tests y esperar al resultado para saber si lo que has programado es correcto.

Ahora no os explicaré cómo hacer correctamente tests unitarios, sino cómo configurarlos para que funcionen en nuestra aplicación Ionic3. Los pasos son los siguientes:

1) Crear la estructura básica de la aplicación.

Lo primero que haremos será un update Ionic a la última versión.

$ npm update -g ionic

Y una vez tenemos Ionic a la última versión preparar una aplicación nueva de Ionic3.

$ ionic start ionic3-unit-test blank

2) Instalar todos los plugins necesarios para poder ejecutar los tests.

$ npm install karma --save-dev
$ npm install karma-cli --save-dev
$ npm install jasmine-core --save-dev
$ npm install jasmine-spec-reporter --save-dev
$ npm install karma-jasmine --save-dev
$ npm install karma-jasmine-html-reporter --save-dev
$ npm install karma-chrome-launcher --save-dev
$ npm install karma-coverage-instambul-reporter --save-dev
$ npm install @angular/cli --save-dev
$ npm install @types/jasmine --save-dev
$ npm install @types/node --save-dev
$ npm install ts-loader --save-dev
$ npm install angular2-template-loader --save-dev
$ npm install html-loader --save-dev

3) Crear los archivos de configuración de karma.

a) test-config/karma.conf.js

var webpackConfig = require('./webpack.test.js');

module.exports = function (config) {
  var _config = {
    basePath: '',

    frameworks: ['jasmine'],
      plugins: [
          require('karma-jasmine'),
          require('karma-chrome-launcher'),
          require('karma-jasmine-html-reporter'),
          require('@angular/cli/plugins/karma')
      ],

    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);
};

b) test-config/karma-test-shim.js

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());

c) test-config/webpack.test.js

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);
}

4) Crear el primer test de nuestra app.component.ts. Creamos un archivo src/app/app.component.spec.ts. Este test sirve para comprobar que nuestra app está creada.

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);
  });
});

5) Modificamos el fichero «package.json» para poder ejecutar los tests con el npm. Para eso necesitaremos añadir esta opción en scripts.

"test": "karma start ./test-config/karma.conf.js --single-run"

6) Una vez hecho esto, ya podemos ejecutar nuestros test.

a) Ejecutar los tests por el terminal

$ npm test

Una vez ejecutada la orden en el terminal, nos mostrará el siguiente mensaje «Executed 1 of 1 SUCCESS» en el terminal. Esto significa que los test han pasado correctamente.

b) Ejecutar los tests con intelliJ

  • Primero se debe instalar el plugin de karma.
  • Una vez tenemos el plugin instalado, debes ir a “Run / Debug configuration” y añadir una nueva configuración del plugin de Karma.
  • En la configuración se ponen las siguientes opciones:
    1. Configuration file: En el desplegable seleccionamos «karma-conf.js».
    2. Node interpreter: En el desplegable seleccionamos la versión de node más nueva.
    3. Karma package: En el desplegable seleccionamos «karma del node_modules».
  • Pulsamos en «Apply» y confirmar con «Ok»
  • Seleccionamos la configuración recientemente creada y apretamos en «Run» esto sirve para ejecutar los tests.
  • Si quieres hacer debug en los tests, tendrás que instalar el siguiente plugin en Chrome
  • Cuando lo tengas solamente deberás pulsar en «Debug» en lugar de «Run».

¡Ahora si! Ya podemos probar nuestra app. Espero que os haya gustado este tutorial y os sea de utilidad.

Podéis encontrar todo el código en mi repositorio en Github