疯狂有趣的构建工具

最初的 Selenium 构建工具,从无到有,发展得极其笨重,使其在工作时既疯狂又“有趣”。

此文档先前位于 wiki 上

WebDriver 是一个大型项目:如果我们尝试将所有内容都放入单个庞大的构建文件中,它最终会变得难以管理。我们知道这一点。我们尝试过了。因此,我们将单个 Rakefile 分解为一系列 build.desc 文件。这些文件中的每一个都描述了构建的一部分。

让我们看一下一个 build.desc 文件。这是 主测试 build.desc 的一部分

java_test(name = "single",
  srcs = [
    "SingleTestSuite.java",
  ],
  deps = [
    ":tests",
    "//java/server/src/org/openqa/selenium/server",
    "//java/client/test/org/openqa/selenium/v1:selenium-backed-webdriver-test",
    "//java/client/test/org/openqa/selenium/firefox:test",
  ]  ])

目标

这突出了大多数关键概念。首先,它声明了一个目标,在本例中,只有一个 java_test 目标。每个目标都有一个 name 属性。

目标名称

“build.desc”文件的位置和名称的组合用于派生生成的 rake 任务。所有任务名称都以“//”开头,后跟包含相对于 Rakefile 的“build.desc”文件的目录路径,后跟一个“:”和“build.desc”中目标的名称。一个示例使这一点更加清晰:)

此示例生成的 rake 任务是 //java/client/test/org/openqa/selenium:single

短目标名称

作为快捷方式,如果目标以包含“build.desc”文件的目录命名,则可以省略冒号后的 rake 任务名称部分。在我们的示例中://java/server/src/org/openqa/selenium/server//java/server/src/org/openqa/selenium/server:server 相同。

隐式目标

一些构建规则提供隐式目标,并为普通构建目标提供相关的扩展。示例包括生成源代码存档或运行测试。这些通过将另一个冒号和隐式目标的名称附加到构建规则的完整名称来声明。在我们的示例中,您可以使用“//java/client/test/org/openqa/selenium:single:run”运行测试

下面描述的每个规则都具有与之关联的隐式目标列表。

输出

“build.desc”文件中指定的每个目标都只生成一个输出。这很重要。请记住这一点。通常,所有输出文件都放置在相对于 rake 任务名称的“build”目录中。在我们的示例中,“//java/org/openqa/selenium/server”的输出将在“build/java/org/openqa/selenium/server.jar”中找到。构建规则应输出它们生成的任何文件的名称和位置。

依赖项

查看上面“single”目标的“deps”部分。":tests" 是对当前“build.desc”文件中目标的引用,在本例中,它是正上方的“java_library”目标。您还会看到对多个完整路径的引用。例如 "//java/server/src/org/openqa/selenium/server" 这指的是在疯狂有趣的 build.desc 文件中定义的另一个目标。

浏览器

py_test 和 js_test 规则具有特殊的处理方式,可在多个浏览器中运行相同的测试。相关的特定于浏览器的元数据保存在 rake-tasks/browsers.rb 中。使用此方法的一般方式是将 _browsername 附加到目标名称;如果没有 _browsername 后缀,则将针对所有浏览器运行测试。

例如,如果我们有一个 js_test 规则 //foo/bar,我们将通过运行目标 //foo/bar_ff:run 在 firefox 中运行其测试,或者我们将通过运行目标 //foo/bar:run 在所有可用浏览器中运行测试

构建目标

您可以使用 -T 选项列出所有构建目标。例如

./go -T

简要描述您可以使用的可用目标。

通用属性

以下属性是所有构建目标所必需的

属性名称类型含义
name字符串用于派生 rake 目标和(通常)生成的二进制文件的名称

以下属性是常用的

属性名称类型含义
srcs数组要为此目标构建的原始源代码
deps数组此目标的先决条件

java_library

  • 输出: 如果设置了“srcs”属性,则 JAR 文件以“name”属性命名。
  • 隐式目标: run(如果指定了“main”属性),project、project-srcs、uber、zip
  • 必需属性:“name”和至少一个“srcs”或“deps”。
属性名称类型含义
deps数组如上所述
srcs数组如上所述
resources数组应复制到 jar 文件中的任何资源。
main字符串jar 的主类的完整类名(用于创建可执行 jar)

