Öğretici: Power BI görsel projeleri için birim testleri eklemeTutorial: Add unit tests for Power BI visual projects

Bu makalede Power BI görselleriniz için birim testleri yazmayla ilgili temel bilgiler açıklanır ve şu işlemlerin nasıl yapıldığı anlatılır:This article describes the basics of writing unit tests for your Power BI visuals, including how to:

  • Karma JavaScript test runner test çerçevesi Jasmine’i ayarlama.Set up the Karma JavaScript test runner testing framework, Jasmine.
  • powerbi-visuals-utils-testutils paketini kullanma.Use the powerbi-visuals-utils-testutils package.
  • Power BI görsellerinde birim testini basitleştirmeye yardımcı olması için sahte öğeler kullanma.Use mocks and fakes to help simplify unit testing of Power BI visuals.

ÖnkoşullarPrerequisites

  • Yüklü bir Power BI görselleri projesiAn installed Power BI visuals project
  • Yapılandırılmış Node.js ortamıA configured Node.js environment

Karma JavaScript test runner’ı ve Jasmine’i yükleme ve yapılandırmaInstall and configure the Karma JavaScript test runner and Jasmine

Gerekli kitaplıkları package.json dosyasında devDependencies bölümüne ekleyin: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"

Package.json hakkında daha fazla bilgi edinmek için npm-package.json dosyasındaki açıklamaya bakın.To learn more about package.json, see the description at npm-package.json.

Package.json dosyasını kaydedin ve package.json konumunda aşağıdaki komutu çalıştırın:Save the package.json file and, at the package.json location, run the following command:

npm install

Paket yöneticisi package.json dosyasına eklenen tüm yeni paketleri yükler.The package manager installs all new packages that are added to package.json.

Birim testlerini çalıştırmak için test runner’ı ve webpack öğesini yapılandırın.To run unit tests, configure the test runner and webpack config.

Aşağıdaki kod örnek bir test.webpack.config.js dosyasıdır: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
        })
    ]
};

Aşağıdaki kod örnek bir karma.conf.ts dosyasıdır: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"
        }
    });
};

Gerekirse bu yapılandırmayı değiştirebilirsiniz.If necessary, you can modify this configuration.

Karma.conf.js dosyasındaki kod aşağıdaki değişkenleri içerir:The code in karma.conf.js contains the following variable:

  • recursivePathToTests Test kodunu bulurrecursivePathToTests: Locates the test code

  • srcRecursivePath Derleme sonrasında çıkış JavaScript kodunu bulursrcRecursivePath: Locates the output JavaScript code after compiling

  • srcCssRecursivePath Stillerle daha az dosya derlendikten sonra çıkış CSS’yi bulursrcCssRecursivePath: Locates the output CSS after compiling less file with styles

  • srcOriginalRecursivePath Görselinizin kaynak kodunu bulursrcOriginalRecursivePath: Locates the source code of your visual

  • coverageFolder Kapsam raporunun nerede oluşturulacağını belirlercoverageFolder: Determines where the coverage report is to be created

Yapılandırma dosyası aşağıdaki özellikleri içerir:The configuration file includes the following properties:

  • singleRun: true Testler sürekli tümleştirme (CI) sisteminde çalıştırılır veya tek bir kez çalıştırılabilir.singleRun: true: Tests are run on a continuous integration (CI) system, or they can be run one time. Testlerinizde hata ayıklaması yapmak için ayarı false olarak değiştirebilirsiniz.You can change the setting to false for debugging your tests. Karma tarayıcıyı çalışır durumda tuttuğundan hata ayıklaması için konsolu kullanabilirsiniz.Karma keeps the browser running so that you can use the console for debugging.

  • files: [...] Bu dizide tarayıcıya yüklenecek dosyaları belirtebilirsiniz.files: [...]: In this array, you can specify the files to load to the browser. Genellikle kaynak dosyalar, test çalışmaları ve kitaplıklar (Jasmine, test yardımcı programları) vardır.Usually, there are source files, test cases, libraries (Jasmine, test utilities). Gerekirse listeye başka dosyalar ekleyebilirsiniz.You can add additional files to the list, as necessary.

  • preprocessors Bu bölümde birim testlerinden önce çalıştırılan eylemleri yapılandıracaksınız.preprocessors: In this section, you configure actions that run before the unit tests run. Typescript’in JavaScript’e ön derlemesini yapar, kaynak eşleme dosyalarını hazırlar ve kod kapsamı raporunu oluştururlar.They precompile the typescript to JavaScript, prepare source map files, and generate code coverage report. Testlerinizde hata ayıklaması yaparken coverage devre dışı bırakılabilir.You can disable coverage when you debug your tests. Kapsam, test kapsamının denetim kodu için ek kod oluşturduğundan hata ayıklama testlerini karmaşıklaştırır.Coverage generates additional code for check code for the test coverage, which complicates debugging tests.

