hornet-js-test
v5.5.0-rc.4
Published
Ensemble des composants pour les tests hornet-js
Downloads
4
Readme
hornet-js-test
Projet d'externalisation des outils de test de Hornet.js
Prérequis
- NodeJS 10.X
Utilisation dans un projet
Ajouter au package.json
"devDependencies": {
"hornet-js-test": "5.5.X"
}
Puis lancer la commande :
npm install
Tests unitaires Karma
Outils
[chai](http://chaijs.com/)
: Bibliothèque d'assertions pour Node[mocha](http://mochajs.org/)
: Framework de tests JavaScript[sinonJS](http://sinonjs.org/)
: Framework de bouchonnages de fonctions[Karma](https://github.com/karma-runner/karma)
: Framework de test Javascript dans des navigateurs
How-To
Création d'un test basique
Pour créer un test, il faut créer une classe qui hérite de BaseTest dans le répertoire de test du projet.
L'api de test repose sur les décorateurs suivants:
-@Decorators.describe
: permet de donner un nom à la classe de test
-@Decorators.it
: permet de définir un bloc de test
-@Decorators.xit
: permet d'ignorer un bloc de test
-@Decorators.before
: permet de définir un bloc de test qui sera exécuté avant tous les tests de la classe
-@Decorators.after
: permet de définir un bloc de test qui sera exécuté après tous les tests de la classe
-@Decorators.beforeEach
: permet de definir un bloc de test qui sera exécuté avant chaque test de la classe.
et sur la fonction runTest() qui permet de lancer le test.
import { BaseTest } from "hornet-js-test/src/test/abstract-test";
import { Decorators } from "hornet-js-test/src/decorators";
import { runTest } from "hornet-js-test/src/test-run";
import * as assert from "assert";
@Decorators.describe('Dummy Test')
class dummyTest extends BaseTest {
@Decorators.it('Test OK')
testOk() {
assert.equal(1, 1);
this.end();
};
};
//lancement du test
runTest(new dummyTest());
Si vous souhaitez lancer le test karma via le builder hornet, voici la commande:
hb test:karma --file test/dummy-spec.karma.tsx
la classe BaseTest
La classe BaseTest propose 3 méthodes utiles au développeur:
-end()
: La méthode end permet de préciser la fin logique du test. Cette méthode est très importante
car elle précise au framework de test que tous les traitements qu'on souhaite ont été lancés.
-renderIntoDocument(composantReact, id de la div)
: Fonction à appeler pour insérer un element dans le DOM (une div). Si l'id n'existe pas, alors on crée une nouvelle div.
-triggerMouseEvent(elementHtml, type de l'evènement)
: Fonction qui permet de lancer des évènements du dom
exemple d'une classe testant le click sur un button
import { BaseTest } from "hornet-js-core/src/test/abstract-test";
import { Decorators } from "hornet-js-test/src/decorators";
import { runTest } from "hornet-js-test/src/test-run";
import * as React from "react";
import * as assert from "assert";
import {Button} from "hornet-js-react-components/src/widget/button/button";
@Decorators.describe('click Test')
class clickTest extends BaseTest {
@Decorators.it('Test click bouton')
testClick() {
let _onClick = (event){
assert.equal(event.target.id, "test1")
this.end();
}
let element: JSX.Element = (
<Button id="test" onClick={_onClick}/>
)
this.renderIntoDocument(element, "main_button_click");
this.triggerMouseEvent(document.querySelector("#main_button_click button"), "click");
};
};
//lancement du test
runTest(new clickTest());
exemple d'une classe testant un composant avec un datasource
import { Logger } from "hornet-js-logger/src/logger";
import { TestLogger } from "hornet-js-test/src/test-logger";
Logger.prototype.buildLogger = TestLogger.getLoggerBuilder({
"appenders": {
"console": {
"type": "console",
"layout": {
"type": "pattern",
"pattern": "%[%d{ISO8601}|%p|%c|%m%]"
}
}
},
"categories": {
"default": { "appenders": ["console"], "level": "INFO" }
}
});
import { Utils } from "hornet-js-utils";
Utils.setConfigObj({
// ADD config for test
});
var chai = require('chai');
const expect = chai.expect;
import * as _ from "lodash";
import * as React from "react";
import { BaseTest } from "hornet-js-core/src/test/abstract-test";
import { runTest } from "hornet-js-test/src/test-run";
import { Decorators } from "hornet-js-test/src/decorators";
import * as assert from "assert";
import { DataSource } from "hornet-js-core/src/component/datasource/datasource";
import { Table } from "hornet-js-react-components/src/widget/table/table";
import { Header } from "hornet-js-react-components/src/widget/table/header";
/* Composant Content */
import { Content } from "hornet-js-react-components/src/widget/table/content";
/* Colonne du tableau */
import { Column } from "hornet-js-react-components/src/widget/table/column";
import { Columns } from "hornet-js-react-components/src/widget/table/columns";
import { CheckColumn } from "src/widget/table/column/check-column";
/** Tableau de liste de secteurs */
let dataSource: DataSource<any>;
let tableElement: JSX.Element;
let table;
let data;
@Decorators.describe('Test Karma table')
class tableTest extends BaseTest {
@Decorators.beforeEach
beforeEach() {
data = [];
for (let i: number = 1; i < 50; i++) {
data.push({ id: i, label: "libelle" + i });
}
dataSource = new DataSource(data);
tableElement = (
<Table id="lite">
<Header title={"Secteurs"}>
</Header>
<Content dataSource={dataSource}>
<Columns>
<CheckColumn keyColumn="id" />
<Column keyColumn="label" title={"libelle"} sortable={false} />
</Columns>
</Content>
</Table>
);
};
@Decorators.it('selectionner un element dans le tableau')
selectionUnElement() {
table = this.renderIntoDocument(tableElement, "main1");
dataSource.on("loadingData", () => {
let item2 = document.querySelector("#main1 #lite-0-colBody-1-0 input");
this.triggerMouseEvent(item2, "click");
});
dataSource.on("select", () => {
expect(_.isEqual(dataSource.selected[ 0 ], { id: 2, label: "libelle2" })).to.be.true;
this.end();
});
};
}
//lancement des Tests
runTest(new tableTest());
Couverture de test
Outils
La couverture de code se base sur les tests unitaires effectués sur les composants JavaScript, TypeScript et JSX (React).
- istanbul : Framework de calcul de couverture de code
How-To
- Se positionner dans le module souhaité, ou dans le module parent pour obtenir la couverture complète.
- Lancer la commande
hb test
Cette commande peut également être jouée pour tous les modules du framework et produira un rapport pour chaque module.
Cette commande lance les tests développés précédemment et produit un rapport de couverture comme suit :
--------------------------------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
--------------------------------------|----------|----------|----------|----------|----------------|
src\ | 78.13 | 46.67 | 100 | 82.14 | |
hornet-component.js | 78.13 | 46.67 | 100 | 82.14 | 31,32,33,36,38 |
src\auto-complete\ | 53.88 | 20.2 | 48.72 | 53.66 | |
auto-complete-field.js | 100 | 100 | 100 | 100 | |
auto-complete-selector.js | 91.67 | 100 | 71.43 | 91.43 | 26,43,44 |
auto-complete-widget.js | 81.48 | 50 | 66.67 | 81.48 | 17,48,50,76,78 |
auto-complete.js | 33.59 | 16.13 | 36 | 33.59 |... 384,391,392 |
src\button\ | 90.91 | 63.64 | 85.71 | 92.59 | |
button-props.js | 100 | 100 | 100 | 100 | |
button.js | 90.91 | 63.64 | 85.71 | 92.59 | 25,26 |
src\calendar\ | 64.46 | 55.81 | 42.11 | 64.46 | |
calendar.js | 43.82 | 33.33 | 23.08 | 43.82 |... 240,244,245 |
date-picker-field.js | 91.67 | 81.82 | 100 | 91.67 | 34,40,45,78 |
date-picker-input.js | 82.76 | 63.64 | 66.67 | 82.76 | 39,40,41,42,45 |
src\chart\ | 26.97 | 0 | 6.52 | 27.15 | |
chart-donut.js | 26.97 | 0 | 6.52 | 27.15 |... 298,305,313 |
src\dialog\ | 55.24 | 29.44 | 37.5 | 53.96 | |
alert-props.js | 100 | 100 | 100 | 100 | |
alert.js | 78.26 | 40.54 | 33.33 | 77.5 |... 70,78,86,94 |
modal-props.js | 100 | 100 | 100 | 100 | |
modal.js | 98.15 | 62.22 | 90.91 | 100 | |
react-aria-modal.js | 37.1 | 13.04 | 21.21 | 36.16 |... 247,248,253 |
src\form\ | 52.13 | 33.96 | 57.14 | 52.13 | |
form.js | 52.17 | 35.48 | 47.06 | 52.17 |... 184,292,293 |
grid-form.js | 54.03 | 35.83 | 72.73 | 54.03 |... 397,415,448 |
read-only-widget.js | 38.89 | 0 | 0 | 38.89 |... 29,30,31,34 |
src\icon\ | 81.58 | 60 | 85.71 | 81.25 | |
icon-props.js | 100 | 100 | 100 | 100 | |
icon.js | 81.58 | 60 | 85.71 | 81.25 |... 31,34,37,38 |
src\navigation\ | 65.99 | 53.68 | 65.31 | 65.99 | |
bread-crumb-item.js | 100 | 93.75 | 100 | 100 | |
bread-crumb.js | 91.49 | 100 | 66.67 | 91.49 | 57,61,65,66 |
menu-constantes.js | 100 | 100 | 100 | 100 | |
menu-infos-complementaires.js | 100 | 100 | 100 | 100 | |
menu-link.js | 80 | 68.75 | 44.44 | 80 |... 66,67,69,91 |
menu-navigation.js | 30.56 | 18.07 | 40 | 30.56 |... 399,400,401 |
menu.js | 97.5 | 80.77 | 100 | 97.5 | 107 |
plan.js | 94.29 | 78.95 | 100 | 94.29 | 75,81 |
src\navigation\store\ | 71.43 | 71.43 | 37.5 | 68 | |
navigation-base-store.js | 71.43 | 71.43 | 37.5 | 68 |... 23,30,31,32 |
src\navigation\utils\ | 76.32 | 25 | 57.14 | 76.32 | |
navigation-utils.js | 76.32 | 25 | 57.14 | 76.32 |... 67,70,78,80 |
src\notification\ | 78.95 | 60.92 | 68.97 | 78.43 | |
notification-message-item.js | 77.27 | 56.41 | 77.78 | 76.32 |... 30,31,34,42 |
notification-props.js | 100 | 100 | 100 | 100 | |
notification.js | 80 | 64.58 | 65 | 79.69 |... 86,87,89,93 |
src\spinner\ | 93.65 | 71.11 | 76.92 | 94.74 | |
spinner-props.js | 100 | 100 | 100 | 100 | |
spinner.js | 93.65 | 71.11 | 76.92 | 94.74 | 76,84,92 |
src\tab\ | 94.74 | 64.06 | 85 | 97.56 | |
tab-props.js | 100 | 100 | 100 | 100 | |
tab.js | 97.22 | 57.58 | 100 | 100 | |
tabs.js | 93.22 | 70.97 | 76.92 | 96.15 | 28,66 |
src\table\ | 62.9 | 47.17 | 56.93 | 62.9 | |
table-caption.js | 75 | 50 | 50 | 75 | 17,18,35,36 |
table-content.js | 85.71 | 100 | 100 | 85.71 | 59,60 |
table-filters.js | 44.12 | 21.43 | 22.73 | 44.12 |... 317,321,325 |
table-header-column.js | 84.62 | 67.27 | 66.67 | 84.62 |... 140,178,183 |
table-header-mass.js | 65.22 | 33.33 | 62.5 | 65.22 |... 125,126,127 |
table-header.js | 88.24 | 100 | 100 | 88.24 | 94,95 |
table-row.js | 67.35 | 52.94 | 63.64 | 67.35 |... 140,181,182 |
table-rows.js | 75.86 | 68.42 | 80 | 75.86 |... 62,63,94,95 |
table-title.js | 71.43 | 20 | 66.67 | 71.43 | 30,31,49,50 |
table-tools-action-add.js | 78.26 | 62.5 | 83.33 | 78.26 |62,63,74,75,100 |
table-tools-action-export-button.js | 32 | 0 | 16.67 | 32 |... 107,112,113 |
table-tools-action-export.js | 66.67 | 12.5 | 42.86 | 66.67 |... 84,89,93,97 |
table-tools-action-filter.js | 67.5 | 30.43 | 55.56 | 67.5 |... 127,131,135 |
table-tools-action-mass.js | 78.95 | 75 | 83.33 | 78.95 | 58,59,71,72 |
table-tools-action-pagination.js | 62.5 | 55.32 | 69.23 | 62.5 |... 269,271,273 |
table-tools-bottom.js | 86.67 | 100 | 100 | 86.67 | 72,73 |
table-tools-top.js | 87.5 | 100 | 100 | 87.5 | 76,77 |
table.js | 46.92 | 50 | 57.69 | 46.92 |... 571,573,575 |
src\table\actions\ | 49.18 | 23.81 | 50 | 46.55 | |
table-actions.js | 49.18 | 23.81 | 50 | 46.55 |... 79,83,85,88 |
src\table\store\ | 85.12 | 75.68 | 81.82 | 84.75 | |
table-store-data.js | 72.73 | 100 | 66.67 | 72.73 |... 15,22,23,24 |
table-store-interface.js | 100 | 100 | 100 | 100 | |
table-store.js | 87.88 | 75.68 | 87.5 | 87.5 |... 110,113,114 |
src\tool-tip\ | 96.88 | 51.61 | 100 | 100 | |
tool-tip-props.js | 100 | 100 | 100 | 100 | |
tool-tip.js | 96.88 | 51.61 | 100 | 100 | |
src\upload-file\ | 51.9 | 18.37 | 50 | 51.9 | |
upload-file-field.js | 48.28 | 9.52 | 33.33 | 48.28 |... 48,50,51,56 |
upload-file-widget.js | 54 | 25 | 57.14 | 54 |... 108,117,120 |
--------------------------------------|----------|----------|----------|----------|----------------|
All files | 63.36 | 44.14 | 54.49 | 62.87 | |
--------------------------------------|----------|----------|----------|----------|----------------|
Un rapport au format HTML est accessible sous target/istanbul/reports/**.
Installation
Ajouter la définition dans le fichier package.json
du projet en plus de l'import du module hornet-js-test
:
"devDependencies": {
"hornet-js-test": "5.5.X"
}
Licence
hornet-js-test
est sous licence cecill 2.1.
Site web : http://www.cecill.info