Oktatóanyag: Egységtesztek hozzáadása Power BI-vizualizációs projektekhezTutorial: Add unit tests for Power BI visual projects

Ez a cikk a Power BI-vizualizációkhoz készült egységtesztek írásának alapjait ismerteti, köztük az alábbiakat:This article describes the basics of writing unit tests for your Power BI visuals, including how to:

  • A Karma JavaScript-tesztfuttatási keretrendszer, a Jasmine beállítása.Set up the Karma JavaScript test runner testing framework, Jasmine.
  • A powerbi-visuals-utils-testutils csomag használata.Use the powerbi-visuals-utils-testutils package.
  • Utánzatok és hamis elemek beállítása a Power BI-vizualizációk egységtesztelésének leegyszerűsítéséhez.Use mocks and fakes to help simplify unit testing of Power BI visuals.

ElőfeltételekPrerequisites

  • Telepített Power BI-vizualizációs projektAn installed Power BI visuals project
  • Konfigurált Node.js-környezetA configured Node.js environment

A Karma JavaScript-tesztfuttató és a Jasmine telepítése és konfigurálásaInstall and configure the Karma JavaScript test runner and Jasmine

Vegye fel a szükséges kódtárakat a package.json fájl devDependencies szakaszába:Add the required libraries to the package.json file in the devDependencies section:

"@babel/polyfill": "^7.2.5",
"@types/d3": "5.5.0",
"@types/jasmine": "2.5.37",
"@types/jasmine-jquery": "1.5.28",
"@types/jquery": "2.0.41",
"@types/karma": "3.0.0",
"@types/lodash-es": "4.17.1",
"coveralls": "3.0.2",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine": "2.5.2",
"jasmine-core": "2.5.2",
"jasmine-jquery": "2.1.1",
"jquery": "3.1.1",
"karma": "3.1.1",
"karma-chrome-launcher": "2.2.0",
"karma-coverage": "1.1.2",
"karma-coverage-istanbul-reporter": "^2.0.4",
"karma-jasmine": "2.0.1",
"karma-junit-reporter": "^1.2.0",
"karma-sourcemap-loader": "^0.3.7",
"karma-typescript": "^3.0.13",
"karma-typescript-preprocessor": "0.4.0",
"karma-webpack": "3.0.5",
"puppeteer": "1.17.0",
"style-loader": "0.23.1",
"ts-loader": "5.3.0",
"ts-node": "7.0.1",
"tslint": "^5.12.0",
"webpack": "4.26.0"

Ha többet szeretne megtudni a package.json ról, tekintse meg a leírást az npm-package.json helyen.To learn more about package.json, see the description at npm-package.json.

Mentse a package.json fájl, majd futtassa az alábbi parancsot a package.json-fájl helyén:Save the package.json file and, at the package.json location, run the following command:

npm install

A csomagkezelő telepíti a package.json fájlba felvett összes új csomagot.The package manager installs all new packages that are added to package.json.

Egységtesztek futtatásához konfigurálja a tesztfuttatót és a webpack konfigurációját.To run unit tests, configure the test runner and webpack config.

Az alábbi kód a test.webpack.config.js fájlra mutat egy példát:The following code is a sample of the test.webpack.config.js file:

const path = require('path');
const webpack = require("webpack");

module.exports = {
    devtool: 'source-map',
    mode: 'development',
    optimization : {
        concatenateModules: false,
        minimize: false
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: /\.tsx?$/i,
                enforce: 'post',
                include: /(src)/,
                exclude: /(node_modules|resources\/js\/vendor)/,
                loader: 'istanbul-instrumenter-loader',
                options: { esModules: true }
            },
            {
                test: /\.less$/,
                use: [
                    {
                        loader: 'style-loader'
                    },
                    {
                        loader: 'css-loader'
                    },
                    {
                        loader: 'less-loader',
                        options: {
                            paths: [path.resolve(__dirname, 'node_modules')]
                        }
                    }
                ]
            }
        ]
    },
    externals: {
        "powerbi-visuals-api": '{}'
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js', '.css']
    },
    output: {
        path: path.resolve(__dirname, ".tmp/test")
    },
    plugins: [
        new webpack.ProvidePlugin({
            'powerbi-visuals-api': null
        })
    ]
};