Tüm Karma yapılandırmalarının açıklamaları için Karma Yapılandırma Dosyası sayfasına gidin.For descriptions of all Karma configurations, go to the Karma Configuration File page.

Kolaylık olması için scripts içine bir test komutu ekleyebilirsiniz: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"
    }
    ...
}

Artık birim testlerinizi yazmaya başlamaya hazırsınız.You're now ready to begin writing your unit tests.

Görselin DOM öğesini denetlemeCheck the DOM element of the visual

Görseli test etmek için ilk olarak görselin bir örneğini oluşturun.To test the visual, first create an instance of visual.

Görsel örneği oluşturucusu oluşturmaCreate a visual instance builder

Aşağıdaki kodu kullanarak test klasörüne visualBuilder.ts dosyasını ekleyin: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");
    }
}

Görselinizin bir örneğini oluşturmak için build yöntemi vardır.There's build method for creating an instance of your visual. mainElement, görselinizdeki “root” belge nesnesi modelinin (DOM) bir örneğini döndüren bir alma yöntemidir.mainElement is a get method, which returns an instance of "root" document object model (DOM) element in your visual. Alıcı isteğe bağlıdır, ancak birim testini yazmayı kolaylaştırır.The getter is optional, but it makes writing the unit test easier.

Artık görselinizin örneğinin bir derlemesine sahipsiniz.You now have a build of an instance of your visual. Test çalışmasını yazalım.Let's write the test case. Test çalışması, görseliniz görüntülenirken oluşturulan SVG öğelerini denetler.The test case checks the SVG elements that are created when your visual is displayed.

Test çalışmalarını yazmak için TypeScript dosyası oluşturmaCreate a typescript file to write test cases

Aşağıdaki kodu kullanarak test çalışmaları için bir visualTest.ts dosyası ekleyin: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();
    });
});

Çeşitli yöntemler çağrılır:Several methods are called:

  • describe: Test çalışmasını açıklar.describe: Describes a test case. Jasmine çerçevesi bağlamında genellikle bir belirtim paketini veya grubunu açıklar.In the context of the Jasmine framework, it often describes a suite or group of specs.

  • beforeEach describe yönteminde tanımlanan her it yöntemi çağrısından önce çağrılır.beforeEach: Is called before each call of the it method, which is defined in the describe method.

  • it: Tek bir belirtimi tanımlar. it yöntemi bir veya birden fazla expectations içermelidir.it: Defines a single spec. The it method should contain one or more expectations.

  • expect: Belirtim için bir beklenti oluşturur. Tüm beklentiler hiçbir hata olmadan geçerse belirtim başarılı olur.expect: Creates an expectation for a spec. A spec succeeds if all expectations pass without any failures.

  • toBeInDOM Eşleştirici yöntemlerinden biri.toBeInDOM: One of the matchers methods. Eşleştiriciler hakkında daha fazla bilgi için bkz. Jasmine Ad Alanı: eşleştiriciler.For more information about matchers, see Jasmine Namespace: matchers.

Jasmine hakkında daha fazla bilgi için bkz. Jasmine çerçevesi belgeleri sayfası.For more information about Jasmine, see the Jasmine framework documentation page.

Birim testlerini başlatmaLaunch unit tests

Bu test, görsellerin kök SVG öğesinin oluşturulup oluşturulmadığını denetler.This test checks that root SVG element of the visuals is created. Birim testini çalıştırmak için komut satırı aracına aşağıdaki komutu girin:To run the unit test, enter the following command in the command-line tool:

npm run test

karma.js test çalışmasını Chrome tarayıcısında çalıştırır.karma.js runs the test case in the Chrome browser.

Chrome’da açılan Karma JavaScript

Not

Google Chrome’u yerel olarak yüklemelisiniz.You must install Google Chrome locally.

Komut satırı penceresinde şu çıkışı alırsınız: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 )
================================================================================

Birim testleri için statik veri eklemeHow to add static data for unit tests