java_test

  • 输出: 如果设置了“srcs”属性,则 JAR 文件以“name”属性命名。
  • 隐式目标: run、project、project-srcs、uber、zip
  • 必需属性:“name”和至少一个“srcs”或“deps”。
属性名称类型含义
deps数组如上所述。
srcs数组如上所述。
resources数组应复制到 jar 文件中的任何资源。
main字符串用于运行这些测试的替代类。
args字符串传递给主类的参数行
sysproperties数组应设置的包含系统属性的映射数组

js_deps

  • 输出: 标记文件,用于指示任务是最新的。
  • 隐式目标:
  • 必需属性:“name”和“srcs”
属性名称类型含义
name字符串如上所述
srcs数组如上所述
deps数组如上所述

js_binary

  • 输出: 一个单体的 JS 文件,其中包含使用 closure compiler 编译的所有依赖项和源,没有优化。
  • 隐式目标:
  • 必需属性: 至少一个 srcs 或 deps。
属性名称类型含义
name字符串如上所述
srcs数组如上所述
deps数组如上所述

js_fragment

  • 输出: 表示导出函数的匿名函数的源代码,由 closure compiler 编译,并启用所有优化。
  • 隐式目标:
  • 必需属性: name、module、function、deps
属性名称类型含义
name字符串如上所述
module字符串包含函数的模块的名称
function字符串要导出的函数的完整名称
deps数组如上所述

js_fragment_header

  • 输出: 一个 C 头文件,其中所有 js_fragment 依赖项都声明为常量。
  • 隐式目标:
  • 必需属性: name、deps
属性名称类型含义
name字符串如上所述
srcs数组如上所述
deps数组如上所述

js_test

  • 输出
  • 隐式目标: _BROWSER:run、run
  • 必需属性: 无。
属性名称类型含义
deps数组如上所述。
srcs数组如上所述。
path字符串在测试服务器上托管测试文件的预期路径。
browsers数组要运行测试的浏览器列表,来自 rake_tasks/browsers.rb。只会尝试在系统上可用的浏览器中运行测试。如果不存在,则默认为系统上的所有浏览器。

假设浏览器 = [‘ff’, ‘chrome’],对于目标 //foo,将生成隐式目标://foo_ff:run 和 //foo_chrome:run,它们在每个浏览器中运行测试,并且将生成隐式目标 //foo:run,它在 ff 和 chrome 中运行测试。

py_test

  • 输出: 创建运行列出的 python 测试所需的目录结构。
  • 隐式目标: _BROWSER:run、run
  • 必需属性: name。
属性名称类型含义
deps数组其他 py_test 规则,其测试也应运行。
common_tests数组要在所有浏览器中运行的测试文件。这些测试将通过模板传递,其中包含特定于浏览器的替换,以便它们在 python 输出文件树中为每个浏览器正确布局。
BROWSER_specific_tests数组仅在浏览器 BROWSER 中运行的测试文件。
resources数组应复制到 python 目录结构的资源。
browsers数组要运行测试的浏览器列表,来自 rake_tasks/browsers.rb。只会尝试在系统上可用的浏览器中运行测试。如果不存在,则默认为系统上的所有浏览器。

注意:每个 py_test 调用都在新的 virtualenv 中执行。

rake_task

  • 输出: 一个疯狂的构建规则,可以引用它“吹掉逃生”舱口并使用普通的 rake 目标。
  • 隐式目标:
  • 必需属性: name、task_name、out。
属性名称类型含义
name字符串如上所述
task_name字符串要调用的普通 rake 目标
out字符串相对于 Rakefile 生成的文件

gcc_library

  • 输出: 如果设置了“srcs”属性,则共享库文件以“name”属性命名。
  • 隐式目标: 无。
  • 必需属性:“name” 和 “srcs”。
属性名称类型含义
srcs数组如上所述
arch字符串“amd64” 用于 64 位构建,“i386” 用于 32 位构建。
args字符串传递给编译器的参数(例如,-I 标志)。
link_args字符串传递给链接器的参数(例如,-l 标志)。

注意:首次构建新库时,构建会成功,但复制到预构建库的操作将失败,并显示类似消息

cp build/cpp/amd64/libimetesthandler64.so 
go aborted!
can't convert nil into String

解决方案:将刚刚构建的库复制到相应的预构建文件夹(cpp/prebuilt/arch/)。

上次修改时间:2022 年 1 月 10 日:更多 wiki (#907) [部署站点] (adcf706a1ad)