Az alábbi kód a karma.conf.ts fájlra mutat egy példát:The following code is a sample of the karma.conf.ts file:

"use strict";

const webpackConfig = require("./test.webpack.config.js");
const tsconfig = require("./test.tsconfig.json");
const path = require("path");

const testRecursivePath = "test/visualTest.ts";
const srcOriginalRecursivePath = "src/**/*.ts";
const coverageFolder = "coverage";

process.env.CHROME_BIN = require("puppeteer").executablePath();

import { Config, ConfigOptions } from "karma";

module.exports = (config: Config) => {
    config.set(<ConfigOptions>{
        mode: "development",
        browserNoActivityTimeout: 100000,
        browsers: ["ChromeHeadless"], // or Chrome to use locally installed Chrome browser
        colors: true,
        frameworks: ["jasmine"],
        reporters: [
            "progress",
            "junit",
            "coverage-istanbul"
        ],
        junitReporter: {
            outputDir: path.join(__dirname, coverageFolder),
            outputFile: "TESTS-report.xml",
            useBrowserName: false
        },
        singleRun: true,
        plugins: [
            "karma-coverage",
            "karma-typescript",
            "karma-webpack",
            "karma-jasmine",
            "karma-sourcemap-loader",
            "karma-chrome-launcher",
            "karma-junit-reporter",
            "karma-coverage-istanbul-reporter"
        ],
        files: [
            "node_modules/jquery/dist/jquery.min.js",
            "node_modules/jasmine-jquery/lib/jasmine-jquery.js",
            {
                pattern: './capabilities.json',
                watched: false,
                served: true,
                included: false
            },
            testRecursivePath,
            {
                pattern: srcOriginalRecursivePath,
                included: false,
                served: true
            }
        ],
        preprocessors: {
            [testRecursivePath]: ["webpack", "coverage"]
        },
        typescriptPreprocessor: {
            options: tsconfig.compilerOptions
        },
        coverageIstanbulReporter: {
            reports: ["html", "lcovonly", "text-summary", "cobertura"],
            dir: path.join(__dirname, coverageFolder),
            'report-config': {
                html: {
                    subdir: 'html-report'
                }
            },
            combineBrowserReports: true,
            fixWebpackSourcePaths: true,
            verbose: false
        },
        coverageReporter: {
            dir: path.join(__dirname, coverageFolder),
            reporters: [
                // reporters not supporting the `file` property
                { type: 'html', subdir: 'html-report' },
                { type: 'lcov', subdir: 'lcov' },
                // reporters supporting the `file` property, use `subdir` to directly
                // output them in the `dir` directory
                { type: 'cobertura', subdir: '.', file: 'cobertura-coverage.xml' },
                { type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt' },
                { type: 'text-summary', subdir: '.', file: 'text-summary.txt' },
            ]
        },
        mime: {
            "text/x-typescript": ["ts", "tsx"]
        },
        webpack: webpackConfig,
        webpackMiddleware: {
            stats: "errors-only"
        }
    });
};

Ezt a konfigurációt szükség esetén módosíthatja.If necessary, you can modify this configuration.

A karma.conf.js a következő változókat tartalmazza:The code in karma.conf.js contains the following variable:

  • recursivePathToTests: A teszt kódjának helyét adja megrecursivePathToTests: Locates the test code

  • srcRecursivePath: A JavaScript kimenet fordítás utáni helyét adja megsrcRecursivePath: Locates the output JavaScript code after compiling

  • srcCssRecursivePath: A CSS kimenet helyét adja meg stílusokat tartalmazó Less-fájlok fordítása utánsrcCssRecursivePath: Locates the output CSS after compiling less file with styles

  • srcOriginalRecursivePath: A vizualizáció forráskódjának helyét adja megsrcOriginalRecursivePath: Locates the source code of your visual

  • coverageFolder: Meghatározza, hogy a rendszer létrehozzon-e lefedettségi jelentéstcoverageFolder: Determines where the coverage report is to be created

A konfigurációs fájl az alábbi tulajdonságokat tartalmazza:The configuration file includes the following properties:

  • singleRun: true: A tesztek futhatnak folyamatos integrációs (CI) rendszeren, vagy egy alkalommal.singleRun: true: Tests are run on a continuous integration (CI) system, or they can be run one time. A tesztek hibakereséséhez a false értékre módosíthatja ezt a beállítást.You can change the setting to false for debugging your tests. A Karma futni hagyja a böngészőt, hogy használhassa a konzolt a hibakereséshez.Karma keeps the browser running so that you can use the console for debugging.

  • files: [...]: Ebben a tömbben a böngészőbe betöltendő fájlokat adhatja meg.files: [...]: In this array, you can specify the files to load to the browser. Itt általában forrásfájlok, tesztesetek és kódtárak (jasmine, tesztelési segédprogramok) találhatók.Usually, there are source files, test cases, libraries (Jasmine, test utilities). Igény szerint további fájlokat is felvehet a listára.You can add additional files to the list, as necessary.

  • preprocessors: Ebben a szakaszban az egységtesztek előtt futtatandó műveleteket konfigurálhatja.preprocessors: In this section, you configure actions that run before the unit tests run. Ezek előfordítják a TypeScriptet JavaScriptre, majd előkészítik a térképfájlokat, és egy kódlefedési jelentést hoznak létre.They precompile the typescript to JavaScript, prepare source map files, and generate code coverage report. A tesztek hibakeresése alatt a coverage letiltható.You can disable coverage when you debug your tests. A lefedettség további kódokat hoz létre a tesztlefedettséghez, ez pedig bonyolíthatja a hibakeresési teszteket.Coverage generates additional code for check code for the test coverage, which complicates debugging tests.

Az összes Karma-konfiguráció leírását megtalálhatja a Karma konfigurációs fájlját ismertető oldalon.For descriptions of all Karma configurations, go to the Karma Configuration File page.

A kényelem érdekében felvehet egy tesztelési parancsot a scripts szakaszba:For your convenience, you can add a test command into scripts:

{
    "scripts": {
        "pbiviz": "pbiviz",
        "start": "pbiviz start",
        "typings":"node node_modules/typings/dist/bin.js i",
        "lint": "tslint -r \"node_modules/tslint-microsoft-contrib\"  \"+(src|test)/**/*.ts\"",
        "pretest": "pbiviz package --resources --no-minify --no-pbiviz --no-plugin",
        "test": "karma start"
    }
    ...
}

Már minden készen áll az egységtesztek írásának megkezdéséhez.You're now ready to begin writing your unit tests.

A vizualizáció DOM-elemének ellenőrzéseCheck the DOM element of the visual

A vizualizáció teszteléséhez először hozza létre annak egy példányát.To test the visual, first create an instance of visual.

Vizualizációpéldány-készítő létrehozásaCreate a visual instance builder

A test könyvtárba vegyen fel egy visualBuilder.ts fájlt az alábbi kód használatával:Add a visualBuilder.ts file to the test folder by using the following code:

import {
    VisualBuilderBase
} from "powerbi-visuals-utils-testutils";

import {
    BarChart as VisualClass
} from "../src/visual";

import  powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;

export class BarChartBuilder extends VisualBuilderBase<VisualClass> {
    constructor(width: number, height: number) {
        super(width, height);
    }

    protected build(options: VisualConstructorOptions) {
        return new VisualClass(options);
    }

    public get mainElement() {
        return this.element.children("svg.barChart");
    }
}

A vizualizációpéldány létrehozásához használja a build metódust.There's build method for creating an instance of your visual. A mainElement egy GET metódus, amely a „root” dokumentum-objektummodell (DOM) elem egy példányát adja vissza a vizualizációban.mainElement is a get method, which returns an instance of "root" document object model (DOM) element in your visual. A beolvasó használata nem kötelező, de megkönnyíti az egységteszt írását.The getter is optional, but it makes writing the unit test easier.

Most már rendelkezik a vizualizáció egy példányának egy buildjével.You now have a build of an instance of your visual. Írjuk meg a tesztelési esetet.Let's write the test case. A teszteset a vizualizáció megjelenésekor létrehozott SVG-elemeket ellenőrzi.The test case checks the SVG elements that are created when your visual is displayed.

TypeScript-fájl létrehozása a tesztesetek írásáhozCreate a typescript file to write test cases

Vegyen fel egy visualTest.ts fájlt a tesztesetekhez az alábbi kód használatával:Add a visualTest.ts file for the test cases by using the following code:

import powerbi from "powerbi-visuals-api";

import { BarChartBuilder } from "./VisualBuilder";

import {
    BarChart as VisualClass
} from "../src/visual";

import VisualBuilder = powerbi.extensibility.visual.test.BarChartBuilder;

describe("BarChart", () => {
    let visualBuilder: VisualBuilder;
    let dataView: DataView;

    beforeEach(() => {
        visualBuilder = new VisualBuilder(500, 500);
    });

    it("root DOM element is created", () => {
        expect(visualBuilder.mainElement).toBeInDOM();
    });
});

Több metódus van meghívva:Several methods are called:

  • describe: A tesztesetet írja le.describe: Describes a test case. A Jasmine-keretrendszerben gyakran specifikációcsomagot vagy -csoportot ír le.In the context of the Jasmine framework, it often describes a suite or group of specs.

  • beforeEach: Az it metódus minden hívása előtt meg lesz hívva, amely a describe metódusban van definiálva.beforeEach: Is called before each call of the it method, which is defined in the describe method.

  • it: Egyetlen specifikációt definiál. Az it metódusnak egy vagy több expectations elemet kell tartalmaznia.it: Defines a single spec. The it method should contain one or more expectations.

  • expect: Egy specifikáció elvárásait hozza létre. A specifikáció akkor sikeres, ha minden elvárás hiba nélkül megvalósul.expect: Creates an expectation for a spec. A spec succeeds if all expectations pass without any failures.

  • toBeInDOM: Az egyeztetési metódusok egyike.toBeInDOM: One of the matchers methods. Az egyeztetőkről a Jasmin névtér: egyeztetők című cikkben olvashat.For more information about matchers, see Jasmine Namespace: matchers.

A Jasmine keretrendszerről a Jasmine keretrendszer dokumentációs oldalán talál további információt.For more information about Jasmine, see the Jasmine framework documentation page.

Egységtesztek elindításaLaunch unit tests

Ez a teszt ellenőrzi, létrejött-e a vizualizációk SVG-gyökéreleme.This test checks that root SVG element of the visuals is created. Az egységteszt futtatásához írja be az alábbi parancsot a parancssori eszközbe:To run the unit test, enter the following command in the command-line tool:

npm run test

A karma.js a Chrome böngészőben futtatja a tesztesetet.karma.js runs the test case in the Chrome browser.

A Chrome böngészőben futó Karma-JavaScript

Megjegyzés

A Google Chrome böngészőt helyileg kell telepítenie.You must install Google Chrome locally.

A parancssori ablakban a következő kimenet jelenik meg:In the command-line window, you'll get following output:

> karma start

23 05 2017 12:24:26.842:WARN [watcher]: Pattern "E:/WORKSPACE/PowerBI/PowerBI-visuals-sampleBarChart/data/*.csv" does not match any file.
23 05 2017 12:24:30.836:WARN [karma]: No captured browser, open https://localhost:9876/
23 05 2017 12:24:30.849:INFO [karma]: Karma v1.3.0 server started at https://localhost:9876/
23 05 2017 12:24:30.850:INFO [launcher]: Launching browser Chrome with unlimited concurrency
23 05 2017 12:24:31.059:INFO [launcher]: Starting browser Chrome
23 05 2017 12:24:33.160:INFO [Chrome 58.0.3029 (Windows 10 0.0.0)]: Connected on socket /#2meR6hjXFmsE_fjiAAAA with id 5875251
Chrome 58.0.3029 (Windows 10 0.0.0): Executed 1 of 1 SUCCESS (0.194 secs / 0.011 secs)

=============================== Coverage summary ===============================
Statements   : 27.43% ( 65/237 )
Branches     : 19.84% ( 25/126 )
Functions    : 43.86% ( 25/57 )
Lines        : 20.85% ( 44/211 )
================================================================================

Statikus adatok hozzáadása egységtesztekhezHow to add static data for unit tests

A test könyvtárban hozza lére a visualData.ts fájlt az alábbi kód használatával:Create the visualData.ts file in the test folder by using the following code:

import powerbi from "powerbi-visuals-api";
import DataView = powerbi.DataView;

import {
    testDataViewBuilder,
    getRandomNumbers
} from "powerbi-visuals-utils-testutils";

export class SampleBarChartDataBuilder extends TestDataViewBuilder {
    public static CategoryColumn: string = "category";
    public static MeasureColumn: string = "measure";

    public constructor() {
        super();
        ...
    }

    public getDataView(columnNames?: string[]): DataView {
        let dateView: any = this.createCategoricalDataViewBuilder([
            ...
        ],
        [
            ...
        ], columnNames).build();

        // there's client side computed maxValue
        let maxLocal = 0;
        this.valuesMeasure.forEach((item) => {
                if (item > maxLocal) {
                    maxLocal = item;
                }
        });
        (<any>dataView).categorical.values[0].maxLocal = maxLocal;
    }
}

A SampleBarChartDataBuilder osztály kiterjeszti a TestDataViewBuilder elemet, és implementálja a getDataView absztrakt metódust.The SampleBarChartDataBuilder class extends TestDataViewBuilder and implements the abstract method getDataView.

Amikor adatmezőgyűjtőkbe helyezi az adatokat, a Power BI egy kategorikus dataview objektumot hoz létre az adatok alapján.When you put data into data-field buckets, Power BI produces a categorical dataview object that's based on your data.

Adatmezőgyűjtők

Az egységtesztek során nem állnak rendelkezésére a Power BI alapvető funkciói az adatok reprodukálásához.In unit tests, you don't have Power BI core functions to reproduce the data. A statikus adatokat azonban le kell képeznie a kategorikus dataview elemekre.But you need to map your static data to the categorical dataview. A leképezésben a TestDataViewBuilder osztály segíthet.The TestDataViewBuilder class can help you map it.

Az adatnézet-leképezésről a DataViewMappings oldalon talál további információt.For more information about Data View mapping, see DataViewMappings.

A getDataView metódusban a createCategoricalDataViewBuilder metódust hívja meg az adatokkal.In the getDataView method, you call the createCategoricalDataViewBuilder method with your data.

A sampleBarChart vizualizáció capabilities.json fájljában dataRoles és dataViewMapping-objektumok találhatók:In sampleBarChart visual capabilities.json file, we have dataRoles and dataViewMapping objects:

"dataRoles": [
    {
        "displayName": "Category Data",
        "name": "category",
        "kind": "Grouping"
    },
    {
        "displayName": "Measure Data",
        "name": "measure",
        "kind": "Measure"
    }
],
"dataViewMappings": [
    {
        "conditions": [
            {
                "category": {
                    "max": 1
                },
                "measure": {
                    "max": 1
                }
            }
        ],
        "categorical": {
            "categories": {
                "for": {
                    "in": "category"
                }
            },
            "values": {
                "select": [
                    {
                        "bind": {
                            "to": "measure"
                        }
                    }
                ]
            }
        }
    }
],

Ugyanezen leképezés létrehozásához a következő paramétereket a createCategoricalDataViewBuilder metódusra kell beállítania:To generate the same mapping, you must set the following params to createCategoricalDataViewBuilder method:

([
    {
        source: {
            displayName: "Category",
            queryName: SampleBarChartData.ColumnCategory,
            type: ValueType.fromDescriptor({ text: true }),
            roles: {
                Category: true
            },
        },
        values: this.valuesCategory
    }
],
[
    {
        source: {
            displayName: "Measure",
            isMeasure: true,
            queryName: SampleBarChartData.MeasureColumn,
            type: ValueType.fromDescriptor({ numeric: true }),
            roles: {
                Measure: true
            },
        },
        values: this.valuesMeasure
    },
], columnNames)

Itt this.valuesCategory egy kategóriákból álló tömb:Where this.valuesCategory is an array of categories:

public valuesCategory: string[] = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];