Aşağıdaki kodu kullanarak test klasöründe visualData.ts dosyasını oluşturun: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;
    }
}

SampleBarChartDataBuilder sınıfı, TestDataViewBuilder öğesini genişletir ve soyut getDataView yöntemini uygular.The SampleBarChartDataBuilder class extends TestDataViewBuilder and implements the abstract method getDataView.

Verileri veri alanı demetlerine yerleştirdiğinizde, Power BI verilerinize göre kategorik bir dataview nesnesi oluşturur.When you put data into data-field buckets, Power BI produces a categorical dataview object that's based on your data.

Veri alanı demetleri

Birim testlerinde, verileri yeniden oluşturmak için Power BI temel işlevleriniz yoktur.In unit tests, you don't have Power BI core functions to reproduce the data. Ama statik verilerinizi kategorik dataview nesnesine eşlemeniz gerekir.But you need to map your static data to the categorical dataview. TestDataViewBuilder sınıfı bu eşlemeyi yapmanıza yardımcı olabilir.The TestDataViewBuilder class can help you map it.

Veri Görünümü eşlemesi hakkında daha fazla bilgi için bkz. DataViewMappings.For more information about Data View mapping, see DataViewMappings.

getDataView yönteminde verilerinizi içeren createCategoricalDataViewBuilder yöntemini çağırırsınız.In the getDataView method, you call the createCategoricalDataViewBuilder method with your data.

sampleBarChart görseli capabilities.json dosyasında dataRoles ve dataViewMapping nesnelerimiz vardır: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"
                        }
                    }
                ]
            }
        }
    }
],

Aynı eşlemeyi oluşturmak için şu parametreleri createCategoricalDataViewBuilder yöntemi olarak ayarlamanız gerekir: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)

Burada this.valuesCategory bir kategori dizisidir:Where this.valuesCategory is an array of categories:

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

this.valuesMeasure de her kategori için ölçüm dizisidir: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];

Artık birim testinizde SampleBarChartDataBuilder sınıfını kullanabilirsiniz.Now, you can use the SampleBarChartDataBuilder class in your unit test.

ValueType sınıfı powerbi-visuals-utils-testutils paketinde tanımlanır.The ValueType class is defined in the powerbi-visuals-utils-testutils package. createCategoricalDataViewBuilder yöntemi de lodash kitaplığını gerektirir.And the createCategoricalDataViewBuilder method requires the lodash library.

Bu paketleri bağımlılıklara ekleyin.Add these packages to the dependencies.

devDependencies bölümündeki package.json dosyasındaIn package.json at devDependencies section

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

ÇağırCall

npm install

lodash-es kitaplığını yüklemek için.to install lodash-es library.

Şimdi birim testini yeniden çalıştırabilirsiniz.Now, you can run the unit test again. Aşağıdaki çıkışı almanız gerekir: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 )
================================================================================

Görseliniz aşağıda gösterildiği gibi Chrome tarayıcısında açılır:Your visual opens in the Chrome browser, as shown:

Chrome'da UT başlatılır

Özet, kapsamın arttığını gösterir.The summary shows that coverage has increased. Geçerli kod kapsamı hakkında daha fazla bilgi edinmek için coverage\index.html dosyasını açın.To learn more about current code coverage, open coverage\index.html.

UT kapsamı dizini

İsterseniz src klasörünün kapsamına da bakabilirsiniz:Or look at the scope of the src folder:

src klasörünün kapsamı

Dosyanın kapsamında kaynak kodu görüntüleyebilirsiniz.In the scope of file, you can view the source code. Birim testleri sırasında belirli bir kod yürütülmezse Coverage yardımcı programları satırı kırmızıyla vurgulayabilir.The Coverage utilities would highlight the row in red if certain code isn't executed during the unit tests.

Visual.ts dosyasının kod kapsamı

Önemli

Kod kapsamı, görselin iyi bir işlevsellik kapsamına sahip olduğunuz anlamına gelmez.Code coverage doesn't mean that you have good functionality coverage of the visual. Tek bir basit birim testi, src\visual.ts içinde yüzde 96’nın üzerinde kapsam sağlar.One simple unit test provides over 96 percent coverage in src\visual.ts.

Sonraki adımlarNext steps

Görseliniz hazır olduğunda görselinizi yayına gönderebilirsiniz.When your visual is ready, you can submit it for publication. Daha fazla bilgi için bkz. Power BI görsellerini AppSource'a yayımlama.For more information, see Publish Power BI visuals to AppSource.