目录
1.贡献
1.1.核心开发
1.1.1.basePath 注意事项
1.1.2.管理依赖
1.1.3.模块和自动加载
1.1.4.与 Elasticsearch 通信
1.1.5.功能测试
1.2.插件开发
1.2.1.插件资源
1.2.2.UI Exports
1.2.3.插件功能测试
2.限制
嵌套字段
1.贡献
我们非常欢迎您为 Kibana 做贡献,如果您想提交 pull request 到 Kibana 仓库,您可以参考核心开发。
如果您想使用 Kibana 内部的插件 API,您可以查看插件开发。
1.1.核心开发
- basePath 注意事项
- 管理依赖
- 模块和自动加载
- 与 Elasticsearch 通信
- 功能测试
1.1.1.basePath 注意事项
所有从 Kibana UI 到服务端的通信,都要遵守 server.basePath
。下面是一些基于上下文处理该问题的建议:
<img>
和 <a>
元素
如您所愿,可以不写基本路径而直接写上 src
或者 href
urls,然后用 kbn-src
或 kbn-href
替换 src
或 href
。
<img kbn-src="plugins/kibana/images/logo.png">
获取一个静态的 asset url
用 webpack 导入 asset 到 build 中。这会给您一个 JavaScript 的 URL,并给 webpack 一个机会去执行优化及中断缓冲。
// in plugin/public/main.js
import uiChrome from 'ui/chrome';
import logoUrl from 'plugins/facechimp/assets/banner.png';
uiChrome.setBrand({
logo: `url(${logoUrl}) center no-repeat`
});
前端 API 请求
使用 chrome.addBasePath()
将 basePath 添加到 url 的前面。
import chrome from 'ui/chrome';
$http.get(chrome.addBasePath('/api/plugin/things'));
服务器端
在每个绝对 URL 路径上添加 config.get('server.basePath')
const basePath = server.config().get('server.basePath');
server.route({
path: '/redirect',
handler(req, reply) {
reply.redirect(`${basePath}/otherLocation`);
}
});
开发模式中的 BasePathProxy
Kibana 开发服务器在一个有随机 server.basePath
的代理之后自动运行。这样,当开发者编写代码时,他们会不断地确认他们的代码是否与 basePath 一起工作。
为了达到这个效果, serve
任务做了如下一些事情:
- 根据
dev.basePathProxyTarget
配置服务器的端口(默认5603
) - 在
server.port
启动一个BasePathProxy
- 为
randomBasePath
挑选一个三位数的值 - 从
/{any}/app/{appName}
重定向到/{randomBasePath}/app/{appName}
,从而使刷新起作用 - 将以
/{randomBasePath}/
开头的所有请求代理到 Kibana 服务器
有时候,在开发环境中代理会产生意想不到的副作用。因此,当需要的时候您可以通过传递 --no-base-path
选项到 serve
任务或者 npm start
以退出代理。
npm start -- --no-base-path
1.1.2.管理依赖
在开发 Kibana 前端环境中使用的插件时,您可能想要包含(至少)一个或两个库。虽然这在90%的情况下都是很简单的,但总会有一些异常值,而其中一些异常值还是在非常受欢迎的项目中。
在 Kibana 中使用外部库之前,您要先安装它。您可以通过如下方式安装:
npm (首选方法)
一旦您发现想要添加的依赖,您可以像这样安装它:
npm install --save some-neat-library
在 javascript 文件的顶部,只需要使用它的名称来导入库:
import someNeatLibrary from 'some-neat-library';
就像在 node.js 中一样,前端代码无需进行扩展配置就能请求 npm 节点模块安装。
webpackShims
当您想要用的库使用 es6 或 common.js 模块,但在 npm 上不可用时,您可以复制库的源文件到 webpackShim。
# 为新的库创建一个目录
mkdir -p webpackShims/some-neat-library
# 将您想使用的库下载到该目录
curl https://cdnjs.com/some-neat-library/library.js > webpackShims/some-neat-library/index.js
然后,像往常一样在您的 JavaScript 代码中包含该库:
import someNeatLibrary from 'some-neat-library';
桥接第三方代码
一些 JavaScript 库声明它们依赖的方式并不会被诸如 webpack 的工具所理解。通常情况下,库不会导出它们提供的值,而只是将它们写入到全局变量里(或者某种意义上的变量)。
当将这样的代码拉入到 Kibana 中时,我们要编写 “桥接代码(shims)” 来整合第三方代码,以便与我们的应用、其他库和模块系统一起工作。我们可以使用 webpackShims
目录来做到这一点。
示例是解释如何编写桥接代码的最简单方式。下面是我们用于 jQuery 的 webpack 桥接代码。
// webpackShims/jquery.js
module.exports = window.jQuery = window.$ = require('node_modules/jquery/dist/jquery');
require('ui/jquery/findTestSubject')(window.$);
由于 webpackShims
的行为类似于 node_modules
, 一旦 webpack 发现 import 'jquery';
语句,桥接代码会被加载。当它发生时,桥接代码会做两件事:
- 将实际 jQuery 模块的导出值分配给
$
和jQuery
,允许像 angular 这样的库检测 jQuery 是否可用,并将其作为模块的导出变量使用。 - 最终,我们编写的 jQuery 插件会被引入,因此每次有文件引入 jQuery 时,该文件会同时得到 jQuery 和
$.findTestSubject
的帮助模块。
下面是我们用于 angular 的 webpack 桥接代码:
// webpackShims/angular.js
require('jquery');
require('node_modules/angular/angular');
require('node_modules/angular-elastic/elastic');
require('ui/modules').get('kibana', ['monospaced.elastic']);
module.exports = window.angular;
如果您一行一行的看,会发现桥接代码做的很简单:
- 确保 jQuery 在 angular(实际运行上述的 shim) 之前加载。
- 从 npm 安装中加载 angular.js 。
- 加载 angular-elastic 插件,每次导入 angular 都需要包含 angular-elastic 插件。
- 使用
ui/modules
模块添加被 angular-elastic 导入进来的模块作为kibana
angular 模块的依赖。 - 最后,导出 window.angular 变量。这意味着当写下
import angular from 'angular';
时会恰当地设置 angular 库中的 angular 变量,而不是未定义的默认配置。
1.1.3.模块和自动加载
自动加载
由于 JS 模块与指令、过滤器和服务的脱节,很难知道要导入哪些内容。更难的是,您不知道自己移除的看似无用的模块是否会对其他地方产生影响。
为了防止其成为一个问题,ui 模块提供了 “自动加载(autoloading)” 模块。这些模块的唯一目的是使用某些组件拓展环境。以下是这些模块的分解:
-
import 'ui/autoload/styles'
在src/ui/public/styles
导入所有样式。 -
import 'ui/autoload/directives'
在src/ui/public/directives
导入所有指令。 -
import 'ui/autoload/filters'
在src/ui/public/filters
导入所有过滤器。 -
import 'ui/autoload/modules'
-
import 'ui/autoload/all'
解析所需路径
Kibana 用 Webpack 管理依赖。
下面是如何将 import/require 语句解析为一个文件:
- 检查模块路径的开头
- 如果路径以 . 开头
- 添加当前文件的目录
- 转到 3
- 如果路径以 / 开头
- 搜索这条精确路径
- 转到 3
- 转到 2
- 搜索已命名模块
-
moduleName
= dirname(require path) - 如果
moduleName
是下面别名中的一个,或者以下面中的别名开头,则匹配
- 用匹配替换别名,继续 3
- 当满足这些条件时,匹配:
-
./webpackShims/${moduleName}
是一个目录 -
./node_modules/${moduleName}
是一个目录
- 如果没有找到匹配
- 转到上层目录
- 从 2.iii 重新开始,直至找到匹配或者到达根目录
- 如果找到匹配
- 以匹配的全路径替换 requite 语句中的
moduleName
前缀,然后转到 3
- 搜索文件
- 下列路径中第一个解析为一个 file 的是我们的匹配
- path + .js
- path + .json
- path + .jsx
- path + .less
- path
- path/${basename(path)} + .js
- path/${basename(path)} + .json
- path/${basename(path)} + .jsx
- path/${basename(path)} + .less
- path/${basename(path)}
- path/index + .js
- path/index + .json
- path/index + .jsx
- path/index + .less
- path/index
- 如果以上路径均不匹配则抛出错误
1.1.4.与 Elasticsearch 通信
Kibana 在服务器和浏览器上暴露了两个客户端用于和 elasticsearch 通信。其中一个为管理客户端,用于管理 Kibana 的状态;另外一个为数据客户端,用于处理其它所有的请求。客户端使用 elasticsearch.js 库。
服务器客户端
服务器客户端通过 elasticsearch 插件暴露。
const adminCluster = server.plugins.elasticsearch.getCluster('admin);
const dataCluster = server.plugins.elasticsearch.getCluster('data);
//ping as the configured elasticsearch.user in kibana.yml
adminCluster.callWithInternalUser('ping');
//ping as the user specified in the current requests header
adminCluster.callWithRequest(req, 'ping');
浏览器客户端
浏览器客户端通过 AngularJS 服务暴露。
uiModules.get('kibana')
.run(function (esAdmin, es) {
es.ping()
.then(() => esAdmin.ping())
.catch(err => {
console.log('error pinging servers');
});
});
1.1.5.功能测试
我们通过功能测试确保 Kibana UI 按照预期方式运行。该功能测试通过自动化用户交互,取代了长达数小时的人工测试。Kibana 使用的工具叫做 FunctionalTestRunner
,能够更好的控制功能测试环境,更便于插件作者使用。
运行功能测试
FunctionalTestRunner
结构非常简单,大部分功能主要源自位于 test/functional/config.js 的配置文件。如果您正在编写一个插件,就会拥有自己的配置文件。有关更多信息,请参见 插件功能测试 。
使用 node.js 执行 FunctionalTestRunner
脚本运行测试,使用 Kibana 的默认配置:
node scripts/functional_test_runner
在没有任何参数的情况下运行时, FunctionalTestRunner
会自动加载位于标准位置的配置,但是您可以用 --config
标记来覆盖这个行为。 --bail
和 --grep
也有命令行标记,功能与 mocha 类似。 日志也可以通过使用 --quiet
、 --debug
或 --verbose
标记进行自定义设置。
使用 --help
标记获得更多选项。
编写功能测试
环境
我们使用 chromedriver、 leadfoot 和 digdug 在 Chrome 上做自动化测试。 FunctionalTestRunner
启动后,digdug 会打开一个启动 chromedriver 的 Tunnel
和一个 Chrome 的精简用例。digdug 还会创建一个 Leadfoot’s Command 类的用例,该用例可以通过 remote
服务器获取。 remote
通过 digdug Tunnel
与 Chrome 进行通讯。 remote
涉及的所有命令详见 leadfoot/Command API。
FunctionalTestRunner
使用 babel 语言自动编译功能测试,因此测试可以使用 Kibana 源代码使用的 ECMAScript 特性。详见 style_guides/js_style_guide.md。
术语
Provider(提供者):
FunctionalTestRunner
运行的代码会被打包进一个函数中,这样它就可以通过配置文件传递,并且能被参数化。这些提供者函数中的任何一个都有可能是异步的,并需要返回或重新获取他们想要的 值 。提供者函数总通过单一参数:API Provider(参见 Provider API 章节)来调用。
提供者配置示例:
// config and test files use `export default`
export default function (/* { providerAPI } */) {
return {
// ...
}
}
Services(服务)
服务根据服务提供者产生的单一值命名。测试和其他服务能够通过请求服务的名称来检索服务实例。除 mocha API 以外的所有功能都是通过服务公开的。
Page objects(页对象)
页对象是一种将通常行为封装进特定页面或插件的特殊服务。当您编写自己的插件时,您可能想要添加一个(或多个)用于描述测试所需执行的常见交互的页面对象。
Test Files(测试文件)
FunctionalTestRunner
的主要目的是执行测试文件。这些文件导出一个提供者 API 调用的测试提供者(Test Provider),但并不会返回数值。相反,测试提供者用 mocha’s BDD interface 定义一个程序组。
Test Suite(测试套件)
测试套件是调用 describe()
的测试集,然后通过调用 it()
、 before()
、 beforeEach()
等填充测试和 setup/teardown hooks。每个测试文件都必须定义唯一一个顶级测试套件,但测试套件可以拥有任意多个嵌套测试套件。
测试文件剖析
下列带注释的示例文件展示了每个测试套件所使用的基本结构。它首先导入 expect.js,然后定义其默认输出:一个匿名的测试提供者。该测试提供者为 getService()
和 getPageObjects()
函数拆解提供者 API。它使用这些函数来收集本套件的依赖。对于 mocha.js 用户,其他测试文件看起来就很普通了。
import expect from 'expect.js';
// test files must `export default` a function that defines a test suite
export default function ({ getService, getPageObject }) {
// most test files will start off by loading some services
const retry = getService('retry');
const testSubjects = getService('testSubjects');
const esArchiver = getService('esArchiver');
// for historical reasons, PageObjects are loaded in a single API call
// and returned on an object with a key/value for each requested PageObject
const PageObjects = getPageObjects(['common', 'visualize']);
// every file must define a top-level suite before defining hooks/tests
describe('My Test Suite', () => {
// most suites start with a before hook that navigates to a specific
// app/page and restores some archives into elasticsearch with esArchiver
before(async () => {
await Promise.all([
// start with an empty .kibana index
esArchiver.load('empty_kibana'),
// load some basic log data only if the index doesn't exist
esArchiver.loadIfNeeded('makelogs')
]);
// go to the page described by `apps.visualize` in the config
await PageObjects.common.navigateTo('visualize');
});
// right after the before() hook definition, add the teardown steps
// that will tidy up elasticsearch for other test suites
after(async () => {
// we unload the empty_kibana archive but not the makelogs
// archive because we don't make any changes to it, and subsequent
// suites could use it if they call `.loadIfNeeded()`.
await esArchiver.unload('empty_kibana');
});
// This series of tests illustrate how tests generally verify
// one step of a larger process and then move on to the next in
// a new test, each step building on top of the previous
it('Vis Listing Page is empty');
it('Create a new vis');
it('Shows new vis in listing page');
it('Opens the saved vis');
it('Respects time filter changes');
it(...
});
}
提供者 API
提供者 API 对象(Provider API Object)是所有提供者的第一个也是唯一一个参数。这个对象可以用于加载服务、页面对象和配置、测试文件。
在配置文件中,API具有以下属性
| ToolingLog 的一个准备使用的实例 |
| 返回一个解析为配置实例的承诺,提供 |
在服务和 PageObject 提供者中,API 是:
| 根据名称,加载并返回服务的一个单例实例 |
| 加载 |
测试提供者中的 API 与服务提供者 API 相同,但是具有附加方法:
| 加载路径上的测试文件。使用此方法将其他文件中的套件嵌套到更高级的套件中。 |
服务指标
内置服务
FunctionalTestRunner
自带三种内置 service:
config:
- 源码: src/functional_test_runner/lib/config/config.js
- 概要: src/functional_test_runner/lib/config/schema.js
- 使用
config.get(path)
查看配置文件中的任意值
log:
- 源码: src/utils/tooling_log/tooling_log.js
-
ToolingLog
实例是可读流。此服务提供的实例由FunctionalTestRunner
CLI 自动传输到 stdout -
log.verbose()
、log.debug()
、log.info()
、log.warning()
像 console.log 那样工作,只不过产生结构化更好的输出
lifecycle:
- 源码: src/functional_test_runner/lib/lifecycle.js
- 设计主要用于 service 中
- 公开生命周期事件以进行基本协调。处理程序可以返回承诺并异步地解析、失败
- 包括
beforeLoadTests
、beforeTests
、beforeEachTest
、cleanup
、phaseStart
、phaseEnd
阶段
Kibana 服务
Kibana 功能测试定义了绝大部分测试会使用的实际功能。
retry:
- 源码: test/functional/services/retry.js
- 重试操作辅助器
- 常用方法:
-
retry.try(fn)
- 在 loop 中执行fn
直至成功或超过默认重试时间 -
retry.tryForTime(ms, fn)
在 loop 中执行,直至成功或超过ms
毫秒
testSubjects:
- 源码: test/functional/services/test_subjects.js
- 测试主题是从测试中选出的被专门标记过的要素
- 可能的情况下,在 CSS 选择器中使用
testSubjects
- 使用:
- 用
data-test-subj
属性标记您的测试对象: <div id="container”> <button id="clickMe” data-test-subj=”containerButton” /> </div> - 使用
testSubjects
帮助器点击这个按钮 await testSubjects.click(‘containerButton’);
- 常用方法:
-
testSubjects.find(testSubjectSelector)
- 在页面中寻找一个测试对象;如果过一段时间没有找到,抛出异常 -
testSubjects.click(testSubjectSelector)
- 在页面中点击一个测试主题;如果过一段时间没有找到,抛出异常
find:
- 源码: test/functional/services/find.js
-
remote.findBy
方法帮助器,用于记录日志和管理超时 - 常用方法:
find.byCssSelector()
find.allByCssSelector()
kibanaServer:
- 源码: test/functional/services/kibana_server/kibana_server.js
- 与 Kibana 服务器交互的帮助器
- 常用方法:
kibanaServer.uiSettings.update()
kibanaServer.version.get()
kibanaServer.status.getOverallState()
esArchiver:
- 源码: test/functional/services/es_archiver.js
- 用
esArchiver
创建的加载、卸载文件 - 常用方法:
esArchiver.load(name)
esArchiver.loadIfNeeded(name)
esArchiver.unload(name)
docTable:
- 源码: test/functional/services/doc_table.js
- 与 doc 表格交互的帮助器
pointSeriesVis:
- 源码: test/functional/services/point_series_vis.js
- 与点序列可视化交互的帮助器
Low-level utilities:
- es
- 源码: test/functional/services/es.js
- Elasticsearch 客户端
- 高级选项:
kibanaServer.uiSettings
或esArchiver
- remote
- 源码: test/functional/services/remote/remote.js
-
https://theintern.github.io/leadfoot/module-leadfoot_Command.html[Leadfoot’s
Command]
类实例 - 负责与浏览器的所有通信
- 高级选项:
testSubjects
、find
和PageObjects.common
- 完整 API 参见 leadfoot/Command API
自定义服务
服务是有意通用的。它们可以是任何东西(甚至什么都不是)。有些服务有助于与特定类型的 UI 元素(如 PooSosieServices )交互,而其他服务则更为基础,如日志或配置。每当您想在可重用包中提供一些功能时,请考虑制作自定义服务。
为了创建一个自定义的 somethingUseful
service:
1.创建一个如下的 test/functional/services/something_useful.js
文件:
// Services are defined by Provider functions that receive the ServiceProviderAPI
export function SomethingUsefulProvider({ getService }) {
const log = getService('log');
class SomethingUseful {
doSomething() {
}
}
return new SomethingUseful();
}
2.从 services/index.js
重新导出您的 provider
3.将它导入到 src/functional/config.js
并添加到服务配置中:
import { SomethingUsefulProvider } from './services';
export default function () {
return {
// … truncated ...
services: {
somethingUseful: SomethingUsefulProvider
}
}
}
PageObjects
PageObject 的目的只是自我解释。可视化的 PageObject 提供与可视化 app 交互的助手,相当于仪表板对于仪表板 app。
"common" PageObject 是一个例外。作为一个延缓的实验性的实现,common PageObject 是有用的跨页面的帮助器集合。现在我们有了共享服务,并且这些服务可以与其他的 FunctionalTestRunner
共享,我们会继续将功能从 common PageObject 转移到服务中。
请在已有或新服务中添加新的方法,而不是进一步扩展 CommonPage 类。
Gotchas
记住您不能运行文件( it
块)中一个单独的测试,因为整个 describe
需要按顺序执行。在一个文件中应该只有一个顶级的 describe
。
功能测试计时
另一个重要的 gotcha 是通过注意时间来编写稳定的测试。所有 remote
方法异步运行。最好在进入下一步之前,在 UI 上添加等待变化的交互。
例如,与其简单的编写点击按钮的交互,不如在头脑中编写更高级目的的交互:
不好的例子: PageObjects.app.clickButton()
class AppPage {
// what can people who call this method expect from the
// UI after the promise resolves? Since the reaction to most
// clicks is asynchronous the behavior is dependant on timing
// and likely to cause test that fail unexpectedly
async clickButton () {
await testSubjects.click(‘menuButton’);
}
}
好的例子: PageObjects.app.openMenu()
class AppPage {
// unlike `clickButton()`, callers of `openMenu()` know
// the state that the UI will be in before they move on to
// the next step
async openMenu () {
await testSubjects.click(‘menuButton’);
await testSubjects.exists(‘menu’);
}
}
这样写将确保您的测试时间不是片状的,或者基于交互后UI更新的假设。
调试
在命令行运行:
node --debug-brk --inspect scripts/functional_test_runner
该命令会输出一个URL,通过在 Chrome 浏览器中访问该URL,您可以调试您的功能测试用例。
您也可以在运行 FunctionalTestRunner
时增加 --debug
或 --verbose
参数,从而在命令行看额外的日志信息。您可以像下面这样,在您的测试用例中增加日志:
// load the log service
const log = getService(‘log’);
// log.debug only writes when using the `--debug` or `--verbose` flag.
log.debug(‘done clicking menu’);
1.2.插件开发
Kibana 插件接口在不断的发展变化。由于插件更新很快,因此很难向后兼容。
Kibana 强制要求安装的插件版本必须和 Kibana 版本一致。插件开发者必须为每个新的 Kibana 版本发布新的插件版本。
- 插件资源
- UI Exports
- 插件功能测试
1.2.1.插件资源
这里有一些资源可以帮助您开发插件
我们的 IRC 频道
很多 Kibana 开发者都在 #kibana
频道上的 irc.freenode.net
上玩。我们 想 帮助您开发插件。更重要的,我们 想要您的帮助 来理解您使用插件的目标,借此我们可以为您创建一个更好的插件系统。如果您从来没有用过 IRC,欢迎来玩。您可以从 Freenode 网页客户端开始。
一些有用的文章
- 贡献指南可以帮助您获得一个开发环境
- Tim Roes' 系列博客 编写 Kibana 插件
视频
插件生成器
下载 插件生成器 以快速生成您的插件。
代码中的引用
-
Plugin class:
kibana.Plugin
类接收哪些选项? - UI Exports: 什么类型的导出是可用的?
1.2.2.UI Exports
可用的 UiExport 类型列表:
类型 | 用途 |
hacks | 每个应用都需要包含的模块。 |
visTypes | 注册器通过 |
fieldFormats | 注册器通过 |
chromeNavControls | 注册器通过 |
navbarExtensions | 注册器通过 |
docViews | 注册器通过 |
app | 向系统添加一个应用。这个 uiExport 类型被定义为元数据的一个对象,而不仅仅是一个模块 id。 |
1.2.3.插件功能测试
插件在 Kibana repo 外部运行并使用 FunctionalTestRunner
。在继续之前,请确认您的 Kibana 开发环境配置正确。
编写您自己的配置
每个工程或插件应该有自己的 FunctionalTestRunner
配置文件。就像 Kibana,配置文件会定义所有要加载的测试文件、服务提供者和 PageObjects,还有某些服务的配置选项。
通过复制下面的例子到 test/functional/config.js
文件开始测试:
import { resolve } from 'path';
import { MyServiceProvider } from './services/my_service';
import { MyAppPageProvider } from './services/my_app_page;
// 允许重写默认的 kibana 目录
// 使用 KIBANA_DIR 环境变量
const KIBANA_CONFIG_PATH = resolve(process.env.KIBANA_DIR || '../kibana', 'test/functional/config.js');
// 配置文件的默认导出必须是一个配置提供程序(config provider)
// 它返回带有项目配置值的对象
export default async function ({ readConfigFile }) {
// 读取 Kibana 配置文件,这样我们可以使用它的一些服务和 PageObjects
const kibanaConfig = await readConfigFile(KIBANA_CONFIG_PATH);
return {
// 列出包含您插件测试用例的文件路径
testFiles: [
resolve(__dirname, './my_test_file.js'),
],
// 定义在您的测试中可用的服务和提供程序,
// 否则,只有内置的服务可用
services: {
...kibanaConfig.get('services'),
myService: MyServiceProvider,
},
// 就像服务那样,PageObjects 定义为提供者的名称映射
// 在 Kibana 中合并或选择指定一个
pageObjects: {
management: kibanaConfig.get('pageObjects.management'),
myApp: MyAppPageProvider,
},
// apps 部分定义 PageObjects.common.navigateTo(appKey) 使用的 urls
// 为您的插件合并 Kibana 配置中定义的 url,以便使用帮助
apps: {
...kibanaConfig.get('apps'),
myApp: {
pathname: '/app/my_app',
}
},
// 选择 esArchiver 从哪里加载
esArchiver: {
directory: resolve(__dirname, './es_archives'),
},
// 选择 screenshots 保存到哪里
screenshots: {
directory: resolve(__dirname, './tmp/screenshots'),
}
// 更多设置,例如 timeouts、 mochaOpts 等定义在配置模式。参见 {blob}src/functional_test_runner/lib/config/schema.js[src/functional_test_runner/lib/config/schema.js]
};
}
现在可以在 repo 的根目录运行您插件工程的 FunctionalTestRunner
脚本。
node ../kibana/scripts/functional_test_runner
使用 esArchiver
2.限制
Kibana 目前有以下限制:
- 嵌套字段
嵌套字段
Kibana 不能执行带嵌套字段(nested objects)的聚合操作。再查询框中执行 Lucene 查询语句的时候也不能有嵌套对象。
使用 include_in_parent 和 copy_to 属性作为临时解决方案已经不再支持了。