A this.valuesMeasure viszont mértékekből álló tömb az egyes kategóriákhoz:And this.valuesMeasure is an array of measures for each category:

public valuesMeasure: number[] = [742731.43, 162066.43, 283085.78, 300263.49, 376074.57, 814724.34, 570921.34];

Most már felhasználhatja a SampleBarChartDataBuilder osztályt az egységtesztben.Now, you can use the SampleBarChartDataBuilder class in your unit test.

A ValueType osztály a powerbi-visuals-utils-testutils csomagban van definiálva.The ValueType class is defined in the powerbi-visuals-utils-testutils package. A createCategoricalDataViewBuilder metódushoz a lodash kódtár szükséges.And the createCategoricalDataViewBuilder method requires the lodash library.

Adja hozzá ezeket a csomagokat a függőségekhez.Add these packages to the dependencies.

A package.json fájlban, a devDependencies szakaszbanIn package.json at devDependencies section

"lodash-es": "4.17.1",
"powerbi-visuals-utils-testutils": "2.2.0"

CallCall

npm install

a lodash-es címtár telepítéséhez.to install lodash-es library.

Most már futtathatja újra az egységtesztet.Now, you can run the unit test again. Az alábbi kimenetet kell kapnia:You must get the following output:

> karma start

23 05 2017 16:19:54.318:WARN [watcher]: Pattern "E:/WORKSPACE/PowerBI/PowerBI-visuals-sampleBarChart/data/*.csv" does not match any file.
23 05 2017 16:19:58.333:WARN [karma]: No captured browser, open https://localhost:9876/
23 05 2017 16:19:58.346:INFO [karma]: Karma v1.3.0 server started at https://localhost:9876/
23 05 2017 16:19:58.346:INFO [launcher]: Launching browser Chrome with unlimited concurrency
23 05 2017 16:19:58.394:INFO [launcher]: Starting browser Chrome
23 05 2017 16:19:59.873:INFO [Chrome 58.0.3029 (Windows 10 0.0.0)]: Connected on socket /#NcNTAGH9hWfGMCuEAAAA with id 3551106
Chrome 58.0.3029 (Windows 10 0.0.0): Executed 1 of 1 SUCCESS (1.266 secs / 1.052 secs)

=============================== Coverage summary ===============================
Statements   : 56.72% ( 135/238 )
Branches     : 32.54% ( 41/126 )
Functions    : 66.67% ( 38/57 )
Lines        : 52.83% ( 112/212 )
================================================================================

A vizualizáció az alábbi ábrán látható módon megnyílik a Chrome böngészőben:Your visual opens in the Chrome browser, as shown:

UT-indítások a Chrome-ban

Az összegzés a lefedettség növekedését mutatja.The summary shows that coverage has increased. Az aktuális kódlefedettségről a következő helyen találhat további információkat: coverage\index.html.To learn more about current code coverage, open coverage\index.html.

UT-lefedettségi index

Megtekintheti az src könyvtár hatókörét is:Or look at the scope of the src folder:

Az scr könyvtár lefedettsége

A fájl hatókörében megtekintheti a forráskódot.In the scope of file, you can view the source code. A Coverage segédprogramok piros színnel emelik ki a sort, ha valamely kód nincs végrehajtva az egységteszt során.The Coverage utilities would highlight the row in red if certain code isn't executed during the unit tests.

A visual.ts fájl kódlefedettsége

Fontos

A kódlefedettség nem jelenti azt, hogy jó a vizualizáció funkciólefedettsége.Code coverage doesn't mean that you have good functionality coverage of the visual. Egy egyszerű egységteszt több, mint 96%os lefedettséget biztosít a src\visual.ts fájlban.One simple unit test provides over 96 percent coverage in src\visual.ts.

Következő lépésekNext steps

A kész vizualizációt beküldheti közzétételre.When your visual is ready, you can submit it for publication. További információ: Power BI-vizualizációk közzététele az AppSource-ban.For more information, see Publish Power BI visuals to AppSource.