├── .gitignore ├── GettingStarted ├── screenshots.png ├── architecture.png ├── testdata_screenshots.png ├── index.rst ├── CopyrightAndLicense.rst ├── COPYRIGHT.txt ├── Demonstrations.rst ├── Introduction.rst └── Install.rst ├── ExecutingTestCases ├── log_failed.png ├── log_passed.png ├── tagstatlink.png ├── report_failed.png ├── report_passed.png ├── summary_passed.png ├── tagstatcombine.png ├── visible_log_level.png ├── index.rst ├── PostProcessing.rst ├── TestExecution.rst ├── ConfiguringExecution.rst └── OutputFiles.rst ├── ExtendingRobotFramework ├── remote.png ├── index.rst ├── ExtendingRobotFrameworkJar.rst └── RemoteLibrary.rst ├── SupportingTools ├── index.rst ├── OtherTools.rst ├── Testdoc.rst ├── LoggingLibrary.py ├── Tidy.rst └── Libdoc.rst ├── Appendices ├── ApiDocumentation.rst ├── index.rst ├── Templates.rst ├── BooleanArguments.rst ├── TimeFormat.rst ├── AvailableSettings.rst ├── DocumentationFormatting.rst └── CommandLineOptions.rst ├── CreatingTestData ├── index.rst ├── CreatingTestSuites.rst ├── UsingTestLibraries.rst ├── ResourceAndVariableFiles.rst └── AdvancedFeatures.rst ├── README.md ├── .gitattributes ├── code_examples ├── select_every_xth_test.py └── check_test_times.py ├── index.rst ├── about.rst ├── roles.rst ├── make.bat ├── Makefile └── conf.py /.gitignore: -------------------------------------------------------------------------------- 1 | _build/ 2 | *.gitconfig -------------------------------------------------------------------------------- /GettingStarted/screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/GettingStarted/screenshots.png -------------------------------------------------------------------------------- /GettingStarted/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/GettingStarted/architecture.png -------------------------------------------------------------------------------- /ExecutingTestCases/log_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/log_failed.png -------------------------------------------------------------------------------- /ExecutingTestCases/log_passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/log_passed.png -------------------------------------------------------------------------------- /ExecutingTestCases/tagstatlink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/tagstatlink.png -------------------------------------------------------------------------------- /ExtendingRobotFramework/remote.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExtendingRobotFramework/remote.png -------------------------------------------------------------------------------- /ExecutingTestCases/report_failed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/report_failed.png -------------------------------------------------------------------------------- /ExecutingTestCases/report_passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/report_passed.png -------------------------------------------------------------------------------- /ExecutingTestCases/summary_passed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/summary_passed.png -------------------------------------------------------------------------------- /ExecutingTestCases/tagstatcombine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/tagstatcombine.png -------------------------------------------------------------------------------- /ExecutingTestCases/visible_log_level.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/ExecutingTestCases/visible_log_level.png -------------------------------------------------------------------------------- /GettingStarted/testdata_screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davycloud/robotframework-userguide-cn/HEAD/GettingStarted/testdata_screenshots.png -------------------------------------------------------------------------------- /SupportingTools/index.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | 支撑工具 3 | ========= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | Libdoc 9 | Testdoc 10 | Tidy 11 | OtherTools -------------------------------------------------------------------------------- /GettingStarted/index.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | 入门指南 3 | ========= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | Introduction 9 | CopyrightAndLicense 10 | Install 11 | Demonstrations -------------------------------------------------------------------------------- /ExecutingTestCases/index.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | 测试执行 3 | ========= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | BasicUsage 9 | TestExecution 10 | PostProcessing 11 | ConfiguringExecution 12 | OutputFiles 13 | -------------------------------------------------------------------------------- /ExtendingRobotFramework/index.rst: -------------------------------------------------------------------------------- 1 | ================== 2 | 扩展RobotFramework 3 | ================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | CreatingTestLibraries 9 | RemoteLibrary 10 | ListenerInterface 11 | ExtendingRobotFrameworkJar 12 | -------------------------------------------------------------------------------- /Appendices/ApiDocumentation.rst: -------------------------------------------------------------------------------- 1 | .. Internal API 2 | 3 | 内部API 4 | ======= 5 | 6 | Robot Framework 2.7版本开始, `API文档 `_ 单独部署到了 `Read the Docs `_ 文档服务上. 如果你不确定某个API怎样使用, 或者向前兼容性怎样, 请发问题到 :ref:`mailing lists`. 7 | 8 | -------------------------------------------------------------------------------- /Appendices/index.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | 附录 3 | ========= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | AvailableSettings 9 | CommandLineOptions 10 | Templates 11 | DocumentationFormatting 12 | TimeFormat 13 | BooleanArguments 14 | ApiDocumentation 15 | -------------------------------------------------------------------------------- /CreatingTestData/index.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | 核心概念 3 | ========= 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | 8 | TestDataSyntax 9 | CreatingTestCases 10 | CreatingTestSuites 11 | UsingTestLibraries 12 | Variables 13 | CreatingUserKeywords 14 | ResourceAndVariableFiles 15 | AdvancedFeatures -------------------------------------------------------------------------------- /GettingStarted/CopyrightAndLicense.rst: -------------------------------------------------------------------------------- 1 | Copyright and license 2 | ===================== 3 | 4 | Robot Framework itself, test libraries and supporting tools distributed with it, 5 | as well as this user guide and other provided documentation have the following 6 | copyright statement. 7 | 8 | .. include:: COPYRIGHT.txt 9 | :literal: 10 | 11 | 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # robotframework-userguide-cn 2 | 3 | ## robotframework用户手册中文版 4 | 5 | 6 | 阅读文档: http://robotframework-userguide-cn.readthedocs.io/zh_CN/latest/ 7 | 8 | 9 | ## 原文参考 10 | 11 | 英文手册:http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html 12 | 13 | English Source:https://github.com/robotframework/robotframework/tree/master/doc/userguide -------------------------------------------------------------------------------- /SupportingTools/OtherTools.rst: -------------------------------------------------------------------------------- 1 | .. _external tools: 2 | 3 | 外部工具 4 | ======== 5 | 6 | Robot Framework有很多可用的外部工具, 包括测试数据的编辑器 RIDE_, 各种IDE或文本编辑器的扩展, 持续集成系统的插件, 等等. 7 | 8 | 这些工具都是作为单独的项目独立于Robot Framework开发, 要获取可用的工具列表请查看: http://robotframework.org/#tools. 9 | 10 | .. note:: 有些支持工具以前是随着Robot Framework一起分发的. 自从Robot Framework 11 | 2.8.6版本之后, 这些工具从代码块和发布包都已经剥离开, 但是仍可单独获取. 12 | 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /GettingStarted/COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | Copyright 2008-2015 Nokia Solutions and Networks 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /ExtendingRobotFramework/ExtendingRobotFrameworkJar.rst: -------------------------------------------------------------------------------- 1 | .. Extending the Robot Framework Jar 2 | 3 | 扩展Robot Framework的Jar包 4 | ========================== 5 | 6 | 为Robot Framework的jar包添加额外的测试库或支撑代码很简单, 直接使用标准JDK安装包含的 ``jar`` 命令即可. Python代码必须位于jar文件内的 :file:`Lib` 路径内, Java代码可以按包结构直接置于jar的根路径. 7 | 8 | 例如, 要添加Python包 `mytestlib`, 首先将文件夹 :file:`mytestlib` 拷贝到 :file:`Lib` 文件夹之下, 然后在包含 :file:`Lib` 的文件夹中执行:: 9 | 10 | jar uf /path/to/robotframework-2.7.1.jar Lib 11 | 12 | 要将编译后的java类添加到jar中, 必须将按Java包结构的整个目录添加到jar包内. 13 | 14 | 例如, 要添加 包 `org.test` 内的类 `MyLib.class`, 类文件路径必须是 :file:`org/test/MyLib.class`, 然后执行:: 15 | 16 | jar uf /path/to/robotframework-2.7.1.jar org 17 | -------------------------------------------------------------------------------- /code_examples/select_every_xth_test.py: -------------------------------------------------------------------------------- 1 | from robot.api import SuiteVisitor 2 | 3 | 4 | class SelectEveryXthTest(SuiteVisitor): 5 | """Visitor that keeps only every Xth test in the visited suite structure.""" 6 | 7 | def __init__(self, x, start=0): 8 | self.x = int(x) 9 | self.start = int(start) 10 | 11 | def start_suite(self, suite): 12 | """Modify suite's tests to contain only every Xth.""" 13 | suite.tests = suite.tests[self.start::self.x] 14 | 15 | def end_suite(self, suite): 16 | """Remove suites that are empty after removing tests.""" 17 | suite.suites = [s for s in suite.suites if s.test_count > 0] 18 | 19 | def visit_test(self, test): 20 | """Save time to avoid visiting tests and their keywords.""" 21 | pass 22 | -------------------------------------------------------------------------------- /index.rst: -------------------------------------------------------------------------------- 1 | .. robotframework-userguide-cn documentation master file, created by 2 | sphinx-quickstart on Sun May 22 16:38:38 2016. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | ======================== 7 | Robot Framework用户手册 8 | ======================== 9 | 10 | Version |version| 11 | 12 | --------------------- 13 | 14 | .. 自定义role应该放在哪里? 15 | 16 | .. role:: name(emphasis) 17 | 18 | .. toctree:: 19 | :maxdepth: 2 20 | 21 | about 22 | 23 | GettingStarted/index 24 | CreatingTestData/index 25 | ExecutingTestCases/index 26 | ExtendingRobotFramework/index 27 | SupportingTools/index 28 | Appendices/index 29 | 30 | 31 | 32 | .. _Python: http://python.org 33 | .. _Robot Framework: http://robotframework.org 34 | .. _RIDE: http://example.com/ 35 | .. _regexp: http://en.wikipedia.org/wiki/Regular_expression -------------------------------------------------------------------------------- /Appendices/Templates.rst: -------------------------------------------------------------------------------- 1 | .. _test data template: 2 | 3 | 测试数据模板 4 | =================== 5 | 6 | 在为Robot Framework `创建测试数据`_ 的时候可以使用这些模板. 有可用于 `测试用例`_ 和 `资源文件`_ 的, 资源模板还可以用于创建 `测试套件初始化文件`_. 7 | 8 | 模板可使用 `HTML格式`_ 和 `TSV格式`_, 并可自由自定义. `纯文本格式`_ 没有模板, 因为纯文本没有太多样板, 所以模板没什么作用. 9 | 10 | 11 | `testcase_template.html`__ 12 | HTML格式的测试用例文件模板 13 | 14 | `testcase_template.tsv`__ 15 | TSV格式的测试用例文件模板 16 | 17 | `resource_template.html`__ 18 | HTML格式的资源文件模板 19 | 20 | `resource_template.tsv`__ 21 | TSV格式的资源文件模板 22 | 23 | `attd_template.html`__ 24 | 用于创建验收测试驱动开发(ATDD)风格的测试用例. 这种测试由高层不带参数的关键字创建, 25 | 相应的模板也做了简化. 26 | 27 | 可通过本手册获取到模板文件, 它们包含在了源代码发行包中, 也可在 `项目页面`__ 找到. 28 | 29 | __ ../../templates/testcase_template.html 30 | __ ../../templates/testcase_template.tsv 31 | __ ../../templates/resource_template.html 32 | __ ../../templates/resource_template.tsv 33 | __ ../../templates/atdd_template.html 34 | __ https://github.com/robotframework/robotframework/tree/master/templates 35 | -------------------------------------------------------------------------------- /GettingStarted/Demonstrations.rst: -------------------------------------------------------------------------------- 1 | 其它资料 2 | ========= 3 | 4 | `Quick Start Guide `__ 5 | 通过一个可执行的demo来介绍Robot Framework最核心的内容, 初学者推荐阅读. 6 | 7 | .. note:: 以下是其它的一些资料, 都是英文的, 有的因为国情还不一定打的开, 就不翻译了. 8 | 9 | `Robot Framework demo `__ 10 | Simple example test cases. Demonstrates also creating custom test libraries. 11 | 12 | `Web testing demo `__ 13 | Demonstrates how to create tests and higher level keywords. The system 14 | under test is a simple web page that is tested using Selenium2Library_. 15 | 16 | `SwingLibrary demo `_ 17 | Demonstrates using SwingLibrary_ for testing Java GUI applications. 18 | 19 | `ATDD with Robot Framework `__ 20 | Demonstrates how to use Robot Framework when following 21 | Acceptance Test Driven Development (ATDD) process. -------------------------------------------------------------------------------- /about.rst: -------------------------------------------------------------------------------- 1 | 关于本手册 2 | ========== 3 | 4 | 本手册是 `Robot Framework `_ 用户手册的中文翻译版. 5 | 6 | 想直接阅读英文的请点击 `这里 `_ 7 | 8 | 获取源码 9 | -------- 10 | 11 | 你可以在 `GitHub `_ 上获取到本手册的源码文件 12 | 13 | - `UserGuide `_ 14 | 15 | - `用户手册 `_ 16 | 17 | 如果你觉得这份手册对你有帮助, 请Star一个以示鼓励. 觉得有翻译不当之处也敬请指正. 18 | 19 | 源文件格式 20 | ---------- 21 | 22 | 原英文文档使用的是reStructureText标准格式, 中文文档使用了Sphinx文档工具, 虽然文件的格式是一样的, 但是其中某些标记和原文有所不同, 特别是文档的内部链接形式. 原文整个文档是一个页面, 中文文档分章节显示. 23 | 24 | 翻译说明 25 | -------- 26 | 27 | 尽量做到按原文翻译, 有些地方感觉原文实在太啰嗦了, 在不影响理解的情况下有所省略. 28 | 29 | 术语的翻译 30 | ^^^^^^^^^^ 31 | 32 | 术语的翻译尽量使用通用的译法, 一般确定不会影响歧义的都直接翻译, 有的会在第一次出现时备注原英文, 有的不方便直译的保留原文或者其它更熟悉的缩写替代. 33 | 34 | 例如: free keyword arguments 如果后面翻译为"关键字参数"难免会和测试关键字产生混淆, 除了少数地方直译为"任意命名参数", 后面一般都使用大家都熟悉的 ``**kwargs`` 写法指代. 35 | 36 | 37 | 表格和代码示例 38 | ^^^^^^^^^^^^^^ 39 | 40 | 文档中出现的大量代码示例和表格, 绝大部分都没有做任何翻译, 因为这些内容都很简单, 且大多数都是无法翻译的代码, 如果只翻译部分, 混杂一起反而很难看. 41 | 表格部分的情况和代码类似, 而且reST中编辑表格是一件比较痛苦的事情, 翻成中文原表格会出现无法对齐的问题, 需要额外的工作量. 42 | -------------------------------------------------------------------------------- /code_examples/check_test_times.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Usage: check_test_times.py seconds inpath [outpath] 4 | 5 | Reads test execution result from an output XML file and checks that no test 6 | took longer than given amount of seconds to execute. 7 | 8 | Optional `outpath` specifies where to write processed results. If not given, 9 | results are written over the original file. 10 | """ 11 | 12 | import sys 13 | from robot.api import ExecutionResult, ResultVisitor 14 | 15 | 16 | class ExecutionTimeChecker(ResultVisitor): 17 | 18 | def __init__(self, max_seconds): 19 | self.max_milliseconds = max_seconds * 1000 20 | 21 | def visit_test(self, test): 22 | if test.status == 'PASS' and test.elapsedtime > self.max_milliseconds: 23 | test.status = 'FAIL' 24 | test.message = 'Test execution took too long.' 25 | 26 | 27 | def check_tests(seconds, inpath, outpath=None): 28 | result = ExecutionResult(inpath) 29 | result.visit(ExecutionTimeChecker(float(seconds))) 30 | result.save(outpath) 31 | 32 | 33 | if __name__ == '__main__': 34 | try: 35 | check_tests(*sys.argv[1:]) 36 | except TypeError: 37 | print __doc__ 38 | -------------------------------------------------------------------------------- /Appendices/BooleanArguments.rst: -------------------------------------------------------------------------------- 1 | .. Boolean arguments 2 | 3 | 布尔型参数 4 | ================= 5 | 6 | Robot Framework的标准库中有很多关键字接受一个布尔型的值, true或false. 如果参数是字符串的形式提供, 则如果该字符串是空的, 或者转为小写后等于 `false` 或 `no`, 则表明该值是`false`. 其它的字符串一律视为`true`. 如果参数是其它类型, 则这些值按照 `Python语言的规则 `__ 来判断. 7 | 8 | 关键字还可以接受除了`false` 和 `no` 之外的其它特殊字符串为false. 例如, 内置_ 关键字 `Should Be True`, 如果它的 `values` 参数被传递字符串 `no values`, 则视作false. 9 | 10 | .. sourcecode:: robotframework 11 | 12 | *** Keywords *** 13 | True examples 14 | Should Be Equal ${x} ${y} Custom error values=True # Strings are generally true. 15 | Should Be Equal ${x} ${y} Custom error values=yes # Same as the above. 16 | Should Be Equal ${x} ${y} Custom error values=${TRUE} # Python `True` is true. 17 | Should Be Equal ${x} ${y} Custom error values=${42} # Numbers other than 0 are true. 18 | 19 | False examples 20 | Should Be Equal ${x} ${y} Custom error values=False # String `false` is false. 21 | Should Be Equal ${x} ${y} Custom error values=no # Also string `no` is false. 22 | Should Be Equal ${x} ${y} Custom error values=${EMPTY} # Empty string is false. 23 | Should Be Equal ${x} ${y} Custom error values=${FALSE} # Python `False` is false. 24 | Should Be Equal ${x} ${y} Custom error values=no values # Special false string in this context. 25 | 26 | 注意, 在Robot Framework 2.9 之前的版本中, 布尔值的判断并不统一. 有的关键字遵守上面的规则, 但是有的简单地把所有非空字符串(包括`false` 和 `no`)都视作true. 27 | 28 | -------------------------------------------------------------------------------- /roles.rst: -------------------------------------------------------------------------------- 1 | .. Roles are used like :role:`example` or via aliases. Styled in userguide.css. 2 | 3 | Standard reST roles 4 | ------------------- 5 | 6 | Standard roles are used as much as possible. There are others but these 7 | make most sense in our context. For more information see 8 | http://docutils.sourceforge.net/docs/ref/rst/roles.html 9 | 10 | code Code, CLI examples, GUI entries, variables, etc. Alias `example` 11 | configured below. 12 | literal Program and environment variable names (e.g. :literel:`rebot`). 13 | Alias ``example``. 14 | emphasis In practice italics. Used with some terms. Alias *example*. 15 | strong In practice bold. Alias **example**. 16 | 17 | Sphinx roles 18 | ------------ 19 | 20 | Need to be defined here but using these eases migrating to Sphinx in the 21 | future. For details see http://sphinx-doc.org/markup/inline.html 22 | 23 | option Command line options. Notice that examples should use code role. 24 | Notice also that standard reST uses option class in option lists. 25 | file File and directory paths. 26 | 27 | Custom roles 28 | ------------ 29 | 30 | Our own custom rules. 31 | 32 | setting Setting names (e.g. :setting:`Library`, :setting:`[Setup]`). 33 | name Keyword, library, test case and test suite names 34 | codesc Formatted like standard code role but supports escaping. 35 | For example, output of :codesc:`\`example\`` is `example`, not 36 | \`example\`. 37 | 38 | .. default-role:: code 39 | .. role:: option 40 | .. role:: file 41 | .. role:: setting 42 | .. role:: name 43 | .. role:: codesc 44 | -------------------------------------------------------------------------------- /SupportingTools/Testdoc.rst: -------------------------------------------------------------------------------- 1 | 2 | 3 | .. Test data documentation tool (Testdoc) 4 | 5 | .. _testdoc: 6 | 7 | 测试数据文档工具(Testdoc) 8 | ========================= 9 | 10 | .. contents:: 11 | :depth: 1 12 | :local: 13 | 14 | Testdoc是Robot Framework内置的工具, 用于从测试用例生成HTML文档. 生成的文档包含名称, 每个测试套件和测试用例的文档和元数据, 以及顶层关键字和它们的参数. 15 | 16 | .. General usage 17 | 18 | 用法 19 | ---- 20 | 21 | .. Synopsis 22 | 23 | 总览 24 | ~~~~ 25 | 26 | :: 27 | 28 | python -m robot.testdoc [options] data_sources output_file 29 | 30 | .. Options 31 | 32 | 选项 33 | ~~~~ 34 | 35 | -T, --title Set the title of the generated documentation. 36 | Underscores in the title are converted to spaces. 37 | The default title is the name of the top level suite. 38 | -N, --name <name> Override the name of the top level test suite. 39 | -D, --doc <doc> Override the documentation of the top level test suite. 40 | -M, --metadata <name:value> Set/override free metadata of the top level test suite. 41 | -G, --settag <tag> Set given tag(s) to all test cases. 42 | -t, --test <name> Include tests by name. 43 | -s, --suite <name> Include suites by name. 44 | -i, --include <tag> Include tests by tags. 45 | -e, --exclude <tag> Exclude tests by tags. 46 | -h, --help Print this help in the console. 47 | 48 | 除了 :option:`--title` 以外的所有选项的语义都和在 :ref:`执行测试用例 <configuring execution>` 时使用完全一样. 49 | 50 | .. _generating documentation: 51 | 52 | 生成文档 53 | -------- 54 | 55 | 生成文档的数据源可以是单个文件, 单个目录, 也可以是多个文件和目录. 所有这些情况, 最后那个参数都必须是最终文档输出要写入的文件. 56 | 57 | Testdoc适用于Robot Framework支持的所有解释器(Python, Jython and IronPython). 它可以以python模块的方式执行, 如 ``python -m robot.testdoc``, 也可以当作一个脚本来执行, 例如: ``python path/robot/testdoc.py``. 58 | 59 | 示例:: 60 | 61 | python -m robot.testdoc my_test.html testdoc.html 62 | jython -m robot.testdoc --name smoke_tests --include smoke path/to/my_tests smoke.html 63 | ipy path/to/robot/testdoc.py first_suite.txt second_suite.txt output.html 64 | -------------------------------------------------------------------------------- /Appendices/TimeFormat.rst: -------------------------------------------------------------------------------- 1 | .. Time format 2 | 3 | 时间格式 4 | =========== 5 | 6 | Robot Framework有一套自己的时间格式, 既灵活且易懂. 这个格式被用于好几个关键字中(例如, BuiltIn_ 关键字 :name:`Sleep` 和 :name:`Wait Until Keyword Succeeds`), DateTime_ 库, 以及 `timeouts`_. 7 | 8 | has its own time format that is both flexible to use and easy 9 | to understand. It is used by several keywords (for example, BuiltIn_ keywords 10 | :name:`Sleep` and :name:`Wait Until Keyword Succeeds`), DateTime_ library, and 11 | `timeouts`_. 12 | 13 | .. Time as number 14 | 15 | 作为数字的时间 16 | -------------- 17 | 18 | 时间总是可以用数字来表示, 此时解释为秒数. 整数和浮点数都可以, 并且可以是真正的数字, 也可以是包含数字值的字符串. 19 | 20 | .. Time as time string 21 | 22 | 时间字符串 23 | ------------------- 24 | 25 | 以时间字符串来表示时间意味着使用类似于 `2 minutes 42 seconds` 这种格式, 这种情况通常比纯的秒数更容易懂. 比如说, `4200` 秒有多长恐怕很难理解, 但是 `1 hour 10 minutes` 就清楚的多了. 26 | 27 | 这种格式的基本思想就是前面有一个数字, 然后跟一个表示时间单位的文本. 数字部分可以是整数或浮点数, 整个格式不区分大小写, 也忽略空格, 同时还可以添加 `-` 前缀来表示负数. 28 | 29 | 可用的表示时间的单位有: 30 | 31 | * days, day, d 32 | * hours, hour, h 33 | * minutes, minute, mins, min, m 34 | * seconds, second, secs, sec, s 35 | * milliseconds, millisecond, millis, ms 36 | 37 | 示例:: 38 | 39 | 1 min 30 secs 40 | 1.5 minutes 41 | 90 s 42 | 1 day 2 hours 3 minutes 4 seconds 5 milliseconds 43 | 1d 2h 3m 4s 5ms 44 | - 10 seconds 45 | 46 | "timer" 字符串 47 | ---------------------- 48 | 49 | Robot Framework 2.8.5 版本开始, 时间还可以用时钟格式 `hh:mm:ss.mil` 来表示. 这种格式里的小时部分和微秒部分是可选的, 开头部分的0在没有意义的时候可以省略. 可通过前缀 `-` 表示负数. 50 | 51 | 下表中左边timer格式和右边时间字符串格式的值是等价的: 52 | 53 | .. table:: Timer and time string examples 54 | :class: tabular 55 | 56 | ============ ====================================== 57 | Timer Time string 58 | ============ ====================================== 59 | 00:00:01 1 second 60 | 01:02:03 1 hour 2 minutes 3 seconds 61 | 1:00:00 1 hour 62 | 100:00:00 100 hours 63 | 00:02 2 seconds 64 | 42:00 42 minutes 65 | 00:01:02.003 1 minute 2 seconds 3 milliseconds 66 | 00:01.5 1.5 seconds 67 | -01:02.345 \- 1 minute 2 seconds 345 milliseconds 68 | ============ ====================================== 69 | -------------------------------------------------------------------------------- /SupportingTools/LoggingLibrary.py: -------------------------------------------------------------------------------- 1 | class LoggingLibrary: 2 | """Library for logging messages. 3 | 4 | = Table of contents = 5 | 6 | - `Usage` 7 | - `Valid log levels` 8 | - `Examples` 9 | - `Importing` 10 | - `Shortcuts` 11 | - `Keywords` 12 | 13 | = Usage = 14 | 15 | This library has several keyword, for example `Log Message`, for logging 16 | messages. In reality the library is used only for _Libdoc_ demonstration 17 | purposes. 18 | 19 | = Valid log levels = 20 | 21 | Valid log levels are ``INFO``, ``DEBUG``, and ``TRACE``. The default log 22 | level can be set during `importing`. 23 | 24 | = Examples = 25 | 26 | Notice how keywords are linked from examples. 27 | 28 | | `Log Message` | My message | | | 29 | | `Log Two Messages` | My message | Second message | level=DEBUG | 30 | | `Log Messages` | First message | Second message | Third message | 31 | """ 32 | ROBOT_LIBRARY_VERSION = '0.1' 33 | 34 | def __init__(self, default_level='INFO'): 35 | """The default log level can be given at library import time. 36 | 37 | See `Valid log levels` section for information about available log 38 | levels. 39 | 40 | Examples: 41 | 42 | | =Setting= | =Value= | =Value= | =Comment= | 43 | | Library | LoggingLibrary | | # Use default level (INFO) | 44 | | Library | LoggingLibrary | DEBUG | # Use the given level | 45 | """ 46 | self.default_level = self._verify_level(default_level) 47 | 48 | def _verify_level(self, level): 49 | level = level.upper() 50 | if level not in ['INFO', 'DEBUG', 'TRACE']: 51 | raise RuntimeError("Invalid log level'%s'. Valid levels are " 52 | "'INFO', 'DEBUG', and 'TRACE'") 53 | return level 54 | 55 | def log_message(self, message, level=None): 56 | """Writes given message to the log file using the specified log level. 57 | 58 | The message to log and the log level to use are defined using 59 | ``message`` and ``level`` arguments, respectively. 60 | 61 | If no log level is given, the default level given during `library 62 | importing` is used. 63 | """ 64 | level = self._verify_level(level) if level else self.default_level 65 | print "*%s* %s" % (level, message) 66 | 67 | def log_two_messages(self, message1, message2, level=None): 68 | """Writes given messages to the log file using the specified log level. 69 | 70 | See `Log Message` keyword for more information. 71 | """ 72 | self.log_message(message1, level) 73 | self.log_message(message2, level) 74 | 75 | def log_messages(self, *messages): 76 | """Logs given messages using the log level set during `importing`. 77 | 78 | See also `Log Message` and `Log Two Messages`. 79 | """ 80 | for msg in messages: 81 | self.log_message(msg) 82 | -------------------------------------------------------------------------------- /GettingStarted/Introduction.rst: -------------------------------------------------------------------------------- 1 | 介绍 2 | ==== 3 | 4 | Robot Framework 是一个基于Python的、可扩展的、关键字驱动的测试自动化框架,用于端到端的验收测试或者验收驱动测试开发(ATDD)中。 5 | 6 | 7 | 为什么选择Robot Framework 8 | ------------------------- 9 | 10 | * 表格式的语法简单易用,以统一的方式 :ref:`创建测试用例 <creating test cases>` 11 | * 可以通过现有关键字创建可复用的 :ref:`高层关键字 <creating user keywords>` 12 | * 提供了直观的HTML格式的 :ref:`测试报告 <report file>` 和 :ref:`日志文件 <log file>` 13 | * 作为一个测试平台,是应用无关的 14 | * 提供了 :ref:`测试库API <creating test libraries>`,可以轻易地使用Python或者Java创建自定义的测试库 15 | * 提供了 :ref:`命令行接口 <executing test cases>` 和基于XML的 :ref:`输出文件 <output file>`,可以与现有框架集成(如持续集成系统) 16 | * 提供了多种测试库支持,如用于web测试的Selenium,Java GUI测试,启动进程,Telnet,SSH等 17 | * 可以创建 :ref:`数据驱动的测试用例 <data-driven style>` 18 | * 内置支持 :ref:`变量 <variables>`,在不同的环境中特别实用 19 | * 提供 :ref:`标签 <tagging test cases>` 来分类和 :ref:`选择测试用例 <selecting test cases>` 20 | * 非常容易与源码控制系统集成,因为 :ref:`测试套件 <creating test suites>` 就是文件夹和文本文件 21 | * 提供了 :ref:`用例级别 <test setup and teardown>` 和 :ref:`测试套件级别 <suite setup and teardown>` 的setup和teardown 22 | * 模块化的架构,支持针对不同接口的应用程序创建测试 23 | 24 | 25 | 整体架构 26 | -------- 27 | 28 | Robot Framework是一个通用的,应用和技术无关的框架。它的高度模块化的架构如下图所示: 29 | 30 | .. image:: architecture.png 31 | 32 | 33 | 测试数据(:ref:`test data <test data>`)使用非常简单、易于编辑的表格格式. Robot Framework会解析测试数据, :ref:`执行测试用例 <executing test cases>`, 并生成日志和报告. 框架本身对测试对象一无所知, 而是通过 :ref:`测试库 <creating test libraries>` 与其交互. 测试库可能是直接使用被测应用程序的接口, 也可以使用其它底层的测试工具作为驱动. 34 | 35 | 36 | 示例截图 37 | -------- 38 | 39 | 以下是 :ref:`测试数据 <test data>` 和 :ref:`测试报告 <report file>` 和 :ref:`测试日志 <log file>` 的截图: 40 | 41 | .. figure:: testdata_screenshots.png 42 | :alt: testdata_screenshots 43 | 44 | 测试用例文件 45 | 46 | 47 | .. figure:: screenshots.png 48 | :alt: screenshots 49 | 50 | 执行报告和日志 51 | 52 | 53 | 54 | 如何获取更多信息 55 | ------------------------ 56 | 57 | 项目页面 58 | ~~~~~~~ 59 | 60 | 获取Robot Framework更多权威资讯的首要地方当然是其官网, http://robotframework.org. 项目源码是托管在 `GitHub`_ 61 | 62 | .. _GitHub: https://github.com/robotframework/robotframework 63 | 64 | .. _mailing lists: 65 | 66 | 邮件列表 67 | ~~~~~~~~ 68 | 69 | .. note:: 一般邮件列表都是使用英文交流, 能加入的同学肯定不需要翻译了, 这段偷懒略过. 70 | 71 | 72 | There are several Robot Framework mailing lists where to ask and 73 | search for more information. The mailing list archives are open for 74 | everyone (including the search engines) and everyone can also join 75 | these lists freely. Only list members can send mails, though, and to 76 | prevent spam new users are moderated which means that it might take a 77 | little time before your first message goes through. Do not be afraid 78 | to send question to mailing lists but remember `How To Ask Questions 79 | The Smart Way`__. 80 | 81 | robotframework-users__ 82 | General discussion about all Robot Framework related 83 | issues. Questions and problems can be sent to this list. Used also 84 | for information sharing for all users. 85 | 86 | robotframework-announce__ 87 | An announcements-only mailing list where only moderators can send 88 | messages. All announcements are sent also to the 89 | robotframework-users mailing list so there is no need to join both 90 | lists. 91 | 92 | robotframework-devel__ 93 | Discussion about Robot Framework development. 94 | 95 | __ http://www.catb.org/~esr/faqs/smart-questions.html 96 | __ http://groups.google.com/group/robotframework-users 97 | __ http://groups.google.com/group/robotframework-announce 98 | __ http://groups.google.com/group/robotframework-devel -------------------------------------------------------------------------------- /SupportingTools/Tidy.rst: -------------------------------------------------------------------------------- 1 | .. _tidy: 2 | .. _test data clean-up tool: 3 | 4 | 测试数据整理工具(Tidy) 5 | ====================== 6 | 7 | .. contents:: 8 | :depth: 1 9 | :local: 10 | 11 | Tidy是Robot Framework内置的用于整理和转换测试数据文件的工具. 12 | 13 | 工具执行结果的默认输出是标准输出流, 不过自从Robot Framework 2.7.5版本后可以将输出文件作为可选参数给出. 14 | 15 | 如果使用了选项 :option:`--inplace` 或 :option:`--recursive`, 文件就会就地修改(也就是原文件会被整理后的文件就地覆盖). 16 | 17 | .. General usage 18 | 19 | 用法 20 | ---- 21 | 22 | .. Synopsis 23 | 24 | 总览 25 | ~~~~ 26 | 27 | :: 28 | 29 | python -m robot.tidy [options] inputfile 30 | python -m robot.tidy [options] inputfile [outputfile] 31 | python -m robot.tidy --inplace [options] inputfile [more input files] 32 | python -m robot.tidy --recursive [options] directory 33 | 34 | .. Options 35 | 36 | 选项 37 | ~~~~ 38 | 39 | -i, --inplace Tidy given file(s) so that original file(s) are overwritten 40 | (or removed, if the format is changed). When this option is 41 | used, it is possible to give multiple input files. Examples:: 42 | 43 | python -m robot.tidy --inplace tests.html 44 | python -m robot.tidy --inplace --format txt *.html 45 | 46 | -r, --recursive Process given directory recursively. Files in the directory 47 | are processed in place similarly as when :option:`--inplace` 48 | option is used. 49 | -f, --format <robot|txt|html|tsv> 50 | Output file format. If the output file is given explicitly, 51 | the default value is got from its extension. Otherwise 52 | the format is not changed. 53 | -p, --use-pipes Use a pipe character (|) as a cell separator in the txt format. 54 | -s, --spacecount <number> 55 | The number of spaces between cells in the txt format. 56 | New in Robot Framework 2.7.3. 57 | -l, --lineseparator <native|windows|unix> 58 | Line separator to use in outputs. The default is 'native'. 59 | 60 | - *native*: use operating system's native line separators 61 | - *windows*: use Windows line separators (CRLF) 62 | - *unix*: use Unix line separators (LF) 63 | 64 | New in Robot Framework 2.7.6. 65 | -h, --help Show this help. 66 | 67 | .. Alternative execution 68 | 69 | 其它的执行方式 70 | ~~~~~~~~~~~~~~ 71 | 72 | 虽然Tidy在上面总览只用了Python来执行, 但是它还支持Jython和IronPython. 而且上面Tide是作为已安装的模块来执行的(``python -m robot.tidy``), 实际还可以当作脚本来执行:: 73 | 74 | 75 | python path/robot/tidy.py [options] arguments 76 | 77 | 78 | 如果你是 :ref:`手动安装 <manual installation>`, 或者只是把 :file:`robot` 目录拷贝到系统某个目录时, 按脚本执行就会非常有用. 79 | 80 | .. Output encoding 81 | 82 | 输出的编码 83 | ~~~~~~~~~~ 84 | 85 | 所有的输出文件都使用UTF-8编码写入, 控制台输出则使用当前控制台的编码. 86 | 87 | 88 | .. Cleaning up test data 89 | 90 | 整理测试数据 91 | ------------ 92 | 93 | 使用HTML编辑器或者手工编写的测试用例文件都可以使用Tidy来标准化. Tidy总是使用一致的题头, 一致顺序的settings, 以及在表格和单元格中间使用一致的空格. 94 | 95 | 96 | 一些例子:: 97 | 98 | python -m robot.tidy messed_up_tests.html cleaned_tests.html 99 | python -m robot.tidy --inplace tests.txt 100 | 101 | .. Changing test data format 102 | 103 | 转换测试数据格式 104 | ---------------- 105 | 106 | Robot Framework支持多种格式的测试数据, 包括HTML, TSV和TXT. Tidy可以轻松地在这些格式之间转换. 输入格式总是基于输入文件的扩展名来判断, 输出的格式则使用 :option:`--format` 选项来指定, 如果不指定该选项, 则默认的格式将从可能的输出文件扩展名来获取. 107 | 108 | 109 | 示例:: 110 | 111 | python -m robot.tidy tests.html tests.txt 112 | python -m robot.tidy --format txt --inplace tests.html 113 | python -m robot.tidy --format tsv --recursive mytests 114 | -------------------------------------------------------------------------------- /ExecutingTestCases/PostProcessing.rst: -------------------------------------------------------------------------------- 1 | .. _rebot: 2 | .. _post-processing outputs: 3 | 4 | 测试输出的处理 5 | ============== 6 | 7 | 测试执行过程中生成的 :ref:`XML output files` 可以使用Rebot工具来处理, 该工具集成到了Robot Framework中. 它在测试执行时自动调用生成测试报告和日志文件, 也可以单独使用, 生成自定义的报告和日志, 或者用来将测试结果组合合并在一起. 8 | 9 | .. contents:: 10 | :depth: 2 11 | :local: 12 | 13 | .. Using Rebot 14 | 15 | 使用Rebot 16 | ----------- 17 | 18 | .. Synopsis 19 | 20 | 概要 21 | ~~~~~ 22 | 23 | :: 24 | 25 | rebot [options] robot_outputs 26 | python|jython|ipy -m robot.rebot [options] robot_outputs 27 | python|jython|ipy path/to/robot/rebot.py [options] robot_outputs 28 | java -jar robotframework.jar rebot [options] robot_outputs 29 | 30 | 如上所列, 使用Rebot最常见的用法是调用 :ref:`执行脚本 <runner script>`: ``rebot``. 同时可以使用Python解释器直接调用模块 :ref:`robot.rebot module <executing installed robot module>` 或 :ref:`robot/rebot.py 文件 <executing installed robot directory>`. 最后还可以通过Java调用 :ref:`standalone JAR distribution`. 31 | 32 | .. note:: 33 | Robot Framework 3.0 版本之前, 安装的 ``rebot`` 脚本只用于Python解释器, 34 | Jython和IronPython对应的脚本分别是 ``jyrebot`` 和 ``ipyrebot``. 35 | 目前这两个脚本也还是会安装, 不过未来的计划是逐渐淘汰并最终删除. 36 | 37 | .. Specifying options and arguments 38 | 39 | 指定选项和参数 40 | ~~~~~~~~~~~~~~~ 41 | 42 | 使用Rebot的基础语法完全等同于 :ref:`执行测试 <executing test cases>`, 并且大部分的命令行选项也都相同. 主要的区别就是Rebot的执行参数是 :ref:`XML output files` 而不是测试文件或目录. 43 | 44 | 45 | .. Return codes with Rebot 46 | 47 | 返回码 48 | ~~~~~~ 49 | 50 | Rebot的返回码和 :ref:`执行测试的返回码 <return codes>` 一样. 51 | 52 | 53 | .. Creating different reports and logs 54 | 55 | 创建不同的报告和日志 56 | -------------------- 57 | 58 | 可以调用Rebot生成和测试结束后自动生成的一样的报告和日志, 显然这样做意义不大. 但是如果想要有选择性的生成报告, 例如, 一份全部用例的报告和一份用例子集的报告, 这时就很有用:: 59 | 60 | rebot output.xml 61 | rebot path/to/output_file.xml 62 | rebot --include smoke --name Smoke_Tests c:\results\output.xml 63 | 64 | 另一个常见用途是在运行测试时只生成output文件(使用选项 ``--log NONE --report NONE``), 把生成日志和报告文件放在后面再执行. 例如, 测试可以在不同的环境执行, 最终把output文件集中汇总到一个地方, 然后在那里创建报告和日志. 如果使用Jython运行测试生成报告和日志耗时较长也可以这样做. 总之, 在执行时禁止日志和报告生成, 改为事后生成, 可以节省很多时间, 同时也占用更少内存. 65 | 66 | .. Combining outputs 67 | 68 | 联合输出 69 | -------- 70 | 71 | Rebot的一个重要的特性功能是能够将不同的测试轮次的输出联合(combine)起来. 例如, 同样的测试用例在不同的环境下运行多次, 最终联合所有的output文件汇总输出一份报告. 72 | 73 | 联合输出非常简单, 只要将需要联合在一起的多个output文件一起作为参数传递即可:: 74 | 75 | rebot output1.xml output2.xml 76 | rebot outputs/*.xml 77 | 78 | 当联合输出时, 将自动创建一个新的顶层测试套件, 把要联合的套件都作为子套件包含在内. 79 | 这和 :ref:`一次执行多个测试文件或目录 <specifying test data to be executed>` 是一样的, 也会使用 ``&`` 和空格来连接各子套件的名字, 生成这个新顶层套件的名字. 可以想象这个自动生成的名字通常不会很好看, 所以最好还是通过选项 80 | :option:`--name` 指定一个更有意义的名字:: 81 | 82 | rebot --name Browser_Compatibility firefox.xml opera.xml safari.xml ie.xml 83 | rebot --include smoke --name Smoke_Tests c:\results\*.xml 84 | 85 | __ `Specifying test data to be executed`_ 86 | 87 | 88 | 合并输出 89 | -------- 90 | 91 | 如果同样的测试再次执行(re-execute), 或者某一个套件分开执行(executed in pieces), 使用上述的联合输出结果创建顶层测试套件是没必要的. 这种情况下, 更好的做法是将所有结果合并(merge)到一起. 92 | 93 | 使用 :option:`--merge` 选项来告诉Rebot将多个output文件合并来, 该选项不带参数, 其它参数的使用则和正常情况下一样:: 94 | 95 | rebot --merge --name Example --critical regression original.xml merged.xml 96 | 97 | 在实践中合并是如何使用的两个主要场景将在下面章节中讨论. 98 | 99 | .. Merging re-executed tests 100 | 101 | 合并重新执行的用例 102 | ~~~~~~~~~~~~~~~~~~ 103 | 104 | 有时候需要重新执行测试用例的一个子集, 例如, 当bug(可能是待测系统的, 也可能是测试本身的bug)修复后的再次执行. 这时可以 :ref:`选择性的执行用例`, 通过名字(:option:`--test` 和 :option:`--suite` 选项), 或通过标签(:option:`--include` 和 :option:`--exclude`), 或通过前次执行状态(:option:`--rerunfailed`). 105 | 106 | 使用默认的 :ref:`联合输出` 报告的做法在这种情况下有些不妥, 主要问题是组合结果是分开的套件, 并且可能已经修复的失败仍然列在其中. 这种情况使用 :option:`--merge (-R)` 更合适. 107 | 108 | 这样merge的结果是, 同一个用例, 后面的执行结果将替代前面的. 使用个实际的例子更容易解释清楚, 下面同时用到了 :option:`--rerunfailed` 和 :option:`--merge`:: 109 | 110 | robot --output original.xml tests # first execute all tests 111 | robot --rerunfailed original.xml --output rerun.xml tests # then re-execute failing 112 | rebot --merge original.xml rerun.xml # finally merge results 113 | 114 | 合并后的测试结果消息将包含一个标注, 提示结果被替代了. 同时该消息还将展示该测试旧的状态和消息. 115 | 116 | 合并结果必须有相同的顶层测试套件. 那些要合并的用例和套件, 如果在原始output中没找到, 则会追加到结果中. 实际情况在下面章节中讨论. 117 | 118 | .. note:: 合并重新执行的结果是Robot Framework 2.8.4新特性功能. 119 | 在Robot Framework 2.8.6之前, 合并使用的是已被废弃的选项 :option:`--rerunmerge` 实现, 同时新的测试和套件在合并输出中会被略过. 120 | 121 | 122 | .. Merging suites executed in pieces 123 | 124 | 合并零碎执行的测试套件 125 | ~~~~~~~~~~~~~~~~~~~~~~ 126 | 127 | 合并选项 :option:`--merge` 的另一个重要用途是将一个零碎执行的测试套件的结果合并起来. 例如, 一个套件分使用 :option:`--include` 和 :option:`--exclude` 执行:: 128 | 129 | robot --include smoke --output smoke.xml tests # first run some tests 130 | robot --exclude smoke --output others.xml tests # then run others 131 | rebot --merge smoke.xml others.xml # finally merge results 132 | 133 | 合并后, 最终的output文件将包含所有测试用例和测试套件的结果. 如果某些用例多次出现, 则后面的会覆盖前面的(如上节). 同样, 这种合并策略要求所有output文件的顶层测试套件是同一个. 134 | -------------------------------------------------------------------------------- /Appendices/AvailableSettings.rst: -------------------------------------------------------------------------------- 1 | .. All available settings in test data 2 | 3 | 可用配置项 4 | ========== 5 | 6 | .. contents:: 7 | :depth: 2 8 | :local: 9 | 10 | .. _setting table: 11 | 12 | 配置表 13 | ------ 14 | 15 | Setting表格是用来为测试套件和测试用例导入测试库, 资源文件和变量文件, 同时也给它们定义元数据. 该表可存在于测试用例文件和资源文件中. 16 | 17 | 注意, 在资源文件中, Setting表只能包含导入(测试库, 资源文件和变量文件)相关的配置项. 18 | 19 | 20 | .. table:: Settings available in the Setting table 21 | :class: tabular 22 | 23 | +-----------------+--------------------------------------------------------+ 24 | | Name | Description | 25 | +=================+========================================================+ 26 | | Library | 用来 :ref:`importing libraries`. | 27 | +-----------------+--------------------------------------------------------+ 28 | | Resource | 用来 :ref:`taking resource files into use`. | 29 | +-----------------+--------------------------------------------------------+ 30 | | Variables | 用来 :ref:`taking variable files into use`. | 31 | +-----------------+--------------------------------------------------------+ 32 | | Documentation | 用来为 :ref:`测试套件 <test suite documentation>` | 33 | | | :ref:`资源文件 <documenting resource files>` 设置文档. | 34 | +-----------------+--------------------------------------------------------+ 35 | | Metadata | 用来设置 :ref:`free test suite metadata`. | 36 | +-----------------+--------------------------------------------------------+ 37 | | Suite Setup | 用来指定 :ref:`suite setup <suite setup>`. | 38 | +-----------------+--------------------------------------------------------+ 39 | | Suite Teardown | 用来指定 :ref:`suite teardown <suite setup>`. | 40 | +-----------------+--------------------------------------------------------+ 41 | | Force Tags | Used for specifying forced values for tags when | 42 | | | :ref:`tagging test cases`. | 43 | +-----------------+--------------------------------------------------------+ 44 | | Default Tags | Used for specifying default values for tags when | 45 | | | :ref:`tagging test cases`. | 46 | +-----------------+--------------------------------------------------------+ 47 | | Test Setup | 用来指定一个缺省的 :ref:`test setup <test setup>`. | 48 | +-----------------+--------------------------------------------------------+ 49 | | Test Teardown | 用来指定一个缺省的 :ref:`test teardown <test setup>`. | 50 | +-----------------+--------------------------------------------------------+ 51 | | Test Template | 用来为测试用例指定一个缺省的 :ref:`template keyword` | 52 | +-----------------+--------------------------------------------------------+ 53 | | Test Timeout | 用来指定一个缺省的 :ref:`test case timeout`. | 54 | +-----------------+--------------------------------------------------------+ 55 | 56 | .. note:: 所有的配置名字都可在结尾使用冒号, 例如: :setting:`Documentation:`. 57 | 这个冒号是可选的, 主要是为了让配置更可读, 特别是在使用纯文本格式时. 58 | 59 | .. Test Case table 60 | 61 | 测试用例表 62 | ---------- 63 | 64 | 测试用例表中的配置总是针对的当前特定的测试用例. 其中的某些配置将会覆盖在Settings表中定义的默认值. 65 | 66 | .. table:: Settings available in the Test Case table 67 | :class: tabular 68 | 69 | +-----------------+--------------------------------------------------------+ 70 | | Name | Description | 71 | +=================+========================================================+ 72 | | [Documentation] | Used for specifying a `test case documentation`_. | 73 | +-----------------+--------------------------------------------------------+ 74 | | [Tags] | Used for `tagging test cases`_. | 75 | +-----------------+--------------------------------------------------------+ 76 | | [Setup] | Used for specifying a `test setup`_. | 77 | +-----------------+--------------------------------------------------------+ 78 | | [Teardown] | Used for specifying a `test teardown`_. | 79 | +-----------------+--------------------------------------------------------+ 80 | | [Template] | Used for specifying a `template keyword`_. | 81 | +-----------------+--------------------------------------------------------+ 82 | | [Timeout] | Used for specifying a `test case timeout`_. | 83 | +-----------------+--------------------------------------------------------+ 84 | 85 | .. Keyword table 86 | 87 | 关键字表 88 | -------- 89 | 90 | 关键字表中的配置是针对的当前特定的用户关键字. 91 | 92 | .. table:: Settings available in the Keyword table 93 | :class: tabular 94 | 95 | +-----------------+--------------------------------------------------------+ 96 | | Name | Description | 97 | +=================+========================================================+ 98 | | [Documentation] | Used for specifying a `user keyword documentation`_. | 99 | +-----------------+--------------------------------------------------------+ 100 | | [Tags] | Used for specifying `user keyword tags`_. | 101 | +-----------------+--------------------------------------------------------+ 102 | | [Arguments] | Used for specifying `user keyword arguments`_. | 103 | +-----------------+--------------------------------------------------------+ 104 | | [Return] | Used for specifying `user keyword return values`_. | 105 | +-----------------+--------------------------------------------------------+ 106 | | [Teardown] | Used for specifying `user keyword teardown`_. | 107 | +-----------------+--------------------------------------------------------+ 108 | | [Timeout] | Used for specifying a `user keyword timeout`_. | 109 | +-----------------+--------------------------------------------------------+ 110 | -------------------------------------------------------------------------------- /CreatingTestData/CreatingTestSuites.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. _creating test suites: 5 | .. _test suites: 6 | 7 | 创建测试套件 8 | ============ 9 | 10 | Robot Framework测试用例存在于测试用例文件中, 这些文件又可以组织在文件夹中. 整个这些文件和文件夹组成了测试套件(Test Suite)的层次结构. 11 | 12 | .. hint:: 译注: 下面的内容有时候也罢test suites翻译成测试用例集. 13 | 14 | 15 | .. contents:: 16 | :depth: 2 17 | :local: 18 | 19 | 20 | .. _test case file: 21 | .. _test case files: 22 | 23 | 测试用例文件 24 | ------------ 25 | 26 | Robot Framework 的测试用例在测试文件中使用测试用例表格来 :ref:`创建 <test case syntax>`. 27 | 28 | 这个测试文件自动创建了一个测试套件, 包含其中所有的测试用例. 理论上, 一个文件中的用例数量没有上限, 但是一般建议不要超过10个, 除非是使用 :ref:`data-driven approach` 的时候. 29 | 30 | 下面在设置表格中的配置项可以用来自定义一个测试用例集: 31 | 32 | `Documentation`:setting: 33 | 用来指定 :ref:`test suite documentation` 34 | `Metadata`:setting: 35 | 使用键值对来指定 :ref:`free test suite metadata` 36 | `Suite Setup`:setting:, `Suite Teardown`:setting: 37 | 用来指定 :ref:`suite setup and teardown`. 38 | 39 | .. note:: 所有的设置名称后面都可以选择性的添加一个冒号, 40 | 例如 :setting:`Documentation:` 这样可以增加可读性, 特别是使用纯文本格式时. 41 | 42 | 43 | .. _test suite directory: 44 | .. _test suite directories: 45 | 46 | 测试套件文件夹 47 | -------------- 48 | 49 | 测试用例文件可以组织在文件夹中, 这些文件夹就是更高层次的测试用例集. 文件夹类型的测试套件不直接包含用例, 仅包含文件用例集, 不过这些文件夹还可能继续保存在其它文件下面, 由此形成一个更高层次的用例套件. 以此类推, 这个组织结构在层次上没有限制, 所有的测试用例可以按需组织. 50 | 51 | 当一个测试目录被执行, 其中的文件和子目录会按如下规则递归的处理: 52 | 53 | - 以点(:file:`.`)或下划线(:file:`_`)开头的文件/目录名被忽略. 54 | - 目录 :file:`CVS` (注意大小写)被忽略. 55 | - 文件的扩展名不在 :ref:`可识别扩展名 <supported file formats>` 之列的(:file:`.html`, :file:`.xhtml`, :file:`.htm`, :file:`.tsv`, :file:`.txt`, :file:`.rst`, 或 :file:`.rest`) 被忽略(大小写无关). 56 | - 处理其它文件和目录. 57 | 58 | 如果被处理的文件或者目录下不包含任何用例, 则也会默默的跳过. 59 | 60 | 61 | .. _Warning on invalid files: 62 | 63 | 非法文件警告 64 | ~~~~~~~~~~~~ 65 | 66 | 一般情况下, 不包含合法测试用例表格的文件会默默地被忽略掉, 但同时把消息写入 :ref:`syslog`. 可以在命令行中指定选项 :option:`--warnonskippedfiles`, 这样就将该消息作为警告处理, 警告消息最终出现在 :ref:`测试执行错误区 <errors and warnings during execution>`. 67 | 68 | 69 | .. _initialization file: 70 | 71 | 初始化文件 72 | ~~~~~~~~~~ 73 | 74 | 目录形式的测试用例集也可以和文件形式的用例集一样有类似的设置. 但是由于目录本身没法保存相关信息, 必须将其保存在一个特殊的测试套件初始化文件中. 75 | 76 | 初始化文件的文件名的格式总是 :file:`__init__.ext`, 其中扩展名和用例文件的扩展名一样, 也必须要是可识别的. (例如: :file:`__init__.robot` 或 :file:`__init__.html`). 这种命名格式借鉴自Python, :file:`__init__.py` 将目录变为一个模块(module). 77 | 78 | 初始化文件中除了不能包含测试用例表格, 以及不支持某些设置项, 其它结构和语法和用例文件一样. 79 | 80 | 初始化文件中创建或者导入的变量和关键字在下层的测试套件中 **不可用**. 想要共享变量和(或)关键字, 可以放在 :ref:`resource files`, 再由测试用例文件导入. 81 | 82 | 初始化文件的最大用途是指定用例集相关的设置. 指定设置的方式类似 :ref:`test case files`, 同时也可以指定某些 :ref:`test case related settings`. 83 | 84 | 下面将解释说明如何在初始化文件中使用不同的设置项. 85 | 86 | `Documentation`:setting:, `Metadata`:setting:, `Suite Setup`:setting:, `Suite Teardown`:setting: 87 | 这些测试套件相关的设置和测试用例文件中的设置一样. 88 | 89 | `Force Tags`:setting: 90 | 为下面的所有用例指定标签. 91 | 92 | `Test Setup`:setting:, `Test Teardown`:setting:, `Test Timeout`:setting: 93 | 为下面的测试用例设置默认的 setup/teardown 或 超时动作. 测试用例可以单独设置以覆盖这里的配置. 94 | 95 | `Default Tags`:setting:, `Test Template`:setting: 96 | 不支持. 97 | 98 | .. sourcecode:: robotframework 99 | 100 | *** Settings *** 101 | Documentation Example suite 102 | Suite Setup Do Something ${MESSAGE} 103 | Force Tags example 104 | Library SomeLibrary 105 | 106 | *** Variables *** 107 | ${MESSAGE} Hello, world! 108 | 109 | *** Keywords *** 110 | Do Something 111 | [Arguments] ${args} 112 | Some Keyword ${arg} 113 | Another Keyword 114 | 115 | 116 | .. _test suite name and documentation: 117 | .. _test suite documentation: 118 | 119 | 测试套件名称和文档 120 | ------------------ 121 | 122 | 测试套件的名称由文件或目录名称构造. 文件的扩展名被去掉, 名字中的下划线被空格替换, 全小写的单词首字母会变大写. 例如: :file:`some_tests.html` 变为 :name:`Some Tests`, :file:`My_test_directory` 转变为 :name:`My Test Directory`. 123 | 124 | 文件或目录名称可以包含前缀来控制测试集的 :ref:`execution order`. 前缀和后面的基础名称用两个下划线分隔, 当构造用例集名称时, 前缀和下划线都被去掉. 125 | 例如, 文件 :file:`01__some_tests.txt` 和 :file:`02__more_tests.txt` 创建的测试用例集名称分别是 :name:`Some Tests` 和 :name:`More Tests`, 并且前者会先执行. 126 | 127 | 测试套件的文档通过在Setting表格中设置 :setting:`Documentation` 来指定. 该设置项可以在用例文件中, 以及目录套件的初始化文件中设置. 测试套件的文档表现形式和创建方式于 :ref:`test case documentation` 一般无二. 128 | 129 | .. sourcecode:: robotframework 130 | 131 | *** Settings *** 132 | Documentation An example test suite documentation with *some* _formatting_. 133 | ... See test documentation for more documentation examples. 134 | 135 | 高层测试套件的名称和文档都可以在执行的时候, 通过命令行选项 :option:`--name` 和 :option:`--doc` 分别覆盖. 详见 `Setting metadata`_. 136 | 137 | .. _ts meta: 138 | .. _free test suite metadata: 139 | 140 | 测试套件的metadata 141 | ------------------ 142 | 143 | 除了文档外, 测试套件还可以设置其他的元数据(metadata). 这些元数据通过在 Setting 表格中使用 :setting:`Metadata` 设置项来指定. 设置的元数据会在测试报告和日志文件中展示. 144 | 145 | 元数据的键和值所在的列跟在 :setting:`Metadata` 后面. 值的处理和文档类似, 也就是说, 可以分割为 :ref:`多格 <dividing test data to several rows>` (由空格拼接), 或者 `多行 <newlines in test data>` (由换行拼接), 并且支持简单的 :ref:`HTML formatting` 甚至 :ref:`variables`. 146 | 147 | .. sourcecode:: robotframework 148 | 149 | *** Settings *** 150 | Metadata Version 2.0 151 | Metadata More Info For more information about *Robot Framework* see http://robotframework.org 152 | Metadata Executed At ${HOST} 153 | 154 | 对于高层的测试用例集, 可以通过命令行选项 :option:`--metadata` 来设置元数据. 具体细节请参考 `Setting metadata`_. 155 | 156 | 157 | .. _suite setup: 158 | .. _suite teardown: 159 | .. _suite setup and teardown: 160 | 161 | 套件的Setup和Teardown 162 | --------------------- 163 | 164 | 测试套件和 :ref:`测试用例一样 <test setup and teardown>` 可以设置Setup和Teardown. 测试套件的Setup在其中所有测试用例和子套件运行之前被执行, Teardown则是在之后执行. 165 | 166 | 每一层测试套件都可以有Setup和Teardown, 目录形式的测试套件需要在 :ref:`initialization file` 中设置. 167 | 168 | 和测试用例类似, 测试套件的Setup和Teardown也都是可接受参数的关键字. 它们在 Setting 表格中通过 :setting:`Suite Setup` 和 :setting:`Suite Teardown` 各自指定. 关键字的参数跟在设置名称的后面. 169 | 170 | 如果一个测试套件的Setup执行失败了, 该套件下的所有子套件和用例会立即置为失败状态, 实际上并不会执行. 利用这种特性, 可以来检验用例执行的必要前置条件是否满足. 171 | 172 | 测试套件的Teardown一般是用来在所有测试用例执行完毕后, 执行必要的清理操作. 不同于用例, 即使setup执行失败了, teardown也会执行. 如果teardown执行失败, 所有的测试用例也会被标记为失败, 不管这些用例自己执行的结果如何. 注意, teardown中的所有关键字, 即使其中某些执行失败, 最终都会被执行. 173 | 174 | Setup和Teardown中的关键字名称可以使用变量. 这种特性使得可以在不同的环境中, 通过命令行指定不同的变量, 就可以执行不同的setup和teardown过程. 175 | -------------------------------------------------------------------------------- /CreatingTestData/UsingTestLibraries.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. _using test libraries: 5 | .. _test libraries: 6 | 7 | 使用测试库 8 | ========== 9 | 10 | 测试库中包含底层的关键字, 通常称之为 *库关键字*, 这些关键字与被测系统直接交互. 11 | 12 | 所有的测试用例都会使用到来自某个库中的关键字, 一般是通过更高层次的 :ref:`user keywords`. 13 | 14 | 本章介绍如何使用测试库和其提供的关键字. :ref:`creating test libraries` 在其它章节讨论. 15 | 16 | .. contents:: 17 | :depth: 2 18 | :local: 19 | 20 | .. Importing libraries 21 | 22 | 导入库 23 | ------ 24 | 25 | 测试库一般是通过设置 :setting:`Library` 设置项来导入, 不过也可以通过使用调用关键字 :name:`Import Library` 来导入. 26 | 27 | .. Using `Library` setting 28 | 29 | 设置 `Library` 30 | ~~~~~~~~~~~~~~~ 31 | 32 | 测试库通常在 Setting 表格中设置 :setting:`Library` 来导入, 库名称跟在 ``Library`` 后面. 不同于大部分的其它数据, 库名称既是大小写敏感的, 也是空白敏感的. 如果一个测试库是在某个包里的, 则必须指明完整的包名称路径. 33 | 34 | 某些情况下, 测试库可以接受参数. 这些参数跟在库名称后面. 和 :ref:`关键字参数 <using arguments>` 差不多, 测试库的参数也可以使用默认值, 不定数量参数, 以及命名参数. 并且库名称和参数都可以使用变量. 例如: 35 | 36 | .. sourcecode:: robotframework 37 | 38 | *** Settings *** 39 | Library OperatingSystem 40 | Library my.package.TestLibrary 41 | Library MyLibrary arg1 arg2 42 | Library ${LIBRARY} 43 | 44 | 可以导入测试库的文件包括 :ref:`test case files`, :ref:`resource files` 和 :ref:`test suite initialization files`. 45 | 46 | 所有这些场景中, 一旦在这些文件中导入了测试库, 则测试库中所有关键字在文件内都是可见的. 对于资源文件, 这些关键字在引用这些资源文件的地方也是可见的. 47 | 48 | .. Using `Import Library` keyword 49 | 50 | 使用 `Import Library` 关键字 51 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52 | 53 | 导入测试库的另一种方式是使用 :ref:`BuiltIn` 库提供的关键字 :name:`Import Library`. 该关键字接受库名称以及可能的参数作为它的参数. 被导入的库中的关键字在调用 :name:`Import Library` 关键字的测试套件中可用. 54 | 55 | 当测试库在测试执行前不能导入, 只能在执行过程中通过某些关键字来启用时, 这种方法就可以发挥作用了. 56 | 57 | .. sourcecode:: robotframework 58 | 59 | *** Test Cases *** 60 | Example 61 | Do Something 62 | Import Library MyLibrary arg1 arg2 63 | KW From MyLibrary 64 | 65 | .. Specifying library to import 66 | 67 | 指定要导入的库 68 | -------------- 69 | 70 | 要导入的库既可以通过库的名称, 也可以通过库的路径来指定. 这两种方式, 不管是使用设置 :setting:`Library` 还是调用 :name:`Import Library` 关键字, 都是一样的. 71 | 72 | Libraries to import can be specified either by using the library name 73 | or the path to the library. These approaches work the same way regardless 74 | is the library imported using the :setting:`Library` setting or the 75 | :name:`Import Library` keyword. 76 | 77 | .. Using library name 78 | 79 | 使用库名 80 | ~~~~~~~~ 81 | 82 | 最常见的是使用库名称来指定要导入的测试库, 就像本章前面所有的例子所示那样. 这种情况下, Robot Framework 试图从 :ref:`module search path` 中查找实现该库的类或者模块. 一般来讲, 通过安装的方式创建的库应该自动在模块搜寻路径内, 其他库的搜索路径可能需要单独的配置. 83 | 84 | 这种方法最大的好处是当模块搜索路径配置完成后(通常使用 :ref:`start-up script` 完成), 普通用户无需关注测试库实际安装位置. 缺点则是当要导入自己写的, 有可能很简单的一个库, 需要进行额外的配置. 85 | 86 | .. Using physical path to library 87 | 88 | 使用库的路径 89 | ~~~~~~~~~~~~ 90 | 91 | 另一种导入库的方法是使用文件的路径来指定库. 类似于指定 :ref:`resource and variable files` 的路径, 库的路径也被认为是相对于当前测试数据文件所在目录的(当然, 指定绝对路径也是可以的). 92 | 93 | 这种方式最大的好处是无需配置模块搜索路径. 94 | 95 | 如果库是一个文件, 则路径必须包含扩展名. 对Python库, 扩展名是 :file:`.py`, 对Java库则是 :file:`.class` 或 :file:`.java`, 不过.class文件必须存在. 如果Python库是一个文件夹, 该路径最后必须有一个斜杠结尾(``/``). 96 | 97 | 下面的例子展示了几种不同的情况. 98 | 99 | .. sourcecode:: robotframework 100 | 101 | *** Settings *** 102 | Library PythonLibrary.py 103 | Library /absolute/path/JavaLibrary.java 104 | Library relative/path/PythonDirLib/ possible arguments 105 | Library ${RESOURCES}/Example.class 106 | 107 | 108 | 该方法的缺陷是, Python类实现的 :ref:`库名称必须和模块名一样 <test library names>`. 此外, 使用 JAR包或者ZIP包发布的库不能使用这种方式. 109 | 110 | .. Setting custom name to test library 111 | 112 | .. _with name syntax: 113 | .. _withsyn: 114 | 115 | 测试库设置别名 116 | -------------- 117 | 118 | 测试库的名称会在日志文件中的关键字名称的前面展示, 如果多个关键字重名, 则库名称必须作为 :ref:`关键字名称的前缀 <handling keywords with same names>`. 119 | 120 | 库的名称一般就是实现该库的模块或类名, 但在有些情况下有改变的需求: 121 | 122 | - 需要不止一次的导入一个相同的库, 每次使用不同的参数. 如果每次是相同的名称则不可能做到. 123 | 124 | - 库名非常长, 不方便. 比如, 有超长包名的Java库. 125 | 126 | - 在不同的环境中使用不同的测试库, 但是希望以相同的名称引用它们. 127 | 128 | - 库的名称起的不好, 有误导作用 (当然, 这时候更应该改名). 129 | 130 | 131 | 指定新的名称的语法格式是使用 ``WITH NAME`` (此处区分大小写) 跟在原库名称的后面, 后面再跟上新的名称. 新指定的名称将展示在logs文件中, 并且当需要指定关键字的全名(:name:`LibraryName.Keyword Name`)时, 其中的库名也应该使用新的名字. 132 | 133 | .. sourcecode:: robotframework 134 | 135 | *** Settings *** 136 | Library com.company.TestLib WITH NAME TestLib 137 | Library ${LIBRARY} WITH NAME MyName 138 | 139 | 如果库需要参数, 参数的位置在原库名和 ``WITH NAME`` 之间. 下面的例子展示了如何使用不同的参数多次导入同一个库. 140 | 141 | .. sourcecode:: robotframework 142 | 143 | *** Settings *** 144 | Library SomeLibrary localhost 1234 WITH NAME LocalLib 145 | Library SomeLibrary server.domain 8080 WITH NAME RemoteLib 146 | 147 | *** Test Cases *** 148 | My Test 149 | LocalLib.Some Keyword some arg second arg 150 | RemoteLib.Some Keyword another arg whatever 151 | LocalLib.Another Keyword 152 | 153 | 使用 ``WITH NAME`` 指定库的别名的方法同样适用于 :name:`Import Library` 关键字. 154 | 155 | .. Standard libraries 156 | 157 | 标准库 158 | ------ 159 | 160 | 随 Robot Framework 版本一同发布的测试库称之为 *标准库*. 其中 BuiltIn_ 最特别, 因为它总是自动启用, 也就是说其中的关键字总是可用的. 其它的标准库如果要使用的话则需要导入. 161 | 162 | .. Normal standard libraries 163 | 164 | 普通标准库 165 | ~~~~~~~~~~ 166 | 167 | 可用的标准库如下所列: 168 | 169 | - BuiltIn_ 170 | - Collections_ 171 | - DateTime_ 172 | - Dialogs_ 173 | - OperatingSystem_ 174 | - Process_ 175 | - Screenshot_ 176 | - String_ 177 | - Telnet_ 178 | - XML_ 179 | 180 | .. _BuiltIn: ../libraries/BuiltIn.html 181 | .. _Collections: ../libraries/Collections.html 182 | .. _DateTime: ../libraries/DateTime.html 183 | .. _Dialogs: ../libraries/Dialogs.html 184 | .. _OperatingSystem: ../libraries/OperatingSystem.html 185 | .. _Process: ../libraries/Process.html 186 | .. _String: ../libraries/String.html 187 | .. _Screenshot: ../libraries/Screenshot.html 188 | .. _Telnet: ../libraries/Telnet.html 189 | .. _XML: ../libraries/XML.html 190 | 191 | .. _remote library: 192 | 193 | 远程库 194 | ~~~~~~~ 195 | 196 | 除了上面列的普通标准库, 还有一个特殊的标准库, 远程库(:name:`Remote`). 远程库并没有关键字, 它作为一个代理存在于Robot Framework和实际(远程的)测试库中间. 实际的测试库可以运行在其它机器上, 而且实现语言也不再限于Robot Framework原生支持的编程语言. 197 | 198 | 更多关于远程库的内容请参考 :ref:`Remote library interface` 章节. 199 | 200 | .. External libraries 201 | 202 | 外部库 203 | ------ 204 | 205 | 标准库之外的其它测试库都统称为 *外部库*. Robot Framework开源社区实现了若干通用的库, 比如 Selenium2Library_ 和 SwingLibrary_, 不过这些库并没有和框架打包发布. 要查看有哪些公开可用的外部库可以登录官网 http://robotframework.org. 206 | 207 | 通用的, 或定制的测试库, 显然都是由使用Robot Framework框架的小组实现的. 关于如何自己开发测试库, 请参考 :ref:`Creating test libraries` 章节. 208 | 209 | 不同的外部库有各种不同安装和使用方式. 有时可能还需要安装其它依赖. 所有测试库都应该有清晰的安装文档和使用说明, 最好实现自动安装. 210 | -------------------------------------------------------------------------------- /ExecutingTestCases/TestExecution.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | 5 | .. _test execution: 6 | 7 | 测试执行 8 | ======== 9 | 10 | 本章将介绍解析测试数据后而创建的测试套件是如何执行的, 如何在发生失败后继续执行测试用例, 以及如何优雅地结束整个测试执行. 11 | 12 | .. contents:: 13 | :depth: 2 14 | :local: 15 | 16 | .. Execution flow 17 | 18 | 执行流程 19 | --------- 20 | 21 | .. Executed suites and tests 22 | 23 | 测试套件和用例 24 | ~~~~~~~~~~~~~~ 25 | 26 | 测试用例总是在测试套件内执行. 从 :ref:`test case file` 创建的测试套件直接包含测试用例, 而从 :ref:`目录 <test suite directories>` 创建的测试套件包含子套件, 子套件中包含测试用例或者它们自己的子套件. 默认情况下, 一个被执行的测试套件内的所有用例都会运行, 不过可以使用某些选项 :option:`--test`, :option:`--suite`, :option:`--include` 和 :option:`--exclude` 来 :ref:`选择用例 <selecting test cases>`. 其中用例数量为零的测试套件将被忽略. 27 | 28 | 测试执行始于顶层测试套件. 如果套件中包含用例, 这些用例将逐个执行, 如果套件包含子套件, 则以深度优先的顺序递归地执行. 29 | 30 | 当单个用例执行时, 用例内的关键字按顺序执行. 通常任意关键字运行失败都将导致当前用例结束, 不过也可以通过设置 :ref:`失败后继续 <continue on failure>`. 31 | 32 | 精确的 :ref:`执行顺序 <execution order>` 以及 :ref:`setups and teardowns` 如何影响执行将在下面的章节讨论. 33 | 34 | 35 | .. _setups and teardowns: 36 | 37 | Setups和Teardowns 38 | ~~~~~~~~~~~~~~~~~ 39 | 40 | Setups和Teardowns可以用在 :ref:`测试套件 <test setup and teardown>`, :ref:`测试用例 <suite setup and teardown>` 和 :ref:`用户关键字 <user keyword teardown>` 级别. 41 | 42 | 43 | .. Suite setup 44 | 45 | 套件setup 46 | ''''''''''' 47 | 48 | 如果一个测试套件有setup, 它将在所有用例和子套件执行前被执行. 如果该setup通过, 测试流程正常继续. 如果该setup失败, 则该套件内的所有用例(包括其中子套件内的用例)统统都标记为失败. 这些用例, 以及其中可能包含的setup和teardown都不会再执行. 49 | 50 | 套件的setup通常被用来设置测试环境. 因为一旦套件的setup失败, 其中所有用例不会执行, 所以可以很方便地使用套件的setup来检验测试环境是否已经满足了可测试条件. 51 | 52 | .. Suite teardown 53 | 54 | 套件teardown 55 | '''''''''''''' 56 | 57 | 测试套件的teardown将在套件内所有用例(包括其中子套件内的用例)执行完毕后再执行. 套件teardown的执行条件不受测试状态的影响, 即使套件的setup执行失败, teardown也会执行. 58 | 59 | 如果teardown失败, 所有的用例都将在随后的测试报告和日志中标记为失败. 60 | 61 | 套件的teardown经常被用作最后清理测试环境的步骤. 为了确保所有的任务都已经结束, teardown内的 :ref:`所有关键字都会被执行 <continue on failure>`, 即使其中有失败的情况. 62 | 63 | 64 | .. Test setup 65 | 66 | 用例setup 67 | '''''''''' 68 | 69 | 用例setup在用例内的关键字执行前被执行. 如果该setup失败, 则所有的关键字都不会再执行. 用例的setup最大的用途是为特定的用例设置测试环境. 70 | 71 | .. Test teardown 72 | 73 | 用例teardown 74 | ''''''''''''' 75 | 76 | 用例teardown在用例执行完毕后被执行. 它的执行也不受用例执行状态的影响, 即不管用例是成功还是失败, teardown总是会执行. 77 | 78 | 和套件的teardown类似, 用例的teardown也主要用来做清理工作, 同样其中的所有关键字都会执行到, 即使其中有失败的情况. 79 | 80 | .. Keyword teardown 81 | 82 | 关键字teardown 83 | '''''''''''''''' 84 | 85 | :ref:`用户关键字 <user keywords>` 没有setup, 只能设置teardown, 其作用和其它类型的teardown一样. 关键字的teardown在关键字执行后被执行, 不管关键字执行状态如何, teardown最终会完全执行即使其中有关键字失败的情况. 86 | 87 | 88 | .. _execution order: 89 | 90 | 执行顺序 91 | ~~~~~~~~ 92 | 93 | 一个测试套件文件内的测试用例的执行顺序就是其在文件中定义的顺序. 高层套件内的多个子套件的执行顺序是子套件文件或目录名称按字母顺序, 不分大小写. 94 | 如果通过命令行指定多个文件和(或)目录, 则它们将以给出的顺序执行. 95 | 96 | 如果想让某个目录内的测试套件按特定顺序执行, 可以为文件或目录名称加上前缀, 例如: :file:`01` 和 :file:`02`. 如果将前缀和基础名称中间用2个下划线连接, 则最终生成的测试套件名称不会包含前缀, 例如:: 97 | 98 | 01__my_suite.html -> My Suite 99 | 02__another_suite.html -> Another Suite 100 | 101 | 如果按照字母顺序排列还有问题, 还有一个解决方案是将它们按想要的顺序依次分别列出. 显然在命令行中列出会导致启动命令超长, 不过使用 :ref:`argument files` 就刚好解决问题, 其中每行列出一个文件. 102 | 103 | 除了固定的顺序外, 还可以使用 :option:`--randomize` 选项使 :ref:`执行顺序随机化 <randomizing execution order>`. 104 | 105 | 106 | .. Passing execution 107 | 108 | 跳过执行 109 | ~~~~~~~~ 110 | 111 | 通常情况下, 用例以及setup和teardown执行通过的标准是其中包含的所有的关键字都执行无错. 从Robot Framework 2.8版本开始, 还可以通过 BuiltIn_ 关键字 :name:`Pass Execution` 和 :name:`Pass Execution If` 以PASS状态结束执行, 同时跳过剩下的关键字. 112 | 113 | 关键字 :name:`Pass Execution` and :name:`Pass Execution If` 在不同条件下的行为如下: 114 | 115 | - 当在 :ref:`setup 或 teardown <setups and teardowns>` (不管是套件的,用例的还是关键字的)中使用, 将使setup或 116 | teardown通过. 如果开始的关键字有teardown, 将会执行. 用例的执行和状态不受影响. 117 | 118 | - 当在测试用例中(setup和teardown之外)使用, 当前用例直接pass. 119 | 如果用例或关键字有teardown, teardown仍会被执行. 120 | 121 | - 如果 :ref:`可继续的失败 <continue on failure>` 在这些关键字之前发生, 122 | 而且在随后的teardown执行中发生了失败, 则整个执行结果标记为失败. 123 | 124 | - 调用这两个关键字时必须要给出中断执行的理由, 同时还可以修改测试用例的标签. 125 | 更多的细节和示例请参考 :ref:`它们的文档 <BuiltIn>`. 126 | 127 | 在测试用例以及setup或teardown的中间跳过执行需要谨慎. 在最坏的情况下, 这可能会导致测试跳过了可能发生问题的地方(因为最终状态是PASS, 所以不会引起注意). 如果是因为外部因素导致测试无法继续, 更安全的做法是将用例置为 :ref:`non-critical <setting criticality>`, 然后失败(fail). 128 | 129 | 130 | .. _continue on failure: 131 | 132 | 失败后继续 133 | ---------- 134 | 135 | 通常测试用例在任意关键字失败后都会立即终止. 这种行为可以缩短测试执行时间, 防止后续的关键字挂住(hanging), 避免引发其它问题. 然而这么做也有缺点, 因为有时候后续的关键字可以给予更多的系统状态相关的信息. 因此Robot Framework提供了若干特性功能, 使得在发生失败后能继续执行. 136 | 137 | .. :name:`Run Keyword And Ignore Error` and :name:`Run Keyword And Expect Error` keywords 138 | 139 | 通过内置关键字 140 | ~~~~~~~~~~~~~~ 141 | 142 | 内置关键字 :name:`Run Keyword And Ignore Error` 和 :name:`Run Keyword And Expect Error` 可以处理关键字执行失败的情况, 这样测试就不会立即终止. 143 | 144 | 但是使用这些关键字会增加额外的复杂度, 所以下面的特性功能更值得考虑. 145 | 146 | .. Special failures from keywords 147 | 148 | 特殊的失败类型 149 | ~~~~~~~~~~~~~~ 150 | 151 | :ref:`库关键字 <library keywords>` 是通过抛异常来报告失败, 所以可以使用特殊的异常来告诉框架, 发生了这个失败是可以继续执行的. 如何创建此种异常在 :ref:`测试库API章节 <continuing test execution despite of failures>` 中说明. 152 | 153 | 当用例结束时, 如果中间发生了一次或多次可继续的失败, 当前用例将标记为失败. 如果是多次失败, 则最终的错误信息里将把所有失败都列出来:: 154 | 155 | Several failures occurred: 156 | 157 | 1) First error message. 158 | 159 | 2) Second error message ... 160 | 161 | 如果在一个可继续的失败后又发生了一个正常失败, 用例会结束, 同时所有的失败都会被列入最后的错误信息中. 162 | 163 | 如果要将关键字的返回值赋给变量, 遇到该关键字失败, 则最终返回值将总是 ``None``. 164 | 165 | 166 | .. :name:`Run Keyword And Continue On Failure` keyword 167 | 168 | 关键字 :name:`Run Keyword And Continue On Failure` 169 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 170 | 171 | 内置关键字 :name:`Run Keyword And Continue On Failure` 将任意失败都转为可继续的. 框架处理这些失败的方式和库关键字发起的可继续失败一样. 172 | 173 | .. Execution continues on teardowns automatically 174 | 175 | teardown总是继续 176 | ~~~~~~~~~~~~~~~~~ 177 | 178 | 为了确保所有的清理任务都被照顾到, :ref:`用例和套件的teardown <setups and teardowns>` 在失败发生时总是会自动继续执行. 也就是说, teardown中的所有关键字, 不管什么层次, 最终总是会全部执行到. 179 | 180 | 181 | .. All top-level keywords are executed when tests have templates 182 | 183 | 用例模板所有顶层关键字 184 | ~~~~~~~~~~~~~~~~~~~~~~ 185 | 186 | 当使用 :ref:`测试模板 <test templates>` 时, 所有的数据行都会被执行到, 以确保所有的数据组合都被测试到. 这种用法仅限于顶层关键字, 也就是说, 如果这些关键字中间发生了不可继续执行的错误, 这个过程还是会和正常的一样结束. 187 | 188 | .. _stopping test execution gracefully: 189 | 190 | 优雅地结束测试执行 191 | ------------------ 192 | 193 | 有时候需要在所有测试结束前中断执行, 同时还需要生成日志和报告. 下面就介绍几种不同的方法, 在所有这些情况中, 剩下的用例都会标记为失败. 194 | 195 | 从Robot Framework 2.9版本开始, 由于前面发生致命错误而自动置为失败的用例将被打上 ``robot-exit`` 标签, 同时在报告中包含 ``NOT robot-exit`` :ref:`标签模式 <generating combined tag statistics>`, 这样可以轻松的看出哪些用例被跳过了. 注意导致退出发生的那个用例本身不会打上 ``robot-exit`` 标签. 196 | 197 | .. Starting from Robot Framework 2.9 the tests that are automatically failed get 198 | .. `robot-exit` tag and the generated report will include `NOT robot-exit` 199 | .. `combined tag pattern`__ to easily see those tests that were not skipped. Note 200 | .. that the test in which the exit happened does not get the `robot-exit` tag. 201 | 202 | __ `Generating combined tag statistics`_ 203 | 204 | .. Pressing `Ctrl-C` 205 | 206 | 按下 ``Ctrl-C`` 207 | ~~~~~~~~~~~~~~~~ 208 | 209 | 当测试运行时, 在控制台中按下 ``Ctrl-C`` 会使得测试中断执行. 如果测试是运行在Python上的, 执行将立即停止, 而使用Jython时, 将在当前正在运行的关键字结束后再结束. 210 | 211 | 如果很快地再次按下 ``Ctrl-C``, 整个执行将立即停止, 并且报告和日志文件都不会生成. 212 | 213 | .. Using signals 214 | 215 | 使用信号 216 | ~~~~~~~~ 217 | 218 | 只有在类Unix系统中才能使用信号 ``INT`` 和 ``TERM`` 来终止测试执行. 这些信号可以在命令行中通过使用 ``kill`` 命令发送给进程. 219 | 220 | 发送信号的方式在使用Jython时和 按 ``Ctrl-C`` 有同样的限制. 并且类似地, 再次发送信号将强行终止整个执行. 221 | 222 | .. Using keywords 223 | 224 | 使用关键字 225 | ~~~~~~~~~~ 226 | 227 | 测试执行的停止还可以通过调用关键字来实现. BuiltIn_ 关键字 :name:`Fatal Error` 用于这种目的. 用户自定义的关键字可以使用 :ref:`fatal exceptions <stopping test execution>`. 228 | 229 | 230 | .. Stopping when first test case fails 231 | 232 | 用例失败即停 233 | ~~~~~~~~~~~~ 234 | 235 | 如果设置了选项 :option:`--exitonfailure`, 则任意一个 :ref:`critical test` 失败都将导致整个测试执行停止, 同样地, 其它剩下的用例会被标记为失败. 236 | 237 | .. Stopping on parsing or execution error 238 | 239 | 解析或执行错误 240 | ~~~~~~~~~~~~~~ 241 | 242 | Robot Framework分开对待关键字执行 *失败* (failures)和执行 *错误* (error)的情况, 243 | 失败是指关键字执行没有通过, 而错误是指非法设置或者库导入错误. 244 | 默认情况下, 这些错误会显示在 :ref:`测试执行错误区 <errors and warnings during execution>`, 但是这些错误本身是不会使用例失败和影响执行的(当然是在错误和用例不相关的时候). 如果设置了选项 :option:`--exitonerror`, 则一旦有错误发生, 整个执行将停止, 并且剩下的所有测试用例会标记为失败. 因为解析错误发生在测试执行前, 也就意味着实际上没有用例会真正运行. 245 | 246 | .. note:: :option:`--exitonerror` is new in Robot Framework 2.8.6. 247 | 248 | 249 | .. Handling teardowns 250 | 251 | 处理teardown 252 | ~~~~~~~~~~~~~ 253 | 254 | 默认情况下, 已经开始运行的用例或套件的teardown总是会执行, 即使测试执行使用了上述的方法来中止了. 这样做可以保证不错过清理任务. 255 | 256 | 如果设置了选项 :option:`--skipteardownonexit` 则可以关闭这个特性, 当执行停止时跳过teardown的执行. 在有些时候, 例如清理任务耗时非常长, 这将非常有用. 257 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=_build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . 10 | set I18NSPHINXOPTS=%SPHINXOPTS% . 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^<target^>` where ^<target^> is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. epub3 to make an epub3 31 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 32 | echo. text to make text files 33 | echo. man to make manual pages 34 | echo. texinfo to make Texinfo files 35 | echo. gettext to make PO message catalogs 36 | echo. changes to make an overview over all changed/added/deprecated items 37 | echo. xml to make Docutils-native XML files 38 | echo. pseudoxml to make pseudoxml-XML files for display purposes 39 | echo. linkcheck to check all external links for integrity 40 | echo. doctest to run all doctests embedded in the documentation if enabled 41 | echo. coverage to run coverage check of the documentation if enabled 42 | echo. dummy to check syntax errors of document sources 43 | goto end 44 | ) 45 | 46 | if "%1" == "clean" ( 47 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 48 | del /q /s %BUILDDIR%\* 49 | goto end 50 | ) 51 | 52 | 53 | REM Check if sphinx-build is available and fallback to Python version if any 54 | %SPHINXBUILD% 1>NUL 2>NUL 55 | if errorlevel 9009 goto sphinx_python 56 | goto sphinx_ok 57 | 58 | :sphinx_python 59 | 60 | set SPHINXBUILD=python -m sphinx.__init__ 61 | %SPHINXBUILD% 2> nul 62 | if errorlevel 9009 ( 63 | echo. 64 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 65 | echo.installed, then set the SPHINXBUILD environment variable to point 66 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 67 | echo.may add the Sphinx directory to PATH. 68 | echo. 69 | echo.If you don't have Sphinx installed, grab it from 70 | echo.http://sphinx-doc.org/ 71 | exit /b 1 72 | ) 73 | 74 | :sphinx_ok 75 | 76 | 77 | if "%1" == "html" ( 78 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 79 | if errorlevel 1 exit /b 1 80 | echo. 81 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 82 | goto end 83 | ) 84 | 85 | if "%1" == "dirhtml" ( 86 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 87 | if errorlevel 1 exit /b 1 88 | echo. 89 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 90 | goto end 91 | ) 92 | 93 | if "%1" == "singlehtml" ( 94 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 95 | if errorlevel 1 exit /b 1 96 | echo. 97 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 98 | goto end 99 | ) 100 | 101 | if "%1" == "pickle" ( 102 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 103 | if errorlevel 1 exit /b 1 104 | echo. 105 | echo.Build finished; now you can process the pickle files. 106 | goto end 107 | ) 108 | 109 | if "%1" == "json" ( 110 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 111 | if errorlevel 1 exit /b 1 112 | echo. 113 | echo.Build finished; now you can process the JSON files. 114 | goto end 115 | ) 116 | 117 | if "%1" == "htmlhelp" ( 118 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 119 | if errorlevel 1 exit /b 1 120 | echo. 121 | echo.Build finished; now you can run HTML Help Workshop with the ^ 122 | .hhp project file in %BUILDDIR%/htmlhelp. 123 | goto end 124 | ) 125 | 126 | if "%1" == "qthelp" ( 127 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 128 | if errorlevel 1 exit /b 1 129 | echo. 130 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 131 | .qhcp project file in %BUILDDIR%/qthelp, like this: 132 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\robotframework-userguide-cn.qhcp 133 | echo.To view the help file: 134 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\robotframework-userguide-cn.ghc 135 | goto end 136 | ) 137 | 138 | if "%1" == "devhelp" ( 139 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 140 | if errorlevel 1 exit /b 1 141 | echo. 142 | echo.Build finished. 143 | goto end 144 | ) 145 | 146 | if "%1" == "epub" ( 147 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 148 | if errorlevel 1 exit /b 1 149 | echo. 150 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 151 | goto end 152 | ) 153 | 154 | if "%1" == "epub3" ( 155 | %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 156 | if errorlevel 1 exit /b 1 157 | echo. 158 | echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. 159 | goto end 160 | ) 161 | 162 | if "%1" == "latex" ( 163 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 164 | if errorlevel 1 exit /b 1 165 | echo. 166 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdf" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "latexpdfja" ( 181 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 182 | cd %BUILDDIR%/latex 183 | make all-pdf-ja 184 | cd %~dp0 185 | echo. 186 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 187 | goto end 188 | ) 189 | 190 | if "%1" == "text" ( 191 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 192 | if errorlevel 1 exit /b 1 193 | echo. 194 | echo.Build finished. The text files are in %BUILDDIR%/text. 195 | goto end 196 | ) 197 | 198 | if "%1" == "man" ( 199 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 200 | if errorlevel 1 exit /b 1 201 | echo. 202 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 203 | goto end 204 | ) 205 | 206 | if "%1" == "texinfo" ( 207 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 208 | if errorlevel 1 exit /b 1 209 | echo. 210 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 211 | goto end 212 | ) 213 | 214 | if "%1" == "gettext" ( 215 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 216 | if errorlevel 1 exit /b 1 217 | echo. 218 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 219 | goto end 220 | ) 221 | 222 | if "%1" == "changes" ( 223 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 224 | if errorlevel 1 exit /b 1 225 | echo. 226 | echo.The overview file is in %BUILDDIR%/changes. 227 | goto end 228 | ) 229 | 230 | if "%1" == "linkcheck" ( 231 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 232 | if errorlevel 1 exit /b 1 233 | echo. 234 | echo.Link check complete; look for any errors in the above output ^ 235 | or in %BUILDDIR%/linkcheck/output.txt. 236 | goto end 237 | ) 238 | 239 | if "%1" == "doctest" ( 240 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 241 | if errorlevel 1 exit /b 1 242 | echo. 243 | echo.Testing of doctests in the sources finished, look at the ^ 244 | results in %BUILDDIR%/doctest/output.txt. 245 | goto end 246 | ) 247 | 248 | if "%1" == "coverage" ( 249 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 250 | if errorlevel 1 exit /b 1 251 | echo. 252 | echo.Testing of coverage in the sources finished, look at the ^ 253 | results in %BUILDDIR%/coverage/python.txt. 254 | goto end 255 | ) 256 | 257 | if "%1" == "xml" ( 258 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 259 | if errorlevel 1 exit /b 1 260 | echo. 261 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 262 | goto end 263 | ) 264 | 265 | if "%1" == "pseudoxml" ( 266 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 267 | if errorlevel 1 exit /b 1 268 | echo. 269 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 270 | goto end 271 | ) 272 | 273 | if "%1" == "dummy" ( 274 | %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy 275 | if errorlevel 1 exit /b 1 276 | echo. 277 | echo.Build finished. Dummy builder generates no files. 278 | goto end 279 | ) 280 | 281 | :end 282 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help 23 | help: 24 | @echo "Please use \`make <target>' where <target> is one of" 25 | @echo " html to make standalone HTML files" 26 | @echo " dirhtml to make HTML files named index.html in directories" 27 | @echo " singlehtml to make a single large HTML file" 28 | @echo " pickle to make pickle files" 29 | @echo " json to make JSON files" 30 | @echo " htmlhelp to make HTML files and a HTML help project" 31 | @echo " qthelp to make HTML files and a qthelp project" 32 | @echo " applehelp to make an Apple Help Book" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " epub3 to make an epub3" 36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 37 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 39 | @echo " text to make text files" 40 | @echo " man to make manual pages" 41 | @echo " texinfo to make Texinfo files" 42 | @echo " info to make Texinfo files and run them through makeinfo" 43 | @echo " gettext to make PO message catalogs" 44 | @echo " changes to make an overview of all changed/added/deprecated items" 45 | @echo " xml to make Docutils-native XML files" 46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 47 | @echo " linkcheck to check all external links for integrity" 48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 49 | @echo " coverage to run coverage check of the documentation (if enabled)" 50 | @echo " dummy to check syntax errors of document sources" 51 | 52 | .PHONY: clean 53 | clean: 54 | rm -rf $(BUILDDIR)/* 55 | 56 | .PHONY: html 57 | html: 58 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 61 | 62 | .PHONY: dirhtml 63 | dirhtml: 64 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 65 | @echo 66 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 67 | 68 | .PHONY: singlehtml 69 | singlehtml: 70 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 71 | @echo 72 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 73 | 74 | .PHONY: pickle 75 | pickle: 76 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 77 | @echo 78 | @echo "Build finished; now you can process the pickle files." 79 | 80 | .PHONY: json 81 | json: 82 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 83 | @echo 84 | @echo "Build finished; now you can process the JSON files." 85 | 86 | .PHONY: htmlhelp 87 | htmlhelp: 88 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 89 | @echo 90 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 91 | ".hhp project file in $(BUILDDIR)/htmlhelp." 92 | 93 | .PHONY: qthelp 94 | qthelp: 95 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 96 | @echo 97 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 98 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 99 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/robotframework-userguide-cn.qhcp" 100 | @echo "To view the help file:" 101 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/robotframework-userguide-cn.qhc" 102 | 103 | .PHONY: applehelp 104 | applehelp: 105 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 106 | @echo 107 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 108 | @echo "N.B. You won't be able to view it unless you put it in" \ 109 | "~/Library/Documentation/Help or install it in your application" \ 110 | "bundle." 111 | 112 | .PHONY: devhelp 113 | devhelp: 114 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 115 | @echo 116 | @echo "Build finished." 117 | @echo "To view the help file:" 118 | @echo "# mkdir -p $$HOME/.local/share/devhelp/robotframework-userguide-cn" 119 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/robotframework-userguide-cn" 120 | @echo "# devhelp" 121 | 122 | .PHONY: epub 123 | epub: 124 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 125 | @echo 126 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 127 | 128 | .PHONY: epub3 129 | epub3: 130 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 131 | @echo 132 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." 133 | 134 | .PHONY: latex 135 | latex: 136 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 137 | @echo 138 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 139 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 140 | "(use \`make latexpdf' here to do that automatically)." 141 | 142 | .PHONY: latexpdf 143 | latexpdf: 144 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 145 | @echo "Running LaTeX files through pdflatex..." 146 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 147 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 148 | 149 | .PHONY: latexpdfja 150 | latexpdfja: 151 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 152 | @echo "Running LaTeX files through platex and dvipdfmx..." 153 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 154 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 155 | 156 | .PHONY: text 157 | text: 158 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 159 | @echo 160 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 161 | 162 | .PHONY: man 163 | man: 164 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 165 | @echo 166 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 167 | 168 | .PHONY: texinfo 169 | texinfo: 170 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 171 | @echo 172 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 173 | @echo "Run \`make' in that directory to run these through makeinfo" \ 174 | "(use \`make info' here to do that automatically)." 175 | 176 | .PHONY: info 177 | info: 178 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 179 | @echo "Running Texinfo files through makeinfo..." 180 | make -C $(BUILDDIR)/texinfo info 181 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 182 | 183 | .PHONY: gettext 184 | gettext: 185 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 186 | @echo 187 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 188 | 189 | .PHONY: changes 190 | changes: 191 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 192 | @echo 193 | @echo "The overview file is in $(BUILDDIR)/changes." 194 | 195 | .PHONY: linkcheck 196 | linkcheck: 197 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 198 | @echo 199 | @echo "Link check complete; look for any errors in the above output " \ 200 | "or in $(BUILDDIR)/linkcheck/output.txt." 201 | 202 | .PHONY: doctest 203 | doctest: 204 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 205 | @echo "Testing of doctests in the sources finished, look at the " \ 206 | "results in $(BUILDDIR)/doctest/output.txt." 207 | 208 | .PHONY: coverage 209 | coverage: 210 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 211 | @echo "Testing of coverage in the sources finished, look at the " \ 212 | "results in $(BUILDDIR)/coverage/python.txt." 213 | 214 | .PHONY: xml 215 | xml: 216 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 217 | @echo 218 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 219 | 220 | .PHONY: pseudoxml 221 | pseudoxml: 222 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 223 | @echo 224 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 225 | 226 | .PHONY: dummy 227 | dummy: 228 | $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy 229 | @echo 230 | @echo "Build finished. Dummy builder generates no files." 231 | -------------------------------------------------------------------------------- /Appendices/DocumentationFormatting.rst: -------------------------------------------------------------------------------- 1 | .. _documentation syntax: 2 | .. _documentation formatting: 3 | 4 | 文档格式 5 | ======== 6 | 7 | 在所有文档出现的地方, 包括 :ref:`测试套件 <test suite documentation>`, :ref:`测试用例 <test case documentation>`, :ref:`用户关键字 <user keyword documentation>`, :ref:`测试套件的元数据 <free test suite metadata>`, 以及 :ref:`测试库文档 <documenting libraries>` 中, 都可以使用简单的HTML格式. 这个格式和大多数wiki用到的样式类似, 被设计成不管是纯文本还是转换成HTML都很易懂. 8 | 9 | 10 | `本章原文 <http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#documentation-formatting>`_ 11 | 12 | .. contents:: 13 | :depth: 2 14 | :local: 15 | 16 | .. Representing newlines 17 | 18 | 如何表示换行 19 | ------------ 20 | 21 | .. _newlines in test data: 22 | 23 | 测试数据中的换行 24 | ~~~~~~~~~~~~~~~~ 25 | 26 | 对所有的文档, 换行都可以通过手动添加 :ref:`字面换行符 <handling whitespace>` (``\n``)来实现. 27 | 28 | 29 | .. sourcecode:: robotframework 30 | 31 | *** Settings *** 32 | Documentation First line.\n\nSecond paragraph, this time\nwith multiple lines. 33 | Metadata Example Value\nin two lines 34 | 35 | 手动添加换行符对于长篇文档来说是个负担, 并且额外的字符也使得文档内容难以阅读. 从Robot Framework 2.7版本开始, :ref:`连续的文档和元数据行 <dividing test data to several rows>` 中间会自动插入换行. 也就是说, 上面的例子还可以写成下面这种情况: 36 | 37 | .. sourcecode:: robotframework 38 | 39 | *** Settings *** 40 | Documentation 41 | ... First line. 42 | ... 43 | ... Second paragraph, this time 44 | ... with multiple lines. 45 | Metadata 46 | ... Example 47 | ... Value 48 | ... in two lines 49 | 50 | 如果一行已经以字面换行符结尾了, 或者以一个 :ref:`转义的反斜杠 <escaping>` 结尾, 则不会自动添加换行. 同一行中多列文字则使用空格拼接起来. 这种方式的拆分对 :ref:`HTML format` 比较有用, 因为HTML表格的列一般比较窄. 51 | 52 | 下面的例子使用不同的方法来分割文档, 所有3个用例的文档最终效果都是一样的, 都包含了两行文档. 53 | 54 | .. sourcecode:: robotframework 55 | 56 | *** Test Cases *** 57 | Example 1 58 | [Documentation] First line\n Second line in multiple parts 59 | No Operation 60 | 61 | Example 2 62 | [Documentation] First line 63 | ... Second line in multiple parts 64 | No Operation 65 | 66 | Example 3 67 | [Documentation] First line\n 68 | ... Second line in\ 69 | ... multiple parts 70 | No Operation 71 | 72 | .. Documentation in test libraries 73 | 74 | 测试库的文档 75 | ~~~~~~~~~~~~ 76 | 77 | 测试库的文档使用正常的换行就可以了. 78 | 79 | 下面的例子中, 关键字的文档最终效果和上面的例子是一样的. 80 | 81 | .. sourcecode:: python 82 | 83 | def example_keyword(): 84 | """First line. 85 | 86 | Second paragraph, this time 87 | with multiple lines. 88 | """ 89 | pass 90 | 91 | 92 | .. _paragraphs: 93 | 94 | 段落 95 | ---- 96 | 97 | 从Robot Framework 2.7.2版本开始, 格式化后的HTML文档里, 所有的普通文本都表示为段落. 实际上, 不管是手动还是自动换行都会造成分段. 多个段落之间可以是空行, 也可以是其它的文本块, 比如表格, 列表等. 98 | 99 | 例如, 下面的测试套件或资源文件文档: 100 | 101 | .. sourcecode:: robotframework 102 | 103 | *** Settings *** 104 | Documentation 105 | ... First paragraph has only one line. 106 | ... 107 | ... Second paragraph, this time created 108 | ... with multiple lines. 109 | 110 | 转为HTML格式后: 111 | 112 | .. raw:: html 113 | 114 | <div class="doc"> 115 | <p>First paragraph has only one line.</p> 116 | <p>Second paragraph, this time created with multiple lines.</p> 117 | </div> 118 | 119 | .. note:: 2.7.2版本之前的段落处理并不一致. Libdoc_ 生成的文档是段落组成的, 但是 120 | 日志和报告里面的文档不是. 121 | 122 | 123 | .. _inline styles: 124 | 125 | 行内样式 126 | -------- 127 | 128 | 文档语法支持的行内样式包括: **粗体**, *斜体* and ``代码``. 粗体文字是用星号把一个或多个单词包住, 例如 ``*this is bold*``. 类似地, 斜体是使用下划线, 例如 ``_italic_``. 两者组合可以生成粗斜体 ``_*bold italic*_``. 129 | 130 | 行内的代码使用双反引号 ````code````. 其效果是生成淡灰色背景加等宽字体. 代码样式是在2.8.6版本新加的功能. 131 | 132 | 星号, 下划线, 双反引号这些字符如果单独出现, 或者出现在文字中间, 则不会起作用, 不过如果前后出现的是标点符号, 则不受影响. 当 :ref:`段落 <paragraphs>` 中有多行, 行内样式可以跨越多行. 133 | 134 | 135 | .. raw:: html 136 | 137 | <table class="tabular docutils"> 138 | <caption>Inline style examples</caption> 139 | <tr> 140 | <th>Unformatted</th> 141 | <th>Formatted</th> 142 | </tr> 143 | <tr> 144 | <td>*bold*</td> 145 | <td><b>bold</b></td> 146 | </tr> 147 | <tr> 148 | <td>_italic_</td> 149 | <td><i>italic</i></td> 150 | </tr> 151 | <tr> 152 | <td>_*bold italic*_</td> 153 | <td><i><b>bold italic</b></i></td> 154 | </tr> 155 | <tr> 156 | <td>``code``</td> 157 | <td><code>code</code></td> 158 | </tr> 159 | <tr> 160 | <td>*bold*, then _italic_ and finally ``some code``</td> 161 | <td><b>bold</b>, then <i>italic</i> and finally <code>some code</code></td> 162 | </tr> 163 | <tr> 164 | <td>This is *bold\n<br>on multiple\n<br>lines*.</td> 165 | <td>This is <b>bold</b><br><b>on multiple</b><br><b>lines</b>.</td> 166 | </tr> 167 | </table> 168 | 169 | URLs 170 | ---- 171 | 172 | 所有看起来像URL的字符串都会自动转换为可点击的链接. 此外, 如果URL以图片类扩展名如 :file:`.jpg`, :file:`.jpeg`, :file:`.png`, :file:`.gif` 或 :file:`.bmp` (大小写无关) 结尾, 则将自动创建图片. 173 | 174 | 例如, 网址 ``http://example.com`` 转为链接, ``http:///host/image.jpg`` 和 ``file:///path/chart.png`` 则转为图片链接. 175 | 176 | URL的自动转换对日志和报告内的所有数据都启用, 但是创建图片只对测试套件文档, 测试用例和关键字文档, 以及测试套件的元数据起作用. 177 | 178 | .. Custom links and images 179 | 180 | 自定义链接和图片 181 | ---------------- 182 | 183 | 从Robot Framework 2.7版本开始, 可以通过一个特殊语法来创建自定义的链接和嵌入图片, 语法格式为 ``[link|content]``. 最终生成的效果取决于 ``link`` 和 ``content``. 184 | 185 | 是否是图片同样是通过文件扩展名来判断, 和 URLs_ 中一样. 不管什么情况, 该语法中的方括号和中间的管道符都是必需的. 186 | 187 | .. Link with text content 188 | 189 | 带文本内容的链接 190 | ~~~~~~~~~~~~~~~~ 191 | 192 | 如果不管 ``link`` 或 ``content`` 都不是图片, 则结果会生成一个普通的链接, 其中 ``link`` 是链接目标, 而 ``content`` 是显示文本:: 193 | 194 | 195 | [file.html|this file] -> <a href="file.html">this file</a> 196 | [http://host|that host] -> <a href="http://host">that host</a> 197 | 198 | .. Link with image content 199 | 200 | 带图片的链接 201 | ~~~~~~~~~~~~ 202 | 203 | 如果 ``content`` 是图片, 则生成的链接显示的内容是图片. 而链接的目标由 ``link`` 决定, 可能是普通的文本链接, 也可能是图片:: 204 | 205 | [robot.html|robot.png] -> <a href="robot.html"><img src="robot.png"></a> 206 | [image.jpg|thumb.jpg] -> <a href="image.jpg"><img src="thumb.jpg"></a> 207 | 208 | .. Image with title text 209 | 210 | 带title文本的图片 211 | ~~~~~~~~~~~~~~~~~ 212 | 213 | 如果 ``link`` 是图片, 而 ``content`` 不是, 则生成的结果是一幅图片, 而 ``content`` 作为图片的title属性, 也就是当鼠标停在图片上面时显示:: 214 | 215 | If `link` is an image but `content` is not, the syntax creates an 216 | image where the `content` is the title text shown when mouse is over 217 | the image:: 218 | 219 | [robot.jpeg|Robot rocks!] -> <img src="robot.jpeg" title="Robot rocks!"> 220 | 221 | .. Section titles 222 | 223 | 章节标题 224 | -------------- 225 | 226 | 如果文档内容较长, 则通常会分为几个章节. 从Robot Framework 2.7.5 版本开始, 可以使用语法格式 ``= My Title =`` 设置章节标题. 其中, 等号(``=``)的数量表示标题的级别:: 227 | 228 | = First section = 229 | 230 | == Subsection == 231 | 232 | Some text. 233 | 234 | == Second subsection == 235 | 236 | More text. 237 | 238 | = Second section = 239 | 240 | You probably got the idea. 241 | 242 | 注意, 最多支持三级标题, 并且标题文本和前后的等号之间 **必须** 要留有空格. 243 | 244 | 245 | .. Tables 246 | 247 | 表格 248 | ---- 249 | 250 | 表格通过两边留有空格的管道符(即竖线)来作为列的分隔, 用换行表示新的一行(row). 在单元内的文字两边加上等号来标记表头, 如 ``= Header =`` 或 ``=Header=``. 251 | 252 | 表格单元格内的文字同样支持行内样式以及链接格式. 例如:: 253 | 254 | | =A= | =B= | = C = | 255 | | _1_ | Hello | world! | 256 | | _2_ | Hi | 257 | 258 | 生成的表格总是带有窄边框, 正常文字是左对齐, 而表头的字体是粗体且居中. 自动添加空单元格以保证表格每行的长度一致. 例如, 上例转为HTML后的格式如下: 259 | 260 | .. raw:: html 261 | 262 | <div class="doc"> 263 | <table> 264 | <tr><th>A</th><th>B</th><th>C</th></tr> 265 | <tr><td><i>1</i></td><td>Hello</td><td>world</td></tr> 266 | <tr><td><i>2</i></td><td>Hi</td><td></td></tr> 267 | </table> 268 | </div> 269 | 270 | .. note:: 支持表头是 Robot Framework 2.8.2 的新特性. 271 | 272 | .. Lists 273 | 274 | 列表 275 | ----- 276 | 277 | 在行首用连字符(即减号``-``)开始, 后面跟空格, 然后是列表项. 列表项可以分为多行, 多行情况下, 后续行要缩进至少一个空格. 一旦遇到没有以 ``- ``开始的行且没有缩进, 则标志着列表的结束:: 278 | 279 | Example: 280 | - a list item 281 | - second list item 282 | is continued 283 | 284 | This is outside the list. 285 | 286 | 上面的文档转为HTML: 287 | 288 | .. raw:: html 289 | 290 | <div class="doc"> 291 | <p>Example:</p> 292 | <ul> 293 | <li>a list item</li> 294 | <li>second list item is continued</li> 295 | </ul> 296 | <p>This is outside the list.</p> 297 | </div> 298 | 299 | .. note:: 多列表的支持在2.7.2版本增加. 在这之前, 该语法阻止 Libdoc_ 把这些行拼成段落, 300 | 所以最终结果也差不多. 列表项可以分为多行是在2.7.4版本增加的功能. 301 | 302 | .. Preformatted text 303 | 304 | 预格式的文本 305 | ------------ 306 | 307 | Robot Framework 2.7 版本开始, 可以在文档中嵌入预格式的(preformatted)文本. 以 ``| `` 作为一行的开始, 其中管道符后面必须要有至少一个空格(空行是个例外). 最终转换到HTML时, 行首的 ``| `` 被去掉, 但是其它所有的空格都会被保留. 308 | 309 | 在下面的文档中, 中间的两行就是预格式的文本块:: 310 | 311 | Doc before block: 312 | | inside block 313 | | some additional whitespace 314 | After block. 315 | 316 | 转为HTML: 317 | 318 | .. raw:: html 319 | 320 | <div class="doc"> 321 | <p>Doc before block:</p> 322 | <pre>inside block 323 | some additional whitespace</pre> 324 | <p>After block.</p> 325 | </div> 326 | 327 | 当在Robot Framework的测试数据中编写这样包含多个空格的文档, 需要对空格进行转义, 以 :ref:`prevent ignoring spaces`. 所以上面的例子实际会写作:: 328 | 329 | Doc before block: 330 | | inside block 331 | | \ \ \ some \ \ additional whitespace 332 | After block. 333 | 334 | .. Horizontal ruler 335 | 336 | 分割线 337 | ------ 338 | 339 | 水平分割线(``<hr>``)常用来分隔大的章节, 在单独一行内使用3个或以上的连字符即可:: 340 | 341 | Some text here. 342 | 343 | --- 344 | 345 | More text... 346 | 347 | 上面的文档转为HTML: 348 | 349 | .. raw:: html 350 | 351 | <div class="doc"> 352 | <p>Some text here.</p> 353 | <hr> 354 | <p>More text...</p> 355 | </div> 356 | -------------------------------------------------------------------------------- /conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # robotframework-userguide-cn documentation build configuration file, created by 4 | # sphinx-quickstart on Sun May 22 16:38:38 2016. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [] 32 | 33 | # Add any paths that contain templates here, relative to this directory. 34 | templates_path = ['_templates'] 35 | 36 | # The suffix(es) of source filenames. 37 | # You can specify multiple suffix as a list of string: 38 | # source_suffix = ['.rst', '.md'] 39 | source_suffix = '.rst' 40 | 41 | # The encoding of source files. 42 | source_encoding = 'utf-8' 43 | 44 | # The master toctree document. 45 | master_doc = 'index' 46 | 47 | # General information about the project. 48 | project = u'robotframework-userguide-cn' 49 | copyright = u'2016, davyyy' 50 | author = u'davyyy' 51 | 52 | # The version info for the project you're documenting, acts as replacement for 53 | # |version| and |release|, also used in various other places throughout the 54 | # built documents. 55 | # 56 | # The short X.Y version. 57 | version = u'3.0' 58 | # The full version, including alpha/beta/rc tags. 59 | release = u'3.0.0' 60 | 61 | # The language for content autogenerated by Sphinx. Refer to documentation 62 | # for a list of supported languages. 63 | # 64 | # This is also used if you do content translation via gettext catalogs. 65 | # Usually you set "language" from the command line for these cases. 66 | language = 'zh_CN' 67 | 68 | # There are two options for replacing |today|: either, you set today to some 69 | # non-false value, then it is used: 70 | #today = '' 71 | # Else, today_fmt is used as the format for a strftime call. 72 | #today_fmt = '%B %d, %Y' 73 | 74 | # List of patterns, relative to source directory, that match files and 75 | # directories to ignore when looking for source files. 76 | # This patterns also effect to html_static_path and html_extra_path 77 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 78 | 79 | # The reST default role (used for this markup: `text`) to use for all 80 | # documents. 81 | #default_role = None 82 | 83 | # If true, '()' will be appended to :func: etc. cross-reference text. 84 | #add_function_parentheses = True 85 | 86 | # If true, the current module name will be prepended to all description 87 | # unit titles (such as .. function::). 88 | #add_module_names = True 89 | 90 | # If true, sectionauthor and moduleauthor directives will be shown in the 91 | # output. They are ignored by default. 92 | #show_authors = False 93 | 94 | # The name of the Pygments (syntax highlighting) style to use. 95 | pygments_style = 'sphinx' 96 | 97 | # A list of ignored prefixes for module index sorting. 98 | #modindex_common_prefix = [] 99 | 100 | # If true, keep warnings as "system message" paragraphs in the built documents. 101 | #keep_warnings = False 102 | 103 | # If true, `todo` and `todoList` produce output, else they produce nothing. 104 | todo_include_todos = False 105 | 106 | 107 | # -- Options for HTML output ---------------------------------------------- 108 | 109 | # The theme to use for HTML and HTML Help pages. See the documentation for 110 | # a list of builtin themes. 111 | html_theme = 'alabaster' 112 | 113 | # Theme options are theme-specific and customize the look and feel of a theme 114 | # further. For a list of options available for each theme, see the 115 | # documentation. 116 | #html_theme_options = {} 117 | 118 | # Add any paths that contain custom themes here, relative to this directory. 119 | #html_theme_path = [] 120 | 121 | # The name for this set of Sphinx documents. 122 | # "<project> v<release> documentation" by default. 123 | #html_title = u'robotframework-userguide-cn v[6~[3~3.0.0' 124 | 125 | # A shorter title for the navigation bar. Default is the same as html_title. 126 | #html_short_title = None 127 | 128 | # The name of an image file (relative to this directory) to place at the top 129 | # of the sidebar. 130 | #html_logo = None 131 | 132 | # The name of an image file (relative to this directory) to use as a favicon of 133 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 134 | # pixels large. 135 | #html_favicon = None 136 | 137 | # Add any paths that contain custom static files (such as style sheets) here, 138 | # relative to this directory. They are copied after the builtin static files, 139 | # so a file named "default.css" will overwrite the builtin "default.css". 140 | html_static_path = ['_static'] 141 | 142 | # Add any extra paths that contain custom files (such as robots.txt or 143 | # .htaccess) here, relative to this directory. These files are copied 144 | # directly to the root of the documentation. 145 | html_extra_path = ['_html'] 146 | 147 | # If not None, a 'Last updated on:' timestamp is inserted at every page 148 | # bottom, using the given strftime format. 149 | # The empty string is equivalent to '%b %d, %Y'. 150 | #html_last_updated_fmt = None 151 | 152 | # If true, SmartyPants will be used to convert quotes and dashes to 153 | # typographically correct entities. 154 | #html_use_smartypants = True 155 | 156 | # Custom sidebar templates, maps document names to template names. 157 | #html_sidebars = {} 158 | 159 | # Additional templates that should be rendered to pages, maps page names to 160 | # template names. 161 | #html_additional_pages = {} 162 | 163 | # If false, no module index is generated. 164 | #html_domain_indices = True 165 | 166 | # If false, no index is generated. 167 | #html_use_index = True 168 | 169 | # If true, the index is split into individual pages for each letter. 170 | #html_split_index = False 171 | 172 | # If true, links to the reST sources are added to the pages. 173 | #html_show_sourcelink = True 174 | 175 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 176 | #html_show_sphinx = True 177 | 178 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 179 | #html_show_copyright = True 180 | 181 | # If true, an OpenSearch description file will be output, and all pages will 182 | # contain a <link> tag referring to it. The value of this option must be the 183 | # base URL from which the finished HTML is served. 184 | #html_use_opensearch = '' 185 | 186 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 187 | #html_file_suffix = None 188 | 189 | # Language to be used for generating the HTML full-text search index. 190 | # Sphinx supports the following languages: 191 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' 192 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' 193 | #html_search_language = 'en' 194 | 195 | # A dictionary with options for the search language support, empty by default. 196 | # 'ja' uses this config value. 197 | # 'zh' user can custom change `jieba` dictionary path. 198 | #html_search_options = {'type': 'default'} 199 | 200 | # The name of a javascript file (relative to the configuration directory) that 201 | # implements a search results scorer. If empty, the default will be used. 202 | #html_search_scorer = 'scorer.js' 203 | 204 | # Output file base name for HTML help builder. 205 | htmlhelp_basename = 'robotframework-userguide-cndoc' 206 | 207 | # -- Options for LaTeX output --------------------------------------------- 208 | 209 | latex_elements = { 210 | # The paper size ('letterpaper' or 'a4paper'). 211 | #'papersize': 'letterpaper', 212 | 213 | # The font size ('10pt', '11pt' or '12pt'). 214 | #'pointsize': '10pt', 215 | 216 | # Additional stuff for the LaTeX preamble. 217 | #'preamble': '', 218 | 219 | # Latex figure (float) alignment 220 | #'figure_align': 'htbp', 221 | } 222 | 223 | # Grouping the document tree into LaTeX files. List of tuples 224 | # (source start file, target name, title, 225 | # author, documentclass [howto, manual, or own class]). 226 | latex_documents = [ 227 | (master_doc, 'robotframework-userguide-cn.tex', u'robotframework-userguide-cn Documentation', 228 | u'davyyy', 'manual'), 229 | ] 230 | 231 | # The name of an image file (relative to this directory) to place at the top of 232 | # the title page. 233 | #latex_logo = None 234 | 235 | # For "manual" documents, if this is true, then toplevel headings are parts, 236 | # not chapters. 237 | #latex_use_parts = False 238 | 239 | # If true, show page references after internal links. 240 | #latex_show_pagerefs = False 241 | 242 | # If true, show URL addresses after external links. 243 | #latex_show_urls = False 244 | 245 | # Documents to append as an appendix to all manuals. 246 | #latex_appendices = [] 247 | 248 | # If false, no module index is generated. 249 | #latex_domain_indices = True 250 | 251 | 252 | # -- Options for manual page output --------------------------------------- 253 | 254 | # One entry per manual page. List of tuples 255 | # (source start file, name, description, authors, manual section). 256 | man_pages = [ 257 | (master_doc, 'robotframework-userguide-cn', u'robotframework-userguide-cn Documentation', 258 | [author], 1) 259 | ] 260 | 261 | # If true, show URL addresses after external links. 262 | #man_show_urls = False 263 | 264 | 265 | # -- Options for Texinfo output ------------------------------------------- 266 | 267 | # Grouping the document tree into Texinfo files. List of tuples 268 | # (source start file, target name, title, author, 269 | # dir menu entry, description, category) 270 | texinfo_documents = [ 271 | (master_doc, 'robotframework-userguide-cn', u'robotframework-userguide-cn Documentation', 272 | author, 'robotframework-userguide-cn', 'One line description of project.', 273 | 'Miscellaneous'), 274 | ] 275 | 276 | # Documents to append as an appendix to all manuals. 277 | #texinfo_appendices = [] 278 | 279 | # If false, no module index is generated. 280 | #texinfo_domain_indices = True 281 | 282 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 283 | #texinfo_show_urls = 'footnote' 284 | 285 | # If true, do not generate a @detailmenu in the "Top" node's menu. 286 | #texinfo_no_detailmenu = False 287 | -------------------------------------------------------------------------------- /ExtendingRobotFramework/RemoteLibrary.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. _remote library interface: 5 | 6 | 远程测试库接口 7 | ============== 8 | 9 | 远程测试库接口使得测试库可以运行在Robot Framework所在之外的机器上, 并且也使测试库的实现语言不再局限于原生支持的Python和Java. 对于测试库的用户来说, 远程库和使用其它测试库基本雷同. 使用远程测试库接口来开发测试库也和创建 :ref:`普通测试库 <creating test libraries>` 大同小异. 10 | 11 | 12 | .. contents:: 13 | :depth: 2 14 | :local: 15 | 16 | .. Introduction 17 | 18 | 介绍 19 | ---- 20 | 21 | 使用远程测试库API的两大原因: 22 | 23 | * 是实际测试库和Robot Framework运行在不同的机器上, 可以实现分布式的测试. 24 | 25 | * 远程测试库可以使用支持 :ref:`XML-RPC` 远程协议的任意编程语言来实现. 26 | 对于大部分主流编程语言如Python, Java, Ruby, .NET, Clojure, Perl 和 node.js, 当前已经存在了 `现成可用的远程服务 <https://code.google.com/p/robotframework/wiki/RemoteLibrary#Available_remote_servers>`_ 实现. 27 | 28 | 远程库接口由 :ref:`standard libraries` 中的 `Remote` 库提供. Remote库自身不提供任何关键字, 只是作为一个代理存在于测试框架和在别处实现的关键字之间. 29 | 30 | Remote库通过远程服务器和实际的库进行交互, 它们之间的通信是基于XML-RPC的一种简单的 :ref:`remote protocol`. 31 | 32 | 整体的结构参见下图: 33 | 34 | .. figure:: ./remote.png 35 | 36 | Robot Framework architecture with Remote library 37 | 38 | 39 | .. note:: Remote库的远程客户端使用的是Python标准库 xmlrpclib_ . 不支持某些XML-RPC 40 | 服务器实现的自定义扩展. 41 | 42 | .. _xmlrpclib: http://docs.python.org/2/library/xmlrpclib.html 43 | 44 | .. Taking Remote library into use 45 | 46 | 使用Remote库 47 | ------------ 48 | 49 | .. Importing Remote library 50 | 51 | 导入Remote库 52 | ~~~~~~~~~~~~ 53 | 54 | Remote库需要指定远程服务器的地址, 其它使用关键字的方式和别的测试库并无二致. 如果在一个测试套件中用到多次Remote库, 或者只是想要取个描述性的名字, 都可以在import时使用 :ref:`WITH NAME syntax`. 55 | 56 | .. sourcecode:: robotframework 57 | 58 | *** Settings *** 59 | Library Remote http://127.0.0.1:8270 WITH NAME Example1 60 | Library Remote http://example.com:8080/ WITH NAME Example2 61 | Library Remote http://10.0.0.2/example 1 minute WITH NAME Example3 62 | 63 | 如果没有提供地址, 则上面第一个例子中的URL将是Remote库所用默认值. 类似地, 如果没有指定端口, 则默认使用端口号8270. (82和70在ASCII码中分别对应字母R和F) 64 | 65 | .. note:: 当在本机使用时, 推荐使用地址 ``127.0.0.1``, 避免使用 ``localhost``. 66 | 因为在Windows上, 地址解析可能会非常的慢, 见 `问题 <14504450>`_. 67 | 在2.8.4版本之前的Robot Framework中Remote库默认地址用的是``localhost`` 68 | 69 | .. note:: 值得注意的是, 如果远程服务器地址的后面没有路径, 70 | Remote库所使用的 `xmlrpclib模块 <xmlrpclib>`_ 会默认使用 ``/RPC2`` 作为路径. 也就是说, 实际使用中 ``http://127.0.0.1:8270`` 等价于 71 | ``http://127.0.0.1:8270/RPC2``. 这是否会带来问题取决于远程服务器的实现. 72 | 如果指定了路径, 哪怕只有一个 ``/``, 则后面不会再自动追加. 例如, 73 | ``http://127.0.0.1:8270/`` 和 ``http://127.0.0.1:8270/my/path`` 都将原封不动. 74 | 75 | 上面的最后一个例子展示了如何设置超时时间(timeout). timeout是Remote库的第2个可选参数. 超时时长用于初始连接服务器, 或者中途连接中断的情形. 超时时间的格式是Robot Framework 的 :ref:`time format` ,如 ``60s`` 或 ``2 minutes 10 seconds``. 76 | 77 | 默认的超时值取决于操作系统和其配置, 一般是几分钟. 注意如果超时时长短于关键字的执行时间, 则关键字会被中断. 78 | 79 | .. note:: Robot Framework 2.8.6版本开始支持timeout参数. 80 | Python/Jython 2.5 或 IronPython中timeout不生效. 81 | 82 | .. _14504450: http://stackoverflow.com/questions/14504450/pythons-xmlrpc-extremely-slow-one-second-per-call 83 | 84 | .. Starting and stopping remote servers 85 | 86 | 远程服务器的启停 87 | ~~~~~~~~~~~~~~~~ 88 | 89 | 在导入Remote库之前, 提供关键字的远程服务器必须先启动. 如果服务器在测试执行之前启动, 则可以像上面的例子一样使用普通的 :setting:`Library` 来设置. 此外, 服务器还可以通过其它关键字(例如, Process_ or `SSH <sshlibrary>`_ )来启动, 这种情况下需要使用 :ref:`库导入关键字 <using Import Library keyword>`, 否则远程库将不可用. 90 | 91 | 远程服务器如何停止取决于它的实现方式. 典型的服务器支持以下方法: 92 | 93 | * 不管使用什么库, 远程服务器应该提供 :name:`Stop Remote Server` 关键字, 94 | 这样可以很容易地在测试执行中停止服务. 95 | * 远程服务器应该在XML-RPC接口中提供 ``stop_remote_server`` 方法. 96 | * 在运行服务器程序的终端(console)按下 ``Ctrl-C`` 可以停止服务. 97 | * 可以通过终止操作系统的进程(例如, ``kill``)来停止服务. 98 | 99 | * Regardless of the library used, remote servers should provide :name:`Stop 100 | Remote Server` keyword that can be easily used by executed tests. 101 | * Remote servers should have `stop_remote_server` method in their 102 | XML-RPC interface. 103 | * Hitting `Ctrl-C` on the console where the server is running should 104 | stop the server. 105 | * The server process can be terminated using tools provided by the 106 | operating system (e.g. ``kill``). 107 | 108 | .. note:: :name:`Stop Remote Server` 关键字或 `stop_remote_server` 方法 109 | 都不是必需的. 110 | 111 | .. _sshlibrary: https://github.com/robotframework/SSHLibrary 112 | 113 | .. _supported argument and return value types: 114 | 115 | 支持的参数和返回值类型 116 | ---------------------- 117 | 118 | 由于XML-RPC协议并不支持所有可能的对象类型, 所以在Remote库和远程服务器之间传递的值必须要转换为某种兼容的类型. 这种转换适用于关键字的参数传递(Remote库->远程服务器)以及返回值(远程服务器->Remote库). 119 | 120 | Remote库和Python的远程服务器遵从下面的规则来处理Python值. 其它远程服务器的处理方式也是类似的. 121 | 122 | 123 | * 字符串, 数字, 布尔值都无需修改, 直接传递. 124 | 125 | * Python ``None`` 转换为空字符串. 126 | 127 | * 所有的列表, 元组和其它可迭代对象(除了字符串和字典)都以列表(list)来传递, 其中的内容都是递归处理. 128 | 129 | * 字典和其它映射(mappings)作为字典传递, 其中的键转换为字符串, 值按支持类型转换, 同样递归处理. 130 | 131 | * 返回的字典转换为一种所谓的 *可通过点号访问的字典*, 这种字典使用 :ref:`extended variable syntax` 来访问键值, 如 ``${result.key}``. 嵌套的字典 ``${root.child.leaf}``. 132 | 133 | * 如果字符串包含了XML中不能表示的ASCII字节(例如, 空字节), 则将以 `Binary objects`_ 传递, 内部使用的是XML-RPC base64数据类型. 接收到的Binary objects会自动转换回字符串. 134 | 135 | * 其它类型转换为字符串. 136 | 137 | .. note:: 在Robot Framework 2.8.3版本之前, 只有列表, 元组和字典可以按上述规则处理. 138 | 其它迭代器和映射对象并不支持. 此外, 支持binary是Robot Framework 2.8.4版本功能, 返回点号返回的字典是Robot Framework 2.9新增功能. 139 | 140 | .. _Binary objects: http://docs.python.org/2/library/xmlrpclib.html#binary-objects 141 | 142 | .. _remote protocol: 143 | 144 | 远程协议 145 | -------- 146 | 147 | 本节介绍Remote库和远程服务器之间的通信协议. 这部分信息主要针对的是要创建远程服务的人. 现成的Python和Ruby服务器都可以用作示例. 148 | 149 | 该远程协议是基于 :ref:`XML-RPC` 实现的, XML-RPC是通过HTTP传递XML来实现的一个简单的远程过程调用(remote procedure call)协议. 150 | 大部分主流的编程语言(Python, Java, C, Ruby, Perl, Javascript, PHP,...)都内置或者可通过扩展来支持XML-RPC. 151 | 152 | 153 | .. Required methods 154 | 155 | 必需的方法 156 | ~~~~~~~~~~ 157 | 158 | 一个远程服务器就是一个XML-RPC服务器, 其公共的接口提供了 :ref:`dynamic library API` 所要求的方法. 其中 ``get_keyword_names`` 和 ``run_keyword`` 是必须的, ``get_keyword_arguments`` 和 ``get_keyword_documentation`` 为推荐实现. 注意这些方法名现在还不支持使用驼峰命名法. 159 | 160 | 实际的关键字是如何实现的和Remote库并无关联. 远程服务器既可以仅充当一个真正测试库的包装器(wrapper), 就像提供的Python和Ruby服务器那样, 也可以自己实现关键字. 161 | 162 | 远程服务器可以在公共接口中额外提供 ``stop_remote_server`` 方法, 以便停止服务. 最好还可以将此方法自动暴露为关键字 :name:`Stop Remote Server`,以便在测试用例中使用. 允许用户停止服务并不总是合适的, 所以服务器最好还要提供某种方法来控制此功能. 例如, 提供一个方法(并暴露为关键字), 返回 ``True`` 或者 ``False`` 来标示该服务器是否允许被终止. 这样外部的工具也有办法知道停止服务器是否成功. 163 | 164 | .. 不太明白这个方法的必要性 165 | 166 | 167 | 提供的Python远程服务器可作为一个实现的参考. 168 | 169 | .. Getting remote keyword names and other information 170 | 171 | 获取远程关键字名称和其它信息 172 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 173 | 174 | Remote库通过调用 ``get_keyword_names`` 方法来从远程服务器上获取其提供的关键字列表. 该方法必须将关键字名称以字符串的列表形式返回. 175 | 176 | 远程服务器可以, 也应该, 实现 ``get_keyword_arguments`` 和 ``get_keyword_documentation`` 方法来提供关于关键字更多的信息. 这两个方法都接受关键字的名称作为参数. 关键字的参数必须以字符串的列表返回, 其中格式和 :ref:`动态库的定义 <getting keyword arguments>` 一样, 而关键字的文档则必须以 :ref:`字符串 <getting keyword documentation>` 返回. 177 | 178 | 远程服务器还可以提供 :ref:`general library documentation <getting general library documentation>` , 供文档生成工具 Libdoc_ 使用. 179 | 180 | .. _executing remote keywords: 181 | 182 | 远程关键字的执行 183 | ~~~~~~~~~~~~~~~~ 184 | 185 | 当Remote库想要远程服务器执行某个关键字时, 调用远程服务器的的 ``run_keyword`` 方法, 并传入关键字的名字和一系列参数, 还可能有字典表示的 :ref:`自由命名参数 <different argument syntaxes>`. 基础类型参数可以直接使用, 复杂的类型 :ref:`被转换为支持的类型 <supported argument and return value types>`. 186 | 187 | 远程服务器的执行结果必须以字典形式返回, 其中包含的项参见下表. 注意, 其中只有 ``status`` 字段是必须的, 其它如果用不上的都可忽略. 188 | 189 | .. table:: Entries in the remote result dictionary 190 | :class: tabular 191 | 192 | +-------------+----------------------------------------------------------------------------+ 193 | | Name | Explanation | 194 | +=============+============================================================================+ 195 | | status | 必填, 执行状态, ``PASS`` 或 ``FAIL``. | 196 | +-------------+----------------------------------------------------------------------------+ 197 | | output | 可被写入日志文件的输出信息, 必须返回单个字符串, 但是其中可以包含 | 198 | | | 很多内容, 还可以设置 :ref:`日志级别 <logging information>`. | 199 | | | ``*INFO* First message\n*HTML* <b>2nd</b>\n*WARN*Another message``. | 200 | | | 还可以嵌入 :ref:`timestamps` , 例如: | 201 | | | ``*INFO:1308435758660* Message with timestamp``. | 202 | +-------------+----------------------------------------------------------------------------+ 203 | | return | 可能的返回值. | 204 | +-------------+----------------------------------------------------------------------------+ 205 | | | 必须是 :ref:`支持的类型 <supported argument and return value types>` 之一. | 206 | | error | 可能的错误信息. 当执行出错是用到. | 207 | +-------------+----------------------------------------------------------------------------+ 208 | | traceback | 可能的 stack trace, 当执行出错时, 以DEBUG级别 | 209 | | | :ref:`写入日志 <reporting keyword status>`. | 210 | +-------------+----------------------------------------------------------------------------+ 211 | | continuable | 如果设置为 ``True``, 或者任何在Python中视作 ``True`` 的值. | 212 | | | 则发生的错误视作 :ref:`可继续的 <continue on failure>` | 213 | | | New in Robot Framework 2.8.4. | 214 | +-------------+----------------------------------------------------------------------------+ 215 | | fatal | 和 ``continuable`` 类似, 表示当前的错误是 | 216 | | | :ref:`fatal <stopping test execution gracefully>`. | 217 | | | New in Robot Framework 2.8.4. | 218 | +-------------+----------------------------------------------------------------------------+ 219 | 220 | .. Different argument syntaxes 221 | 222 | 参数语法 223 | ~~~~~~~~ 224 | 225 | Remote库是一个 :ref:`dynamic library`, 因此它和其它动态库一样, :ref:`遵从相同的规则 <getting keyword arguments>`, 处理不同的参数语法. 包括必填参数, 默认值, varargs, 以及 :ref:`命名参数语法 <named argument syntax with dynamic libraries>`. 226 | 227 | 自由命名参数(``**kwargs``)主要也和 :ref:`其它动态库一样 <free keyword arguments with dynamic libraries>`. 228 | 229 | 首先, ``get_keyword_arguments`` 需要返回参数列表的规范, 其中必须包含 ``**kwargs``, 这点和其它动态库是一样的. 主要的不同在于远程服务器的 ``run_keyword`` 方法必须包含一个可选的第3个参数, 用来接收用户指定的kwargs. 为了向后兼容, 这个参数必须设置为可选的(optional), 因为Remote库只在测试数据用到时才会传递kwargs到 ``run_keyword`` 方法. 230 | 231 | 实际上 ``run_keyword`` 和下面的Python和Java示例看上去差不多, 差别在于程序语言是怎么处理可选参数的. 232 | 233 | .. sourcecode:: python 234 | 235 | def run_keyword(name, args, kwargs=None): 236 | # ... 237 | 238 | 239 | .. sourcecode:: java 240 | 241 | public Map run_keyword(String name, List args) { 242 | // ... 243 | } 244 | 245 | public Map run_keyword(String name, List args, Map kwargs) { 246 | // ... 247 | } 248 | 249 | .. note:: Remote library supports ``**kwargs`` starting from 250 | Robot Framework 2.8.3. 251 | -------------------------------------------------------------------------------- /Appendices/CommandLineOptions.rst: -------------------------------------------------------------------------------- 1 | .. All command line options 2 | 3 | 命令行选项 4 | ================= 5 | 6 | 本附录中列出了所有在 `执行测试用例`_ 和 `后处理输出`_ 时可用的命令行选项. 此外, 可影响执行的环境变量也列了出来. 7 | 8 | .. contents:: 9 | :depth: 2 10 | :local: 11 | 12 | .. Command line options for test execution 13 | 14 | 测试执行相关的命令行选项 15 | --------------------------------------- 16 | 17 | -N, --name <name> `Sets the name`_ of the top-level test suite. 18 | -D, --doc <document> `Sets the documentation`_ of the top-level test suite. 19 | -M, --metadata <name:value> `Sets free metadata`_ for the top level test suite. 20 | -G, --settag <tag> `Sets the tag(s)`_ to all executed test cases. 21 | -t, --test <name> `Selects the test cases by name`_. 22 | -s, --suite <name> `Selects the test suites`_ by name. 23 | -R, --rerunfailed <file> `Selects failed tests`_ from an earlier `output file`_ to be re-executed. 24 | --runfailed <file> Deprecated since Robot Framework 2.8.4. 25 | Use :option:`--rerunfailed` instead. 26 | -i, --include <tag> `Selects the test cases`_ by tag. 27 | -e, --exclude <tag> `Selects the test cases`_ by tag. 28 | -c, --critical <tag> Tests that have the given tag are `considered critical`_. 29 | -n, --noncritical <tag> Tests that have the given tag are `not critical`_. 30 | -v, --variable <name:value> Sets `individual variables`_. 31 | -V, --variablefile <path:args> Sets variables using `variable files`_. 32 | -d, --outputdir <dir> Defines where to `create output files`_. 33 | -o, --output <file> Sets the path to the generated `output file`_. 34 | -l, --log <file> Sets the path to the generated `log file`_. 35 | -r, --report <file> Sets the path to the generated `report file`_. 36 | -x, --xunit <file> Sets the path to the generated `xUnit compatible result file`_. 37 | --xunitskipnoncritical Mark non-critical tests on `xUnit compatible result file`_ as skipped. 38 | -b, --debugfile <file> A `debug file`_ that is written during execution. 39 | -T, --timestampoutputs `Adds a timestamp`_ to all output files. 40 | --splitlog `Split log file`_ into smaller pieces that open in 41 | browser transparently. 42 | --logtitle <title> `Sets a title`_ for the generated test log. 43 | --reporttitle <title> `Sets a title`_ for the generated test report. 44 | --reportbackground <colors> `Sets background colors`_ of the generated report. 45 | -L, --loglevel <level> `Sets the threshold level`_ for logging. Optionally 46 | the default `visible log level`_ can be given 47 | separated with a colon (:). 48 | --suitestatlevel <level> Defines how many `levels to show`_ in the 49 | *Statistics by Suite* table in outputs. 50 | --tagstatinclude <tag> `Includes only these tags`_ in the *Statistics by Tag* table. 51 | --tagstatexclude <tag> `Excludes these tags`_ from the *Statistics by Tag* table. 52 | --tagstatcombine <tags:title> Creates `combined statistics based on tags`_. 53 | --tagdoc <pattern:doc> Adds `documentation to the specified tags`_. 54 | --tagstatlink <pattern:link:title> Adds `external links`_ to the *Statistics by Tag* table. 55 | --removekeywords <all|passed|name:pattern|tag:pattern|for|wuks> `Removes keyword data`_ 56 | from the generated log file. 57 | --flattenkeywords <for|foritem|name:pattern|tag:pattern> `Flattens keywords`_ 58 | in the generated log file. 59 | --listener <name:args> `Sets a listener`_ for monitoring test execution. 60 | --warnonskippedfiles Show a warning when `an invalid file is skipped`_. 61 | --nostatusrc Sets the `return code`_ to zero regardless of failures 62 | in test cases. Error codes are returned normally. 63 | --runemptysuite Executes tests also if the selected `test suites are empty`_. 64 | --dryrun In the `dry run`_ mode tests are run without executing 65 | keywords originating from test libraries. Useful for 66 | validating test data syntax. 67 | --exitonfailure `Stops test execution <Stopping when first test case fails_>`__ 68 | if any critical test fails. 69 | --exitonerror `Stops test execution <Stopping on parsing or execution error_>`__ 70 | if any error occurs when parsing test data, importing libraries, and so on. 71 | --skipteardownonexit `Skips teardowns`_ is test execution is prematurely stopped. 72 | --prerunmodifier <name:args> Activate `programmatic modification of test data`_. 73 | --prerebotmodifier <name:args> Activate `programmatic modification of results`_. 74 | --randomize <all|suites|tests|none> `Randomizes`_ test execution order. 75 | --console <verbose|dotted|quiet|none> `Console output type`_. 76 | --dotted Shortcut for `--console dotted`. 77 | --quiet Shortcut for `--console quiet`. 78 | -W, --consolewidth <width> `Sets the width`_ of the console output. 79 | -C, --consolecolors <auto|on|ansi|off> `Specifies are colors`_ used on the console. 80 | -K, --consolemarkers <auto|on|off> Show `markers on the console`_ when top level 81 | keywords in a test case end. 82 | -P, --pythonpath <path> Additional locations to add to the `module search path`_. 83 | -E, --escape <what:with> `Escapes characters`_ that are problematic in the console. 84 | -A, --argumentfile <path> A text file to `read more arguments`_ from. 85 | -h, --help Prints `usage instructions`_. 86 | --version Prints the `version information`_. 87 | 88 | .. Command line options for post-processing outputs 89 | 90 | 用于后处理输出的命令行选项 91 | -------------------------- 92 | 93 | -R, --merge Changes result combining behavior to `merging <merging outputs_>`__. 94 | --rerunmerge Deprecated since Robot Framework 2.8.6. 95 | Use :option:`--merge` instead. 96 | -N, --name <name> `Sets the name`_ of the top level test suite. 97 | -D, --doc <document> `Sets the documentation`_ of the top-level test suite. 98 | -M, --metadata <name:value> `Sets free metadata`_ for the top-level test suite. 99 | -G, --settag <tag> `Sets the tag(s)`_ to all processed test cases. 100 | -t, --test <name> `Selects the test cases by name`_. 101 | -s, --suite <name> `Selects the test suites`_ by name. 102 | -i, --include <tag> `Selects the test cases`_ by tag. 103 | -e, --exclude <tag> `Selects the test cases`_ by tag. 104 | -c, --critical <tag> Tests that have the given tag are `considered critical`_. 105 | -n, --noncritical <tag> Tests that have the given tag are `not critical`_. 106 | -d, --outputdir <dir> Defines where to `create output files`_. 107 | -o, --output <file> Sets the path to the generated `output file`_. 108 | -l, --log <file> Sets the path to the generated `log file`_. 109 | -r, --report <file> Sets the path to the generated `report file`_. 110 | -x, --xunit <file> Sets the path to the generated `xUnit compatible result file`_. 111 | --xunitskipnoncritical Mark non-critical tests on `xUnit compatible result file`_ as skipped. 112 | -T, --timestampoutputs `Adds a timestamp`_ to all output files. 113 | --splitlog `Split log file`_ into smaller pieces that open in 114 | browser transparently. 115 | --logtitle <title> `Sets a title`_ for the generated test log. 116 | --reporttitle <title> `Sets a title`_ for the generated test report. 117 | --reportbackground <colors> `Sets background colors`_ of the generated report. 118 | -L, --loglevel <level> `Sets the threshold level`_ to select log messages. 119 | Optionally the default `visible log level`_ can be given 120 | separated with a colon (:). 121 | --suitestatlevel <level> Defines how many `levels to show`_ in the 122 | *Statistics by Suite* table in outputs. 123 | --tagstatinclude <tag> `Includes only these tags`_ in the *Statistics by Tag* table. 124 | --tagstatexclude <tag> `Excludes these tags`_ from the *Statistics by Tag* table. 125 | --tagstatcombine <tags:title> Creates `combined statistics based on tags`_. 126 | --tagdoc <pattern:doc> Adds `documentation to the specified tags`_. 127 | --tagstatlink <pattern:link:title> Adds `external links`_ to the *Statistics by Tag* table. 128 | --removekeywords <all|passed|name:pattern|tag:pattern|for|wuks> `Removes keyword data`_ 129 | from the generated outputs. 130 | --flattenkeywords <for|foritem|name:pattern|tag:pattern> `Flattens keywords`_ 131 | in the generated outputs. 132 | --starttime <timestamp> Sets the `starting time`_ of test execution when creating 133 | reports. 134 | --endtime <timestamp> Sets the `ending time`_ of test execution when creating reports. 135 | --nostatusrc Sets the `return code`_ to zero regardless of failures 136 | in test cases. Error codes are returned normally. 137 | --processemptysuite Processes output files even if files contain 138 | `empty test suites`_. 139 | --prerebotmodifier <name:args> Activate `programmatic modification of results`_. 140 | -C, --consolecolors <auto|on|ansi|off> `Specifies are colors`_ used on the console. 141 | -P, --pythonpath <path> Additional locations to add to the `module search path`_. 142 | -E, --escape <what:with> `Escapes characters`_ that are problematic in the console. 143 | -A, --argumentfile <path> A text file to `read more arguments`_ from. 144 | -h, --help Prints `usage instructions`_. 145 | --version Prints the `version information`_. 146 | 147 | 148 | .. _Sets the name: `Setting the name` 149 | .. _Sets the documentation: `Setting the documentation`_ 150 | .. _Sets free metadata: `Setting free metadata`_ 151 | .. _Sets the tag(s): `Setting tags`_ 152 | .. _Selects the test cases by name: `By test suite and test case names`_ 153 | .. _Selects the test suites: `Selects the test cases by name`_ 154 | .. _Selects failed tests: `Re-executing failed test cases`_ 155 | .. _Selects the test cases: `By tag names`_ 156 | .. _considered critical: `Setting criticality`_ 157 | .. _not critical: `considered critical`_ 158 | .. _ContinueOnFailure: `Continue on failure`_ 159 | .. _Skips teardowns: `Handling Teardowns`_ 160 | .. _SkipTeardownOnExit: `Handling Teardowns`_ 161 | .. _DryRun: `Dry run`_ 162 | .. _Randomizes: `Randomizing execution order`_ 163 | .. _individual variables: `Setting variables in command line`_ 164 | 165 | .. _create output files: `Output directory`_ 166 | .. _Adds a timestamp: `Timestamping output files`_ 167 | .. _Split log file: `Splitting logs`_ 168 | .. _Sets a title: `Setting titles`_ 169 | .. _Sets background colors: `Setting background colors`_ 170 | 171 | .. _Sets the threshold level: `Setting log level`_ 172 | .. _levels to show: `Configuring displayed suite statistics`_ 173 | .. _Includes only these tags: `Including and excluding tag statistics`_ 174 | .. _Excludes these tags: `Includes only these tags`_ 175 | .. _combined statistics based on tags: `Generating combined tag statistics`_ 176 | .. _documentation to the specified tags: `Adding documentation to tags`_ 177 | .. _external links: `Creating links from tag names`_ 178 | 179 | .. _Sets a listener: `Setting listeners`_ 180 | .. _an invalid file is skipped: `Warning on invalid files`_ 181 | .. _test suites are empty: `When no tests match selection`_ 182 | .. _empty test suites: `test suites are empty`_ 183 | .. _Sets the width: `Console width`_ 184 | .. _Specifies are colors: `Console colors`_ 185 | .. _markers on the console: `Console markers`_ 186 | .. _Escapes characters: `Escaping complicated characters`_ 187 | .. _read more arguments: `Argument files`_ 188 | .. _usage instructions: `Getting help and version information`_ 189 | .. _version information: `usage instructions`_ 190 | 191 | .. _Removes keyword data: `Removing and flattening keywords`_ 192 | .. _Flattens keywords: `Removes keyword data`_ 193 | .. _starting time: `Setting start and end time of execution`_ 194 | .. _ending time: `starting time`_ 195 | 196 | 197 | Environment variables for execution and post-processing 198 | ------------------------------------------------------- 199 | 200 | ``ROBOT_OPTIONS`` and ``REBOT_OPTIONS`` 201 | Space separated list of default options to be placed 202 | `in front of any explicit options`__ on the command line. 203 | 204 | ``ROBOT_SYSLOG_FILE`` 205 | Path to a syslog_ file where Robot Framework writes internal 206 | information about parsing test case files and running 207 | tests. 208 | 209 | ``ROBOT_SYSLOG_LEVEL`` 210 | Log level to use when writing to the syslog_ file. 211 | 212 | ``ROBOT_INTERNAL_TRACES`` 213 | When set to any non-empty value, Robot Framework's 214 | internal methods are included in `error tracebacks`__. 215 | 216 | __ `ROBOT_OPTIONS and REBOT_OPTIONS environment variables`_ 217 | __ `Debugging problems`_ 218 | 219 | 220 | .. option:: --prerebotmodifier 221 | 222 | Activate `programmatic modification of results`_. 223 | -------------------------------------------------------------------------------- /GettingStarted/Install.rst: -------------------------------------------------------------------------------- 1 | 安装指导 2 | ======== 3 | 4 | 本文介绍如何在不同的操作系统安装和卸载Robot Frameworks. 5 | 6 | 如果你已经安装了 `pip <http://pip-installer.org>`_ ,那么只需如此:: 7 | 8 | pip install robotframework 9 | 10 | 11 | 概述 12 | ---- 13 | 14 | `Robot Framework <http://robotframework.org>`_ 是使用 `Python <http://python.org>`_ 开发实现, 15 | 同时支持 `Jython <http://jython.org>`_ (JVM) 和 `IronPython <http://ironpython.net>`_ (.NET). 16 | 显然, 这些python解释器至少需要安装其中之一. 17 | 18 | 安装Robot Framework的各种方法都会在下面列出并在随后的章节中详细说明. 19 | 20 | `使用pip安装`_ 21 | 推荐方式. 作为Python标准包管理器, 最新的Python, Jython和IronPython版本里都自带了pip. 22 | 如果你已经有了pip, 只需运行:: 23 | 24 | pip install robotframework 25 | 26 | `从源码安装`_ 27 | 从源码安装不关心是何种操作系统和使用何种Python解释器. 从 `PyPI <https://pypi.python.org/pypi/robotframework>`_ 28 | 下载源码, 或者从 `GitHub 代码仓库 <https://github.com/robotframework/robotframework>`_ clone源码. 29 | 30 | `独立的JAR包安装`_ 31 | 如果使用Jython执行测试就可以, 则最简单的方式是下载独立的 ``robotframework-<version>.jar`` 文件, 32 | 下载地址是 `Maven <http://search.maven.org/#search%7Cga%7C1%7Ca%3Arobotframework>`_. 33 | JAR包中包含了Jython和Robot Framework, 所以只需要系统安装了 `Java <http://java.com>`_ 即可. 34 | 35 | `手动安装`_ 36 | 如果有特殊需求其它方式无法满足的, 可以手动自定义安装. 37 | 38 | 39 | 前提条件 40 | -------- 41 | 42 | Robot Framework 除了可以在 Python_ (both Python 2 and Python 3), Jython_ 43 | (JVM) 和 IronPython_ (.NET) 上运行外, 还可以运行在 `PyPy <http://pypy.org>`_. 44 | 要使用的解释器必须在安装Robot Framework之前安装. 45 | 46 | 使用何种解释器一般取决于测试库和测试环境. 有些库使用的工具或模块只能在Python上运行. 47 | 而其它的库可能使用了一些Java相关的工具, 则需要Jython; 或者使用了.Net库则需要IronPython. 48 | 还有很多工具和库和这些解释器都兼容. 49 | 50 | 如果你没有特殊需求而只是想试试这个框架, 推荐使用Python, 毕竟这是最成熟的解释器, 而且一般 51 | 会比Jython或IronPython更快(特别是启动时间). 而且在大多数的类UNIX操作系统里都内置了. 52 | 53 | Python 2 vs Python 3 54 | ^^^^^^^^^^^^^^^^^^^^ 55 | 56 | Python 2和Python 3虽然是同一种语言, 但是有诸多不兼容的地方. 57 | 例如, Python 3中所有字符串都是Unicode, 而Python 2中缺省是bytes. 58 | 最新的Python 2发布版本是2010年发布的Python 2.7, 将支持到2020年. 59 | 60 | 关于两者之间更多的差别,以及如何编写兼容两个版本的代码,请参考 `Should I use Python 2 or 3?`__ 61 | 62 | Robot Framework 3.0 是首个支持Python 3的版本. 同时也继续支持Python 2, 并且计划在Python 2的 63 | 官方支持期内一直保持支持. 我们希望广大的测试库和工具开发者们也开始关注支持Python 3. 64 | 65 | __ https://wiki.python.org/moin/Python2orPython3 66 | 67 | Python的安装 68 | ^^^^^^^^^^^^ 69 | 70 | 大多数的类UNIX系统如 ``Linux`` 和 ``OS X`` 默认都安装了Python. 71 | Windows用户需要自行安装, 推荐访问Python的官网 http://python.org, 选择适合自己系统的安装文件. 72 | 73 | Robot Framework 3.0 支持 Python 2.6, 2.7, 3.3 以及更新的版本, 不过计划 `在RF3.1版本中放弃支持 Python 2.6`__. 74 | 如果你需要使用更老的系统, Robot Framework 2.5-2.8 支持 Python 2.5, Robot Framework 2.0-2.1 支持 Python 2.3 和 2.4. 75 | 76 | 在Windows下安装Python推荐使用管理员(administrator)安装并且选择安装给所有用户. 77 | 此外, 不能设置环境变量 ``PYTHONCASEOK`` 78 | 79 | .. note:: ``PYTHONCASEOK`` 如果被设置, Python在import module时不区分大小写. 80 | 81 | 安装完Python, 需要配置环境变量 ``PATH``, 82 | 83 | .. tip:: 最新的Python Windows安装文件在安装过程中,可以选择 `Add python.exe to Path`. 该选项默认没有勾选. 84 | 85 | 86 | 87 | __ https://github.com/robotframework/robotframework/issues/2276 88 | 89 | Jython的安装 90 | ^^^^^^^^^^^^ 91 | 92 | 使用了Java实现的测试库或者内部使用了Java工具, 则需要在Jython上运行Robot Framework, 当然, 93 | 这就需要Java运行环境(JRE)或者Java开发工具集(JDK). 这两者的安装超出了本文档的范围, 请参考官网 94 | http://java.com 95 | 96 | 安装Jython则比较简单, 从 http://jython.org 下载安装包, 一个可执行的JAR包, 然后通过命令行运行 97 | `java -jar jython_installer-<version>.jar`. 如果系统有所配置, 也可以双击安装. 98 | 99 | Robot Framework 3.0 支持 Jython 2.7,需要 Java 7 或更新版本. 100 | 如果需要使用更老的 Jython 或 Java 版本, Robot Framework 2.5-2.8 支持 101 | Jython 2.5 (需要 Java 5 或更新), Robot Framework 2.0-2.1 支持 Jython 2.2. 102 | 103 | 安装完Jython, 可能还需要配置环境变量PATH 104 | 105 | 106 | IronPython的安装 107 | ^^^^^^^^^^^^^^^^ 108 | 109 | IronPython_ 使得Robot Framework可以运行在 `.NET平台 <http://www.microsoft.com/net>`_ . 110 | 与 C# 和其它 .NET 语言或APIs交互. 只支持 IronPython 2.7. 111 | 112 | 当使用IronPython, 需要安装一个依赖模块 `elementtree <http://effbot.org/downloads/#elementtree>`_ 113 | (1.2.7 preview release). 这是因为 ``elementtree`` 在IronPython中发布版无法工作( 114 | `详见 <https://github.com/IronLanguages/main/issues/968>`__). 115 | 可以下载该模块的源码, 解压, 并在当前路径的命令行中运行 ``ipy setup.py install`` 116 | 117 | 118 | 配置环境变量 ``PATH`` 119 | ^^^^^^^^^^^^^^^^^^^^^ 120 | 121 | ``PATH`` 环境变量定义了一系列路径, 系统运行命令时默认从这些路径中搜索. 122 | 为了在命令行中更方便的使用 Robot Framework, 推荐将 运行脚本_ 所在的路径添加到 ``PATH``. 123 | 124 | 大多数的类UNIX系统中默认都自带了Python并且配置好了 ``PATH``, 无需额外操作. 125 | 对于Windows, 或其它解释器, ``PATH`` 必须单独配置. 126 | 127 | .. tip:: 最新的Python Windows安装文件在安装过程中,可以选择 `Add python.exe to Path`. 128 | 该选项默认没有勾选. 但是如果勾选了, 将把 Python 安装路径和 ``Python脚本`` 路径 129 | 都加入到 ``PATH``. 130 | 131 | 哪些路径要加入到 ``PATH`` 132 | """"""""""""""""""""""""" 133 | 134 | 到底要将哪些路径加入到 ``PATH`` 中取决于解释器和操作系统. 135 | 第一个路径是python解释器的安装路径(如: ``C:\\Python27``), 另一个则是该解释器的脚本安装路径. 136 | Python和IronPython将脚本安装至安装路径的子目录 ``Scripts`` 中 (如: :file:`C:\\Python27\\Scripts`), 137 | Jython则使用 ``bin`` 路径, (如: :file:`C:\\jython2.7.0\\bin`) 138 | 139 | 注意, ``Scripts`` 或 ``bin`` 路径在解释器安装完后不一定就立即创建, 会在随后安装Robot Framework 140 | 或者其他第三方模块时才创建. 141 | 142 | 在Windows系统中配置 ``PATH`` 143 | """"""""""""""""""""""""""""" 144 | 145 | 假设Python的安装路径是 ``C:\Python27``, 则脚本的路径是 ``C:\Python27\Scripts`` 146 | 147 | 1. 打开设置环境变量的对话框(系统属性-高级-环境变量), 一般分为 `用户变量` 和 `系统变量`, 148 | 两者的区别在于用户变量只影响当前用户, 而系统变量影响所有用户. 149 | 2. 找到 ``PATH`` 变量(注意,Windows系统中环境变量的名称不区分大小写, 也可能是 `Path`), 150 | 选择 `编辑..`, 将 `;C:\Python27;C:\Python27\Scripts` 添加到值的末尾. 151 | 3. 保存 152 | 4. 开启命令行, 检查是否生效 153 | 154 | 注意, 如果安装有多个Python版本, 当执行 ``robot`` 或者 ``rebot`` 时, 将总是使用 *第一个* 出现在 155 | ``PATH`` 中的Python解释器, 而不管该脚本是安装在哪个版本下的. 为了避免这种情况, 可以直接执行 156 | robot模块, 如 `C:\\Python27\\python.exe -m robot`. 157 | 158 | 在类UNIX系统中配置 ``PATH`` 159 | """"""""""""""""""""""""""""" 160 | 161 | 类UNIX系统一般通过编辑系统或者用户配置文件来配置环境变量, 具体的文件因系统而异. 162 | 163 | 配置 ``https_proxy`` 164 | ^^^^^^^^^^^^^^^^^^^^^^ 165 | 166 | 如果要 `使用pip安装`_ , 但是当前系统是通过代理上网, 则需要设置 ``https_proxy`` 环境变量. 167 | 具体的设置方式因系统而异, Windows系统一般是在Internet选项中设置, 其它类UNIX系统的设置 168 | 类似 `配置环境变量 PATH`_ . 代理服务器的地址需要咨询网络管理员, 一般是一个URL地址, 169 | 如 `http://10.0.0.42:8080`. 170 | 171 | 使用pip安装 172 | ------------ 173 | 174 | Python标准包管理器是 pip_, 但还有其它的选择, 例如 :ref:`Buildout <http://buildout.org>` 175 | 和 :ref:`easy_install <http://peak.telecommunity.com/DevCenter/EasyInstall>`. 176 | 本章节只覆盖使用pip的情况, 其它包管理器应该也可以用来安装Robot Framework. 177 | 178 | 最新的Python, Jython和IronPython版本已经捆绑安装了pip. 179 | 180 | Python下安装pip 181 | ^^^^^^^^^^^^^^^^^ 182 | 183 | 从2.7.9版本开始, Python的Windows安装包已经默认会安装并激活pip. 如果你已经设置完了环境变量, 184 | 那么就直接运行 ``pip install robotframework`` 185 | 186 | Windows之外的系统, 或者比较老的Python版本, 需要自己安装pip. Linux系统可能使用系统的包管理器 187 | 比如 Apt 或者 Yum 安装, 当然也可以参考 pip_ 主页上的指导手册进行操作. 188 | 189 | 如果你安装了多个Python版本和pip, 当运行 ``pip`` 命令时, 实际执行的是最先出现在 PATH_ 定义中 190 | 的. 可以直接指定Python版本, 调用 ``pip`` 模块: 191 | 192 | .. sourcecode:: bash 193 | 194 | python -m pip install robotframework 195 | python3 -m pip install robotframework 196 | 197 | Jython下安装pip 198 | ^^^^^^^^^^^^^^^^^^ 199 | 200 | Jython 2.7 包含了 pip, 但是在使用前需要激活, 使用下面的命令: 201 | 202 | .. sourcecode:: bash 203 | 204 | jython -m ensurepip 205 | 206 | Jython的pip安装至 :file:`<JythonInstallation>/bin` 路径. 执行 `pip install robotframework` 207 | 命令实际运行的是否是该路径下的, 同样取决于最先出现在 PATH_ 定义中的pip. 208 | 另一种方式是直接指定Jython版本, 调用 ``pip`` 模块: 209 | 210 | .. sourcecode:: bash 211 | 212 | jython -m pip install robotframework 213 | 214 | IronPython下安装pip 215 | ^^^^^^^^^^^^^^^^^^^^ 216 | 217 | IronPython从 `版本 2.7.5`__ 开始包含pip. 与Jython类似, 需要先激活: 218 | 219 | .. sourcecode:: bash 220 | 221 | ipy -X:Frames -m ensurepip 222 | 223 | 注意 `-X:Frames` 命令行选项在激活和使用pip时都要带上. 224 | 225 | IronPython将pip安装至 :file:`<IronPythonInstallation>/Scripts` 路径. 226 | 运行 `pip install robotframework` 实际调用的pip版本同样取决于最先出现 227 | 在 PATH_ 定义中的pip. 可以直接运行IronPython调用 ``pip`` 模块: 228 | 229 | .. sourcecode:: bash 230 | 231 | ipy -X:Frames -m pip install robotframework 232 | 233 | IronPython 早于 2.7.5 的版本官方并不支持 pip. 234 | 235 | __ http://blog.ironpython.net/2014/12/pip-in-ironpython-275.html 236 | 237 | 使用pip 238 | ^^^^^^^^^^^^^^^^^^^^ 239 | 240 | 安装完pip, 并设置完 https代理_ (如果需要的话), 使用pip是很简单的事情. 最 241 | 简单的办法就是直接使用pip, 让它自动从 `Python Package Index (PyPI)`__ 下载 242 | 并安装包. 243 | 244 | __ PyPI_ 245 | 246 | .. sourcecode:: bash 247 | 248 | # Install the latest version 249 | pip install robotframework 250 | 251 | # Upgrade to the latest version 252 | pip install --upgrade robotframework 253 | 254 | # Install a specific version 255 | pip install robotframework==2.9.2 256 | 257 | # Install separately downloaded package (no network connection needed) 258 | pip install robotframework-3.0.tar.gz 259 | 260 | # Uninstall 261 | pip uninstall robotframework 262 | 263 | 注意, pip 1.4 及随后的版本默认只安装稳定版本. 如果你想要安装 alpha 或者 beta 或者 264 | 发布候选版本, 需要显示指定版本号, 或者使用 :option:`--pre` 选项: 265 | 266 | .. sourcecode:: bash 267 | 268 | # Install 3.0 beta 1 269 | pip install robotframework==3.0b1 270 | 271 | # 更新到最新版本, 即使该版本是pre-release版本 272 | pip install --pre --upgrade robotframework 273 | 274 | 从源码安装 275 | ------------------- 276 | 277 | 从源码安装适用于任何操作系统上的任何Python解释器. 看上去从源码安装比较恐怖, 278 | 实际过程很简单直接. 279 | 280 | 获取源码 281 | ^^^^^^^^^^^^^^^^^^^^ 282 | 283 | 源码一般就是下载 `.tar.gz` 格式的源代码打包文件. 最新的版本可以在 PyPI_ 下载. 284 | 2.8.1和以前的版本可以在 `Google Code <https://code.google.com/p/robotframework/downloads/list?can=1>`_ 下载. 285 | 将包下载到本地后, 先解压, 得到文件夹, 名称为 `robotframework-<version>`, 其中 286 | 包含所有源代码和安装所需要的脚本. 287 | 288 | 此外, 还可以通过 `GitHub 代码仓库`_ 克隆项目源码. 这样可以获取到最新的代码, 289 | 也可以切换到不同的发布版本或者标签. 290 | 291 | 292 | 安装 293 | ^^^^^^^^^^^^^^^^^^^^ 294 | 295 | Robot Framework 使用 Python 标准的 ``setup.py`` 脚本来执行安装. 该脚本就在源码 296 | 路径内, 使用命令行调用对应的python解释器执行: 297 | 298 | .. sourcecode:: bash 299 | 300 | python setup.py install 301 | jython setup.py install 302 | ipy setup.py install 303 | 304 | ``setup.py`` 可以接受若干参数, 例如, 安装到其它不需要管理员权限的路径. 305 | 具体帮助请运行 `python setup.py --help` . 306 | 307 | .. _standalone JAR distribution: 308 | 309 | 独立的JAR包安装 310 | ------------------- 311 | 312 | Robot Framework 还提供了一个独立的Java包, 包含了 Jython_ 和 Robot Framework 版本. 313 | 这样就只需要 Java_ 环境即可. 这样做的好处是无需安装, 但是不足之处就是这样无法再使用 314 | 普通的 Python_ 解释器运行. 315 | 316 | JAR包的名字是 ``robotframework-<version>.jar``, 可在 `Maven`_ 获取. 317 | 下载后, 可以直接按下面的方式运行测试: 318 | 319 | .. sourcecode:: bash 320 | 321 | java -jar robotframework-3.0.jar mytests.robot 322 | java -jar robotframework-3.0.jar --variable name:value mytests.robot 323 | 324 | 如果想要使用 ``Rebot`` 运行 `输出结果处理`_, 或者其它内置的工具, 则需要将这些 325 | 命令名称, ``rebot``, ``libdoc``, ``testdoc`` 或 ``tidy`` 作为第一个参数传递: 326 | 327 | .. sourcecode:: bash 328 | 329 | java -jar robotframework-3.0.jar rebot output.xml 330 | java -jar robotframework-3.0.jar libdoc MyLibrary list 331 | 332 | 获取帮助提示, 不带参数的执行该JAR包. 333 | 334 | 除了Python标准库和Robot Framework模块, JAR包版本从 2.9.2 开始还包含了 PyYAML 335 | 依赖包, 用来处理 ``yaml`` 格式的变量文件. 336 | 337 | .. _manual installation: 338 | 339 | 手动安装 340 | -------- 341 | 342 | 如果不想使用上述的自动安装方式, 可以手动安装将Robot Framework安装到自己指定的路径. 343 | 按照如下步骤: 344 | 345 | 1. 获取源码 346 | 2. 拷贝源码到需要的地方 347 | 3. 决定 怎样运行测试 348 | 349 | 检查安装结果 350 | ------------ 351 | 352 | 成功安装后, 执行 `运行脚本`_ 并带上 :option:`--version` 选项, 如果如下所示可以获取到 353 | Robot Framework的版本和Python解释器的版本, 则表示安装成功: 354 | 355 | .. sourcecode:: bash 356 | 357 | $ robot --version 358 | Robot Framework 3.0 (Python 2.7.10 on linux2) 359 | 360 | $ rebot --version 361 | Rebot 3.0 (Python 2.7.10 on linux2) 362 | 363 | 如果运行失败并报"命令找不到"类似错误提示, 首先要去检查 PATH_ 的设置. 364 | 365 | 文件被安装到了哪里 366 | ^^^^^^^^^^^^^^^^^^^ 367 | 368 | 当使用自动安装包时, Robot Framework源码会被拷贝到存放Python外部模块的路径下. 369 | 在类UNIX系统中, 如果是系统自带的Python, 这个路径的具体位置在不同操作系统中也 370 | 有所不同. 如果是自己安装的, 则这个路径一般是安装路径下面的 :file:`Lib/site-packages`. 371 | 例如, :file:`C:\\Python27\\Lib\\site-packages`. 实际的Robot Framework 372 | 代码所在的文件夹名为 :file:`robot`. 373 | 374 | Robot Framework `运行脚本`_ 则创建并被拷贝到另一个平台相关的位置. 在类UNIX 375 | 系统中, 一般是 :file:`/usr/bin` 或 :file:`/usr/local/bin`.在Windows中, 376 | 包括使用Jython 和 IronPython, 这个目录在解释器安装目录下的 :file:`Scripts` 377 | 或 :file:`bin` 目录. 378 | 379 | 380 | 卸载 381 | ---- 382 | 383 | 最简单的卸载Robot Framework的方式也是使用 pip_: 384 | 385 | .. sourcecode:: bash 386 | 387 | pip uninstall robotframework 388 | 389 | 即使是使用源码安装的包也可以使用pip删除. 如果没有pip或者是手动安装的, 390 | 则找到文件安装路径, 将其手动删除即可 391 | 392 | 升级 393 | ----- 394 | 395 | 如果使用 pip_, 升级到某个新版本可以带上 `--upgrade` 选项, 或者直接指定 396 | 这个版本号: 397 | 398 | .. sourcecode:: bash 399 | 400 | pip install --upgrade robotframework 401 | pip install robotframework==2.9.2 402 | 403 | 使用pip会自动卸载旧版本, 然后再安装新版本. 如果使用源码安装方式, 则直接覆盖安装即可. 404 | 如果遇到问题, 先 卸载_, 再安装. 405 | 406 | 当升级 Robot Framework时, 有时新版本包含了向后不兼容的改动, 这些改动会影响现有的测试. 407 | 一般这种情况在小版本变化是很少发生,如 2.8.7 或 2.9.2, 但是在大版本变化时比较普遍, 如 408 | 2.9 和 3.0. 向后不兼容的改动和说明, 以及废弃的特性功能, 都在发布说明中会有解释. 所以, 409 | 在升级一个大版本前, 最好先仔细学习下发布说明. 410 | 411 | 运行 Robot Framework 412 | --------------------- 413 | 414 | .. _runner script: 415 | 416 | 使用 ``robot`` 和 ``rebot`` 脚本 417 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 418 | 419 | 从Robot Framework 3.0版本开始, 测试执行使用 ``robot`` 脚本, 运行结果处理使用 420 | ``rebot`` 脚本: 421 | 422 | .. sourcecode:: bash 423 | 424 | robot tests.robot 425 | rebot output.xml 426 | 427 | 如果 PATH_ 设置正确, 这两个脚本都可以直接在命令行中运行. 它们除了在Windows中是 428 | 批处理文件, 其它系统都是使用的Python脚本实现. 429 | 430 | 老的Robot Framework版本不包含 ``robot`` 脚本, 同时 ``rebot`` 脚本也只在Python 431 | 解释器下安装. 对应于不同的解释器, 老版本中使用 ``pybot``, ``jybot`` 和 ``ipybot`` 432 | 执行测试, 使用 ``jyrebot`` 和 ``ipyrebot`` 处理测试输出. 这些脚本现在仍能工作, 433 | 不过将在未来的版本中废弃并删除. 434 | 435 | 436 | .. _executing installed robot module: 437 | 438 | 执行安装的 ``robot`` 模块 439 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 440 | 441 | 执行测试的另一种方式是使用Python的 `-m 命令行选项`__ 直接调用 ``robot`` 模块, 442 | 或者子模块 ``robot.run``. 这种方法在同时使用多Python版本时非常有用. 443 | 444 | .. sourcecode:: bash 445 | 446 | python -m robot tests.robot 447 | python3 -m robot.run tests.robot 448 | jython -m robot tests.robot 449 | /opt/jython/jython -m robot tests.robot 450 | 451 | 直接使用 ``python -m robot`` 是 Robot Framework 3.0 版本新增特性, 在老版本 452 | 中, 只支持 ``python -m robot.run``. 现在Python 2.6版本中仍然必须使用后者. 453 | 454 | 处理测试输出也是相同的办法, 只是模块是 ``robot.rebot``: 455 | 456 | .. sourcecode:: bash 457 | 458 | python -m robot.rebot output.xml 459 | 460 | __ https://docs.python.org/2/using/cmdline.html#cmdoption-m 461 | 462 | .. _executing installed robot directory: 463 | 464 | 执行安装的 ``robot`` 目录 465 | ^^^^^^^^^^^^^^^^^^^^^^^^^ 466 | 467 | 如果你知道Robot Framework安装到了哪里, 还可以直接运行 :file:`robot` 路径 468 | 或者其中的文件 :file:`run.py`, 执行方法是: 469 | 470 | .. sourcecode:: bash 471 | 472 | python path/to/robot/ tests.robot 473 | jython path/to/robot/run.py tests.robot 474 | 475 | 直接运行路径是 Robot Framework 3.0 版本新增特性, 在老版本中, 只支持运行 476 | :file:`robot/run.py` 文件. 477 | 478 | 理测试输出也是相同的办法, 只是文件变为 :file:`robot/rebot.py`: 479 | 480 | .. sourcecode:: bash 481 | 482 | python path/to/robot/rebot.py output.xml 483 | 484 | 这种方式在 `手动安装`_ 时特别有用. 485 | 486 | .. _PATH: `配置环境变量 PATH`_ 487 | .. _https代理: `配置 https_proxy`_ 488 | .. _运行脚本: `使用 robot 和 rebot 脚本`_ 489 | .. _输出结果处理: `使用 robot 和 rebot 脚本`_ -------------------------------------------------------------------------------- /CreatingTestData/ResourceAndVariableFiles.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. _resource and variable files: 5 | 6 | 资源文件和变量文件 7 | ================== 8 | 9 | 在 :ref:`test case files` 和 :ref:`test suite initialization files` 中的用户关键字和变量只能在创建它们的文件中使用. *资源文件* 提供了共享机制. 10 | 11 | 资源文件的结构和用例文件非常接近, 可以很容易地创建. 12 | 13 | *变量文件* 则提供的强大的创建和共享变量的功能. 可以创建非字符串类型的复杂变量, 以及动态地创建过程. 因为变量文件使用的是Python代码, 所以非常灵活. 当然, 相对于 :ref:`variable tables` 来说, 这也稍稍带来了一定的复杂度. 14 | 15 | .. contents:: 16 | :depth: 2 17 | :local: 18 | 19 | .. _resource file: 20 | .. _resource files: 21 | 22 | 资源文件 23 | -------- 24 | 25 | .. _taking resource files into use: 26 | 27 | 使用资源文件 28 | ~~~~~~~~~~~~ 29 | 30 | 资源文件通过在设置表格中设定 :setting:`Resource` 来引入. 跟在设置名称后面的值就是资源文件所在的路径. 31 | 32 | 如果路径使用的是绝对路径格式, 则直接使用. 如果是相对路径的话, 首先在当前文件(即要引入资源文件的文件)所在路径下相对查找该路径. 如果没有找到, 则继续在Python的 :ref:`module search path` 下的目录中查找. 路径名称可以并且推荐使用变量, 以便做到路径和系统无关(例如 :file:`${RESOURCES}/login_resources.html` 或 :file:`${RESOURCE_PATH}`). 此外, 这里统一使用正斜杠(``/``), 在Windows系统中会自动转换为反斜杠(``\``). 33 | 34 | .. sourcecode:: robotframework 35 | 36 | *** Settings *** 37 | Resource myresources.html 38 | Resource ../data/resources.html 39 | Resource ${RESOURCES}/common.tsv 40 | 41 | 定义在资源文件中的用户关键字和变量在导入后即可使用. 同时, 该资源文件中从其它文件(测试库/资源文件/变量文件)导入的关键字和变量的关键字, 也变得可用. 42 | 43 | .. The user keywords and variables defined in a resource file are 44 | .. available in the file that takes that resource file into 45 | .. use. Similarly available are also all keywords and variables from the 46 | .. libraries, resource files and variable files imported by the said 47 | .. resource file. 48 | 49 | .. _resource file structure: 50 | 51 | 资源文件的结构 52 | ~~~~~~~~~~~~~~ 53 | 54 | 资源文件的整体结构和测试用例文件一样, 只不过其中不能包含测试用例. 此外, 资源文件中的设置表格只能包含导入相关的设置(:setting:`Library`, :setting:`Resource`, :setting:`Variables`)和文档设置(:setting:`Documentation`). 变量表格和关键字表格则和用例文件中完全一样. 55 | 56 | 如果多个资源文件中包含了重名的用户关键字, 必须使用 :ref:`资源文件名作为前缀 <handling keywords with same names>` 来区分. 例如,:name:`myresources.Some Keyword` and :name:`common.Some Keyword`. 并且, 如果多个资源文件包含了同名的变量, 则最终生效的是 *最先* 导入的那个. 57 | 58 | 59 | .. _Documenting resource files: 60 | 61 | 资源文件的文档 62 | ~~~~~~~~~~~~~~ 63 | 64 | 资源文件中创建的关键字可以使用 :setting:`[Documentation]` 来设置 :ref:`文档 <user keyword name and documentation>`. 和 :ref:`测试套件 <test suite name and documentation>` 类似, 资源文件本身在设置表格中也可以通过 :setting:`Documentation` 设置文档. 65 | 66 | :ref:`Libdoc` 和 :ref:`RIDE` 都会用到这些文档, 并且这些文档内容很自然的对打开资源文件的人来说也是可见的. 67 | 68 | 当关键字运行时, 关键字文档的第一行将写入日志, 而资源文件的文档在测试执行过程中会被忽略. 69 | 70 | .. _Example resource file: 71 | 72 | 资源文件示例 73 | ~~~~~~~~~~~~ 74 | 75 | .. sourcecode:: robotframework 76 | 77 | *** Settings *** 78 | Documentation An example resource file 79 | Library Selenium2Library 80 | Resource ${RESOURCES}/common.robot 81 | 82 | *** Variables *** 83 | ${HOST} localhost:7272 84 | ${LOGIN URL} http://${HOST}/ 85 | ${WELCOME URL} http://${HOST}/welcome.html 86 | ${BROWSER} Firefox 87 | 88 | *** Keywords *** 89 | Open Login Page 90 | [Documentation] Opens browser to login page 91 | Open Browser ${LOGIN URL} ${BROWSER} 92 | Title Should Be Login Page 93 | 94 | Input Name 95 | [Arguments] ${name} 96 | Input Text username_field ${name} 97 | 98 | Input Password 99 | [Arguments] ${password} 100 | Input Text password_field ${password} 101 | 102 | 103 | .. _variable file: 104 | .. _variable files: 105 | 106 | 变量文件 107 | -------- 108 | 109 | 顾名思义, 变量文件中包含了测试数据中的 :ref:`variables`. 虽然变量可以通过变量表格中创建, 或者通过命令行设置, 不过这些方法有所局限, 而变量文件可以动态地创建任意类型的变量. 110 | 111 | 变量文件一般就是由Python模块实现, 有两种不同的方法来创建变量: 112 | 113 | `直接创建变量`_ 114 | 变量就是模块的属性. 最简单的情形下, 这种语法几乎不需要真正的编程. 例如, ``MY_VAR = 'my value'`` 就创建了变量 ``${MY_VAR}``, 后面是变量的值. 115 | 116 | `通过特殊函数获取变量`_ 117 | 变量文件中可以包含一个特殊的函数 ``get_variables`` (或者 ``getVariables``), 该函数 将变量按字典的形式返回. 该函数还可以接受参数, 所以这种方法非常灵活. 118 | 119 | 120 | 此外变量文件还可以由 `Python或Java类 <Implementing variable file as Python or Java class>` 来实现. 具体的方法类似. 121 | 122 | 123 | .. _taking variable files into use: 124 | 125 | 使用变量文件 126 | ~~~~~~~~~~~~ 127 | 128 | .. _Setting table: 129 | 130 | 通过Setting 131 | ''''''''''' 132 | 133 | 所有的测试数据文件都可以在设置表中通过 :setting:`Variables` 来导入变量, 如同使用 :setting:`Resource` 来 :ref:`导入资源文件 <taking resource files into use>` 一样. 和资源文件的查找顺序类似, 待导入的变量文件路径最开始在相对于当前要导入变量的文件所在路径上寻找, 如果找不到, 则继续在 :ref:`模块搜索路径` 上搜寻. 路径名称可以使用变量, 并且在Windows中也可以使用正斜杠. 134 | 135 | 如果 :ref:`变量文件可以接受参数 <getting variables from a special function>`, 这些参数跟在路径后面的单元格中, 并且这些参数同样可以使用变量. 136 | 137 | .. sourcecode:: robotframework 138 | 139 | *** Settings *** 140 | Variables myvariables.py 141 | Variables ../data/variables.py 142 | Variables ${RESOURCES}/common.py 143 | Variables taking_arguments.py arg1 ${ARG2} 144 | 145 | 变量文件中定义的所有变量在导入它的测试文件中都是可见的. 如果同时导入了多个变量文件并且存在名称冲突, 则最先导入的生效. 此外, 通过变量表格和命令行方式设置的变量会覆盖变量文件中的同名变量. 146 | 147 | 148 | 通过命令行 149 | '''''''''''' 150 | 151 | 还可以通过命令行选项 :option:`--variablefile` 来指定变量文件. 选项后面跟着文件的路径, 如果要传递参数的话, 使用冒号 (``:``) 来分隔:: 152 | 153 | --variablefile myvariables.py 154 | --variablefile path/variables.py 155 | --variablefile /absolute/path/common.py 156 | --variablefile taking_arguments.py:arg1:arg2 157 | 158 | 从Robot Framework 2.8.2版本开始, 通过命令行设置的变量文件同样支持在 :ref:`模块搜索路径` 上搜寻. 159 | 160 | 如果文件路径使用了Windows的绝对路径格式, 驱动器号后面的冒号不会被视作分隔符:: 161 | 162 | --variablefile C:\path\variables.py 163 | 164 | 从Robot Framework 2.8.7版本开始, 还可以使用分号(``;``)作为参数的分隔符. 这种情况对参数本身也包含冒号时特别有用. 不过需要注意, 在UNIX-like操作系统中, 要使用双引号将整个选项值括起来:: 165 | 166 | --variablefile "myvariables.py;argument:with:colons" 167 | --variablefile C:\path\variables.py;D:\data.xls 168 | 169 | 这些变量文件中的变量在所有测试文件中全局可见, 这点和通过选项 :option:`--variable` 来设置 :ref:`单个变量 <Setting variables in command line>` 类似. 170 | 171 | 如果同时使用了 :option:`--variablefile` 和 :option:`--variable` 选项, 并且发生变量名冲突, 则使用 :option:`--variable` 选项设置的变量胜出. 172 | 173 | 174 | .. _creating variables directly: 175 | 176 | 直接创建变量 177 | ~~~~~~~~~~~~ 178 | 179 | .. Basic syntax 180 | 181 | 基础语法 182 | '''''''' 183 | 184 | 当使用变量文件时, 它们像Python的模块一样被导入, 其中的非下划线(``_``)开头的全局属性均被视作变量. 因为变量的名字是不区分大小写的, 所以不管小写还是大写字母都是可以的, 通常推荐大写字母用作全局变量和属性. 185 | 186 | .. sourcecode:: python 187 | 188 | VARIABLE = "An example string" 189 | ANOTHER_VARIABLE = "This is pretty easy!" 190 | INTEGER = 42 191 | STRINGS = ["one", "two", "kolme", "four"] 192 | NUMBERS = [1, INTEGER, 3.14] 193 | MAPPING = {"one": 1, "two": 2, "three": 3} 194 | 195 | 在上面的例子中, 创建了 ``${VARIABLE}``, ``${ANOTHER VARIABLE}`` 等变量. 前面2个是字符串, 第3个是整数, 接下来是两个列表, 最后一个是字典. 这些变量都可以用作 :ref:`scalar variable`, 列表和字典还可以当作 :ref:`list variable` 如 ``@{STRINGS}`` (注字典当列表变量使用时只包含字典的键), 而字典显然可以被当作 :ref:`dictionary variable` 如 ``&{MAPPING}``. 196 | 197 | 如果想让列表和字典类型的变量显得更明确, 可以分别使用前缀 ``LIST__`` 和 ``DICT__``来区分(注意后面是两个下划线): 198 | 199 | .. sourcecode:: python 200 | 201 | from collections import OrderedDict 202 | 203 | LIST__ANIMALS = ["cat", "dog"] 204 | DICT__FINNISH = OrderedDict([("cat", "kissa"), ("dog", "koira")]) 205 | 206 | 这些前缀最终不会被视作变量名称的一部分, 只是会让Robot Framework校验变量的值和类型是否符合. 对字典来说, 变量值还将转换为特殊的字典类型, 就像 :ref:`creating dictionary variables` 中使用的一样. 这样这些字典之中的值就可以像访问属性一样获取, 如 ``${FINNISH.cat}``. 同时这些字典还是排序的, 不过如果想保持和原来的顺序一样则要求初始的字典是排序的. 207 | 208 | 上面例子中的变量同样可以使用下面的方式在变量表中创建. 209 | 210 | .. sourcecode:: robotframework 211 | 212 | *** Variables *** 213 | ${VARIABLE} An example string 214 | ${ANOTHER VARIABLE} This is pretty easy! 215 | ${INTEGER} ${42} 216 | @{STRINGS} one two kolme four 217 | @{NUMBERS} ${1} ${INTEGER} ${3.14} 218 | &{MAPPING} one=${1} two=${2} three=${3} 219 | @{ANIMALS} cat dog 220 | &{FINNISH} cat=kissa dog=koira 221 | 222 | .. note:: 变量文件中的字符串中的变量格式是不会当变量替换的. 例如, 223 | ``VAR = "an ${example}"`` 将创建变量 ``${VAR}``, 其值为 ``an ${example}``. 224 | 是否存在变量 ``${example}`` 都不会影响. 225 | 226 | 227 | .. _Using objects as values: 228 | 229 | 使用对象 230 | '''''''' 231 | 232 | 变量文件中变量定义突破了变量表格中只能定义字符串和基础类型的限制, 现在变量可以包含任意类型的对象. 在下面的例子中, 变量 ``${MAPPING}`` 包含了一个Java哈希表, 其中包含两个值(该例子只适用于Jython上运行). 233 | 234 | .. sourcecode:: python 235 | 236 | from java.util import Hashtable 237 | 238 | MAPPING = Hashtable() 239 | MAPPING.put("one", 1) 240 | MAPPING.put("two", 2) 241 | 242 | 第二个例子创建了Python的字典 ``${MAPPING}``, 同样包含两个值, 且这两个值是该文件中自定义类的实例. 243 | 244 | .. sourcecode:: python 245 | 246 | MAPPING = {'one': 1, 'two': 2} 247 | 248 | class MyObject: 249 | def __init__(self, name): 250 | self.name = name 251 | 252 | OBJ1 = MyObject('John') 253 | OBJ2 = MyObject('Jane') 254 | 255 | .. _Creating variables dynamically: 256 | 257 | 动态创建变量 258 | '''''''''''' 259 | 260 | 因为变量文件就是真正的编程语言, 其中几乎可以包含任意的代码逻辑来设置变量. 261 | 262 | .. sourcecode:: python 263 | 264 | import os 265 | import random 266 | import time 267 | 268 | USER = os.getlogin() # current login name 269 | RANDOM_INT = random.randint(0, 10) # random integer in range [0,10] 270 | CURRENT_TIME = time.asctime() # timestamp like 'Thu Apr 6 12:45:21 2006' 271 | if time.localtime()[3] > 12: 272 | AFTERNOON = True 273 | else: 274 | AFTERNOON = False 275 | 276 | 上面的例子中使用了Python标准库来设置不同的变量, 你也可以使用自己的代码来构造这些值. 277 | 278 | 下面的例子展示了类似的概念, 真实的代码中的数据可以是来自数据库, 或者外部文件, 甚至是要求用户输入. 279 | 280 | .. sourcecode:: python 281 | 282 | import math 283 | 284 | def get_area(diameter): 285 | radius = diameter / 2 286 | area = math.pi * radius * radius 287 | return area 288 | 289 | AREA1 = get_area(1) 290 | AREA2 = get_area(2) 291 | 292 | .. _Selecting which variables to include: 293 | 294 | 选择性的包含变量 295 | '''''''''''''''' 296 | 297 | 当 Robot Framework 处理变量文件时, 这些文件(模块)中所有的属性只要不是以下划线开头, 都会被视作变量, 这其中甚至包括函数或类, 不管是在文件中创建的还是从其它模块导入的. 例如, 上面最后一个例子中除了 ``${AREA1}`` 和 ``${AREA2}`` 这两个我们预期的变量外, 最终还包含了 ``${math}`` 和 ``${get_area}`` 这两个变量. 298 | 299 | 虽然通常情况下这些额外的变量不会造成什么问题, 但是它们有可能会无意覆盖其它的变量名, 由此引发的错误将难以定位. 一个可行的解决办法是通过加下划线作为前缀来忽略这些属性: 300 | 301 | .. sourcecode:: python 302 | 303 | import math as _math 304 | 305 | def _get_area(diameter): 306 | radius = diameter / 2.0 307 | area = _math.pi * radius * radius 308 | return area 309 | 310 | AREA1 = _get_area(1) 311 | AREA2 = _get_area(2) 312 | 313 | 但是如果属性的数量非常多, 这样做就很不方便(同时, 这种做法也不符合Python的编码风格). 推荐的做法是使用特殊属性 ``__all__``, 将要作为变量暴露的属性名放在列表中赋值给它. 314 | 315 | .. sourcecode:: python 316 | 317 | import math 318 | 319 | __all__ = ['AREA1', 'AREA2'] 320 | 321 | def get_area(diameter): 322 | radius = diameter / 2.0 323 | area = math.pi * radius * radius 324 | return area 325 | 326 | AREA1 = get_area(1) 327 | AREA2 = get_area(2) 328 | 329 | .. note:: ``__all__`` 属性在Python中最初就是用来设置哪些属性可以在 330 | ``from modulename import *`` 的语法中被导入. 331 | 332 | 333 | .. _getting variables from a special function: 334 | 335 | 通过特殊函数获取变量 336 | ~~~~~~~~~~~~~~~~~~~~~ 337 | 338 | 在变量文件中获取变量的另一种方法是通过特殊的函数 ``get_variables``(或 ``getVariables``). 如果这个函数存在, Robot Framework将调用该函数, 并且预期返回的结果是Python的字典类型或者Java中的 ``Map`` 类型, 其中变量的名称是键, 而值就是变量的值. 339 | 340 | 创建的变量可以用作标量, 列表和字典, 就和 :ref:`creating variables directly` 完全一样, 同样可以使用前缀 ``LIST__`` 和 ``DICT__`` 来明确表示创建的是列表和字典. 341 | 342 | 下面的例子和 :ref:`creating variables directly` 中的第一个例子在功能上完全相同. 343 | 344 | .. sourcecode:: python 345 | 346 | def get_variables(): 347 | variables = {"VARIABLE ": "An example string", 348 | "ANOTHER VARIABLE": "This is pretty easy!", 349 | "INTEGER": 42, 350 | "STRINGS": ["one", "two", "kolme", "four"], 351 | "NUMBERS": [1, 42, 3.14], 352 | "MAPPING": {"one": 1, "two": 2, "three": 3}} 353 | return variables 354 | 355 | ``get_variables`` 可以接受参数, 这样可以很方便的改变实际要创建什么样的变量. 参数的数量和类型和普通的Python函数并无二致. 当在测试数据中 :ref:`taking variable files into use` 时, 调用参数跟在变量文件后面的表格里, 而在命令行中则通过冒号或分号和文件路径分开. 356 | 357 | 358 | 下面这个傻傻的例子展示了变量文件如何使用参数. 在更真实的场景中, 这些参数可能是一个用来读取参数的外部文件的路径, 或者是数据库的地址. 359 | 360 | .. sourcecode:: python 361 | 362 | variables1 = {'scalar': 'Scalar variable', 363 | 'LIST__list': ['List','variable']} 364 | variables2 = {'scalar' : 'Some other value', 365 | 'LIST__list': ['Some','other','value'], 366 | 'extra': 'variables1 does not have this at all'} 367 | 368 | def get_variables(arg): 369 | if arg == 'one': 370 | return variables1 371 | else: 372 | return variables2 373 | 374 | .. _Implementing variable file as Python or Java class: 375 | 376 | 用类实现变量文件 377 | ~~~~~~~~~~~~~~~~~ 378 | 379 | 从Robot Framework 2.7版本开始, 还可以使用Python或Java之中的类来实现变量文件. 380 | 381 | .. Implementation 382 | 383 | 具体实现 384 | '''''''' 385 | 386 | 因为变量导入时使用的文件路径, 所有使用类实现的时候有一些限制: 387 | 388 | - Python的类名必须和所在的模块名相同. 389 | - Java类必须在默认包中. 390 | - 指向Java类的路径必须以 :file:`.java` 或 :file:`.class` 结尾, class文件必须存在. 391 | 392 | 不管以何种语言实现, 框架都将不带参数的构造一个实例, 通过该实例获取变量. 和使用模块类似, 变量可以直接定义为实例的属性, 也可以使用特殊的 ``get_variables``(或 ``getVariables``) 方法. 393 | 394 | 当直接定义变量时, 会忽略所有可调用的(callable)的属性以避免调用实例的方法. 如果需要可调用的变量, 需要使用其它的方法来创建变量文件. 395 | 396 | 397 | 示例 398 | '''' 399 | 400 | 第一个例子通过属性直接创建变量, 同时以Python和Java两种语言实现. 两个例子的效果相同, 都通过类的属性创建了变量 ``${VARIABLE}`` and ``@{LIST}``, 并通过实例的属性创建变量 ``${ANOTHER VARIABLE}``. 401 | 402 | .. sourcecode:: python 403 | 404 | class StaticPythonExample(object): 405 | variable = 'value' 406 | LIST__list = [1, 2, 3] 407 | _not_variable = 'starts with an underscore' 408 | 409 | def __init__(self): 410 | self.another_variable = 'another value' 411 | 412 | .. sourcecode:: java 413 | 414 | public class StaticJavaExample { 415 | public static String variable = "value"; 416 | public static String[] LIST__list = {1, 2, 3}; 417 | private String notVariable = "is private"; 418 | public String anotherVariable; 419 | 420 | public StaticJavaExample() { 421 | anotherVariable = "another value"; 422 | } 423 | } 424 | 425 | 第二个例子通过动态的方法来获取变量. 同样, 两种语言的效果一样, 都创建了唯一的变量 ``${DYNAMIC VARIABLE}``. 426 | 427 | .. sourcecode:: python 428 | 429 | class DynamicPythonExample(object): 430 | 431 | def get_variables(self, *args): 432 | return {'dynamic variable': ' '.join(args)} 433 | 434 | .. sourcecode:: java 435 | 436 | import java.util.Map; 437 | import java.util.HashMap; 438 | 439 | public class DynamicJavaExample { 440 | 441 | public Map<String, String> getVariables(String arg1, String arg2) { 442 | HashMap<String, String> variables = new HashMap<String, String>(); 443 | variables.put("dynamic variable", arg1 + " " + arg2); 444 | return variables; 445 | } 446 | } 447 | 448 | .. _Variable file as YAML: 449 | 450 | YAML格式的变量文件 451 | ~~~~~~~~~~~~~~~~~~~~~ 452 | 453 | 变量文件还可以使用 :ref:`YAML <http://yaml.org>` 文件. YAML是一种数据序列化的标记语言, 拥有简单的语法和友好的可读性. 下面的例子展示了一个简单的YAML文件: 454 | 455 | .. sourcecode:: yaml 456 | 457 | string: Hello, world! 458 | integer: 42 459 | list: 460 | - one 461 | - two 462 | dict: 463 | one: yksi 464 | two: kaksi 465 | with spaces: kolme 466 | 467 | .. note:: 在Robot Framework中使用YAML文件要求安装 :ref:`PyYAML 468 | <http://pyyaml.org>` 模块. 如果已经有了 pip_, 则使用下面的命令即可安装 469 | ``pip install pyyaml``. 470 | 471 | Robot Framework从2.9版本开始支持YAML. 从2.9.2版本开始, :ref:`standalone JAR distribution` 已经默认包含了PyYAML. 472 | 473 | YAML 变量文件的使用和其它变量文件完全一样, 既可以使用命令行选项 :option:`--variablefile`, 也可以使用配置 :setting:`Variables`, 或者使用关键字 :name:`Import Variables` 动态导入. 唯一需要记住的是, 导入YAML文件的路径名必须以 :file:`.yaml` 扩展名结尾. 474 | 475 | 上例中的YAML文件创建的变量和下面的变量表格创建的变量完全一样. 476 | 477 | .. sourcecode:: robotframework 478 | 479 | *** Variables *** 480 | ${STRING} Hello, world! 481 | ${INTEGER} ${42} 482 | @{LIST} one two 483 | &{DICT} one=yksi two=kaksi 484 | 485 | 使用YAML文件作为变量文件必须总是使用顶层的映射(mappings). 如上例所示, 映射中的键和值分别是变量的名称和值. 变量的值可以是YAML语法支持的任意数据类型. 如果名称或值中包含了non-ASCII的字符, 则YAML文件必须使用UTF-8编码格式. 486 | 487 | 如果值是mapping类型, 则最终将转换为特殊的字典, 这一点等同于在变量表格中 :ref:`creating dictionary variables`. 这样就可以使用 ``${DICT.one}`` 这样的属性访问方法来获取到字典的值. 当然, 这里要求键的名字必须是合法的Python属性名称, 如果其中包含了空格或者其他非法的名称, 则还是可以使用 ``&{DICT}[with spaces]`` 语法来获取字典的值. 这个生成的字典也是有序的, 不过遗憾的是, 原始的YAML文件中的顺序没法保留下来. 488 | -------------------------------------------------------------------------------- /ExecutingTestCases/ConfiguringExecution.rst: -------------------------------------------------------------------------------- 1 | .. _configuring execution: 2 | 3 | 测试执行的配置项 4 | ================= 5 | 6 | 本章将介绍用于配置 :ref:`测试执行 <test execution>` 或 :ref:`测试输出的处理 <post-processing outputs>` 的各种命令行选项. 与生成output文件相关的选项将在 :ref:`下一章 <created outputs>` 讨论. 7 | 8 | 9 | .. contents:: 10 | :depth: 2 11 | :local: 12 | 13 | .. _selecting test cases: 14 | 15 | 选择测试用例 16 | ------------- 17 | 18 | Robot Framework提供了若干命令行选项用于选择测试用例来执行. 这些选项同样可以在使用 Rebot_ 处理测试输出时使用. 19 | 20 | .. _by test suite and test case names: 21 | 22 | 根据套件和用例名称 23 | ~~~~~~~~~~~~~~~~~~ 24 | 25 | 测试套件和测试用例可以按照它们的名字来选择, 分别用到的选项是 :option:`--suite (-s)` 和 :option:`--test (-t)`. 这些选项都可以多次指定, 用来选择多个套件或用例. 选项的参数是大小写无关并且忽略空格, 同时, 还可以使用 :ref:`简单模式` 来匹配多个名字. 26 | 27 | 如果同时使用了选项 :option:`--suite` 和 :option:`--test`, 则只有匹配套件内的匹配用例才会被选中. 28 | 29 | :: 30 | 31 | --test Example 32 | --test mytest --test yourtest 33 | --test example* 34 | --test mysuite.mytest 35 | --test *.suite.mytest 36 | --suite example-?? 37 | --suite mysuite --test mytest --test your* 38 | 39 | 使用选项 :option:`--suite` 和执行相应的测试用例文件或目录差不多是一样的. 40 | 通过选项指定套件的一个最大的好处是可以基于父套件来选择套件. 使用时将父子套件名称之间用点(``.``)来连接. 这种情况, 如果父套件有setup和teardown, 则会执行. 41 | 42 | :: 43 | 44 | --suite parent.child 45 | --suite myhouse.myhousemusic --test jack* 46 | 47 | 通过 :option:`--test` 选项来选择单个的测试用例执行在创建测试用例时很实用, 但是在自动化执行时作用有限. 通常情况下, 通过标签来选择用例更加灵活. 48 | 49 | .. _by tag names: 50 | 51 | 根据标签 52 | ~~~~~~~~~ 53 | 54 | 分别使用 :option:`--include (-i)` 和 :option:`--exclude (-e)` 选项可以指定要包含和排除的 :ref:`标签 <tag>` 名字. 55 | 使用 :option:`--include`, 只有那些标签匹配上的测试用例才会选中, 而使用 :option:`--exclude` 则相反. 如果两个选项同时出现, 只有那些两者同时满足的用例会被选中. 56 | 57 | :: 58 | 59 | --include example 60 | --exclude not_ready 61 | --include regression --exclude long_lasting 62 | 63 | :option:`--include` 和 :option:`--exclude` 都可以指定多次. 这种情况下, 被选中的用例是: 有任意一个标签匹配上任意的包含的标签, 同时, 没有任何标签匹配上排除标签. 64 | 65 | 66 | 除了指定完全匹配某个标签, 还可以使用 :ref:`标签模式 <tag patterns>`, 即使用 ``*`` 和 ``?`` 这些通配符, 以及 ``AND``, ``OR``, 和 ``NOT`` 这些逻辑操作符来组合标签:: 67 | 68 | --include feature-4? 69 | --exclude bug* 70 | --include fooANDbar 71 | --exclude xxORyyORzz 72 | --include fooNOTbar 73 | 74 | 通过标签来选择用例是非常灵活的机制, 由此可以实现很多有趣的功能: 75 | 76 | - 一部分测试子集要在其它测试执行前先执行, 这个子集通常也称作冒烟测试, 可以被打上标签 77 | ``smoke``, 然后通过 ``--include smoke`` 执行. 78 | 79 | - 还未完成的测试用例, 可以在提交到版本控制系统的时候打上标签 ``not_ready``, 执行时指定 80 | ``--exclude not_ready`` 以避免执行到. 81 | 82 | - 敏捷开发中, 测试用例可以打上 ``sprint-<num>`` 标签, 其中 ``<num>`` 表示某次迭代, 83 | 当所有用例执行完成, 可以针对这轮特定的迭代生成单独的报告 84 | (例如: ``rebot --include sprint-42 output.xml``). 85 | 86 | .. _Re-executing failed test cases: 87 | 88 | 重新执行失败的用例 89 | ~~~~~~~~~~~~~~~~~~ 90 | 91 | 命令行选项 :option:`--rerunfailed (-R)` 可被用来从上次执行的 :ref:`output file` 中抽取所有失败的用例重新执行. 该选项是非常有用的, 例如, 把所有用例全部执行一遍很耗时间, 这样就可以迭代地修复和执行那些失败的用例. 92 | 93 | :: 94 | 95 | robot tests # first execute all tests 96 | robot --rerunfailed output.xml tests # then re-execute failing 97 | 98 | 该选项在幕后的工作就是把失败的用例挑选出来, 就和使用 :option:`--test` 一样. 同时它还可以和其它选择用例的选项 :option:`--test`, :option:`--suite`, :option:`--include` 和 :option:`--exclude` 结合使用以达到微调的效果. 99 | 100 | 如果选项指定的output文件并不是出自当前要执行的测试的话, 将会导致不可预测的结果. 此外, 如果output中没有失败的用例, 则会报错. 使用特殊的 ``NONE`` 作为output文件值的话, 其效果等同于不指定该选项. 101 | 102 | .. tip:: 重新执行的结果和初始的结果可以通过命令行选项 :option:`--merge` :ref:`合并 <merging outputs>` 103 | 104 | .. note:: 重新执行失败的用例是Robot Framework 2.8版本的新特性功能. 105 | 在Robot Framework 2.8.4版本之前的选项名是 :option:`--runfailed`. 106 | 旧的名字仍在用, 但是将在以后去除掉. 107 | 108 | .. _When no tests match selection: 109 | 110 | 当没有用例匹配选择的情况 111 | ~~~~~~~~~~~~~~~~~~~~~~~~ 112 | 113 | 默认情况下, 如果没有任何用例匹配选择标准, 测试执行将以失败告终, 报错如:: 114 | 115 | [ ERROR ] Suite 'Example' with includes 'xxx' contains no test cases. 116 | 117 | 因为没有输出文件生成, 所以此种行为在自动化执行和处理测试的时候将会是个麻烦. 幸好有另一个命令行选项 :option:`--RunEmptySuite` 可被用来强制要求测试套件在这种情况下也正常执行. 118 | 119 | 该选项也可用在执行空目录或者空的测试用例文件, 效果都是一样. 120 | 121 | 相似的情形在使用 Rebot_ 处理输出文件时也存在, 例如没有任何用例匹配到过滤规则, 或者output文件中就没有任何用例. 默认在此种情况下, Rebot的执行也会报错. 选项 :option:`--ProcessEmptySuite` 可用来改变这个行为. 该选项和在测试运行时使用的 :option:`--RunEmptySuite` 作用一样. 122 | 123 | .. note:: :option:`--ProcessEmptySuite` 是 Robot Framework 2.7.2版本新加功能. 124 | 125 | .. _Setting criticality: 126 | 127 | 设置关键性 128 | ---------- 129 | 130 | 测试执行的最终结果取决于关键(critical)用例的结果. 如果任意一个关键用例失败, 则整个测试被认为失败. 反之, 非关键(non-critical)测试用例的失败不会影响整个测试的状态. 131 | 132 | 所有的测试用例默认都是关键的, 不过可以通过选项 :option:`--critical (-c)` 和 :option:`--noncritical (-n)` 来设置. 这些选项基于标签来指定哪些用例是关键的, 类似于 :option:`--include` 和 :option:`--exclude` :ref:`通过标签选择用例 <by tag names>`. 133 | 134 | 如果只使用 :option:`--critical`, 标签匹配上的用例是关键的. 如果单使用 :option:`--noncritical`, 则标签没有匹配上的用例是关键的. 最后, 如果两个都设置了, 则只有那些既匹配了critical标签, 又没有匹配non-critical标签的用例被视作关键的. 135 | 136 | 这两个选项和 :option:`--include` 和 :option:`--exclude` 一样也支持 :ref:`标签模式` 的用法. 即大小写无关, 空格和下划线无关, 支持 ``*`` 和 ``?`` 通配符, ``AND``, ``OR`` 和 ``NOT`` 运算符的模式匹配规则. 137 | 138 | :: 139 | 140 | --critical regression 141 | --noncritical not_ready 142 | --critical iter-* --critical req-* --noncritical req-6?? 143 | 144 | 设置关键性的最常用处是在测试用例未完全就绪时, 或者测试执行时测试特性仍在开发中. 当然, 你可以使用 :option:`--exclude` 选项将这些用例在执行时排除在外, 但是将它们作为非关键的用例进行执行可以让你看到它们何时转为pass. 145 | 146 | 测试执行时设置的关键性没有在任何地方保存. 如果要在Rebot :ref:`post-processing outputs` 时也保持相同的关键性, 需要同时也使用相同的 :option:`--critical` 和/或 :option:`--noncritical` 选项:: 147 | 148 | # Use rebot to create new log and report from the output created during execution 149 | robot --critical regression --outputdir all tests.robot 150 | rebot --name Smoke --include smoke --critical regression --outputdir smoke all/output.xml 151 | 152 | # No need to use --critical/--noncritical when no log or report is created 153 | robot --log NONE --report NONE tests.robot 154 | rebot --critical feature1 output.xml 155 | 156 | 157 | .. _Setting metadata: 158 | 159 | 设置元数据 160 | ---------- 161 | 162 | .. _Setting the name: 163 | 164 | 设置名字 165 | ~~~~~~~~ 166 | 167 | Robot Framework 解析测试数据时, :ref:`测试套件的名字 <test suite name and documentation>` 是根据用例文件和目录创建而来的. 而顶层的测试套件名字可以通过命令行选项 :option:`--name (-N)` 指定. 给定名字中的下划线将自动转为空格, 并且其中的单词将转为首字母大写. 168 | 169 | 170 | .. _Setting the documentation: 171 | 172 | 设置文档 173 | ~~~~~~~~~~ 174 | 175 | 除了可以在测试数据中 :ref:`定义文档 <test suite name and documentation>`, 顶层测试套件的文档还可以通过命令行选项 :option:`--doc (-D)` 给出. 文档中的下划线将转为空格, 并且文档中可以包含简单的 :ref:`HTML formatting`. 176 | 177 | 178 | .. _setting free metadata: 179 | 180 | 设置自由元数据 181 | ~~~~~~~~~~~~~~ 182 | 183 | :ref:`Free test suite metadata` 可以通过命令行选项 :option:`--metadata (-M)` 给出. 该选项的参数格式是 ``name:value``, 其中 ``name`` 是要设置的元数据的名字, ``value`` 是值. 184 | 名字和值中包含的下划线会被转为空格, 并且值可以包含简单的 :ref:`HTML formatting`. 185 | 186 | 该选项可以出现多次以设置多个元数据 187 | 188 | .. _Setting tags: 189 | 190 | 设置标签 191 | ~~~~~~~~~~~~ 192 | 193 | 命令行选项 :option:`--settag (-G)` 可用来为所有测试用例设置给定的标签. 该选项也可以使用多次以设置多个标签. 194 | 195 | .. _module search path: 196 | .. _Configuring where to search libraries and other extensions: 197 | 198 | 模块搜索路径 199 | ------------- 200 | 201 | 当Robot Framework导入 :ref:`test library <specifying library to import>`, :ref:`listener <setting listeners>`, 或其它基于Python的扩展的时候, 它要用Python解释器从系统中导入包含扩展内容的模块(module). 202 | 其中查找模块的一系列的位置被称之为 *模块搜索路径*, 本节将介绍几种不同的方法来配置. 当导入基于Java的库或Jython的扩展时, 除了正常的模块搜索路径, 还要加上Java的类路径(classpash). 203 | 204 | Robot Framework在导入 :ref:`资源和变量文件` 时, 如果指定的路径不能直接匹配到文件路径, 则也会用到Python的模块搜索路径. 205 | 206 | 模块搜索路径的设置正确, 测试库和扩展才能被找到, 这是测试执行成功的必要条件. 如果你想要通过下面的方法自定义模块搜索路径, 则创建一个自定义的 :ref:`start-up script` 是个不错的选择. 207 | 208 | 209 | .. _Locations automatically in module search path: 210 | 211 | 自动包含在模块搜索路径中的位置 212 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 213 | 214 | Python解释器的标准库和安装的第三方库最终都是在模块搜索路径内. 也就是说, 使用 :ref:`Python打包系统打包 <packaging libraries>` 的测试库是自动安装到模块搜索路径内的, 可以直接导入. 215 | 216 | 217 | 218 | ``PYTHONPATH``, ``JYTHONPATH`` and ``IRONPYTHONPATH`` 219 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 220 | 221 | Python, Jython和IronPython分别从环境变量 ``PYTHONPATH``, ``JYTHONPATH`` 和 222 | ``IRONPYTHONPATH`` 中读取需要加入到模块搜索路径中的位置. 223 | 无论用到哪个环境变量, 如果你想要指定多个位置, 需要在类UNIX系统中使用冒号分隔(``/opt/libs:$HOME/testlibs``), 而在Windows系统中使用分号分隔(``D:\libs;%HOMEPATH%\testlibs``). 224 | 225 | 环境变量可以在系统级别设置为永久生效, 也可以针对某个用户有效. 同时还可以使用命令来临时设置, 这点可以在 :ref:`start-up scripts` 得到非常好的应用. 226 | 227 | .. note:: 在Robot Framework 2.9之前, 当使用Jython和IronPython运行时, 228 | ``PYTHONPATH`` 环境变量中的内容被框架自己加入到模块搜索路径中. 229 | 现在则不会了, 必须分别使用 ``JYTHONPATH`` 和 ``IRONPYTHONPATH``. 230 | 231 | 232 | .. _Using --pythonpath option: 233 | 234 | ``--pythonpath`` 选项 235 | ~~~~~~~~~~~~~~~~~~~~~ 236 | 237 | Robot Framework提供了一个单独的命令行选项 :option:`--pythonpath (-P)` 用来将位置加入到模块搜索路径. 虽然该选项名称中包含的是python, 它对Jython和IronPython也同样有用. 238 | 239 | 不管在何种操作系统下, 多个位置都使用冒号来分隔, 或者可以多次使用该选项. 240 | 给定的路径名称可以使用glob的模式匹配多个路径, 但是通配符必须要 :ref:`转义 <escaping complicated characters>`. 241 | 242 | 243 | 例如:: 244 | 245 | --pythonpath libs 246 | --pythonpath /opt/testlibs:mylibs.zip:yourlibs 247 | --pythonpath mylib.jar --pythonpath lib/STAR.jar --escape star:STAR 248 | 249 | 250 | 程序设置 ``sys.path`` 251 | ~~~~~~~~~~~~~~~~~~~~~~~ 252 | 253 | Python解释器把模块搜索路径以字符串列表的形式存储在 :ref:`sys.path <https://docs.python.org/2/library/sys.html#sys.path> <>`. 该属性可以在程序执行过程中动态地更新, 改动将在下次需要导入某个模块的时候起效. 254 | 255 | .. _Java classpath: 256 | 257 | Java的类路径 258 | ~~~~~~~~~~~~~~ 259 | 260 | 当用Jython导入Java实现的库时, 这些库的位置既可以是在Jython的模块搜索路径, 也可以是在 :ref:`Java classpath <https://docs.oracle.com/javase/8/docs/technotes/tools/findingclasses.html>`. 设置classpath的最常见方式是通过环境变量 ``CLASSPATH``, 具体和 ``PYTHONPATH``, ``JYTHONPATH`` 或 ``IRONPYTHONPATH`` 类似. 261 | 262 | 或者, 可以使用Java的选项 :option:`-cp`. 该选项不属于 ``robot`` :ref:`runner script`, 但是可以在使用Jython时通过选项前缀 :option:`-J` 来启用, 例如:: 263 | 264 | jython -J-cp example.jar -m robot.run tests.robot 265 | 266 | 当使用独立的JAR包时, classpath的设置有些许不同, 因为 `java -jar` 命令既不支持环境变量 ``CLASSPATH`` 也不支持 :option:`-cp` 选项. 有两种不同的方法来解决:: 267 | 268 | java -cp lib/testlibrary.jar:lib/app.jar:robotframework-2.9.jar org.robotframework.RobotFramework tests.robot 269 | java -Xbootclasspath/a:lib/testlibrary.jar:lib/app.jar -jar robotframework-2.9.jar tests.robot 270 | 271 | 272 | .. _Setting variables: 273 | 274 | 设置变量 275 | -------- 276 | 277 | :ref:`variables` 既可以使用 :option:`--variable (-v)` 选项 :ref:`个别 <setting variables in command line>` 设置, 也可以使用 :option:`--variablefile (-V)` 选项通过 :ref:`variable file` 批量设置. 关于变量和变量文件在其它章节介绍, 下面的例子展示了如何使用这些命令行选项:: 278 | 279 | --variable name:value 280 | --variable OS:Linux --variable IP:10.0.0.42 281 | --variablefile path/to/variables.py 282 | --variablefile myvars.py:possible:arguments:here 283 | --variable ENVIRONMENT:Windows --variablefile c:\resources\windows.py 284 | 285 | 286 | .. _Dry run: 287 | 288 | 空运行(Dry run) 289 | -------------- 290 | 291 | Robot Framework支持所谓的 *空运行* 模式, 这种模式下测试用例的运行和正常一样, 只是测试库中的关键字不执行. 该模式可以用于验证测试数据, 如果空运行通过, 则数据应该是语法正确的. 使用 :option:`--dryrun` 选项即可启用该模式. 292 | 293 | 空运行模式的执行可能会因为以下原因而失败: 294 | 295 | * Using keywords that are not found. 296 | * Using keywords with wrong number of arguments. 297 | * Using user keywords that have invalid syntax. 298 | 299 | 除了这些失败, 正常的 :ref:`执行错误 <errors and warnings during execution>` 也会有提示. 例如, 当测试库或资源文件无法导入时. 300 | 301 | .. note:: 空运行模式不校验变量. 这点限制可能会在未来版本中有所提升. 302 | 303 | 304 | .. _Randomizing execution order: 305 | 306 | 执行顺序随机化 307 | -------------- 308 | 309 | 测试执行的顺序可以通过选项 :option:`--randomize <what>[:<seed>]` 随机化, 这其中的 ``<what>`` 可能是以下几种: 310 | 311 | ``tests`` 312 | 每个测试套件内的用例按随机顺序执行 313 | 314 | ``suites`` 315 | 所有的测试套件按随机顺序执行, 但是套件内的测试用例还是按照它们定义的顺序执行. 316 | 317 | ``all`` 318 | 测试套件和测试用例都按照随机顺序执行. 319 | 320 | ``none`` 321 | 测试套件和测试用例都不会随机执行. 该值可被用来覆盖掉前面设置的 :option:`--randomize` 选项. 322 | 323 | 从Robot Framework 2.8.5版本开始, 还可以给定一个自定义的随机种子(seed)来初始化随机生成器. 该种子作为选项 :option:`--randomize` 的值给出, 格式为 `<what>:<seed>`, 必须是整数. 如果没有给定种子, 则随机生成. 324 | 325 | 被执行的顶层测试套件自动获得了名为 :name:`Randomized` 的 :ref:`元数据 <free test suite metadata>`, 可通过其知晓什么被随机化以及随机种子是多少. 326 | 327 | Examples:: 328 | 329 | robot --randomize tests my_test.robot 330 | robot --randomize all:12345 path/to/tests 331 | 332 | 333 | .. _pre-run modifier: 334 | .. _Programmatic modification of test data: 335 | 336 | 测试数据编程修改 337 | ---------------- 338 | 339 | 如果Robot Framework内置的在执行前修改测试数据的功能不够用, 从2.9版本开始, 可以通过编程的方法来自定义修改. 这可以通过创建一个模型修改器(model modifier)并使用选项 :option:`--prerunmodifier` 来激活使用它. 340 | 341 | 模型修改器被实现为观察者(visitor), 可以遍历可执行的测试套件结构, 并且按需修改. 观察者接口在 :ref:`Robot Framework API documentation <visitor interface_>` 中有所说明. 使用它可以修改 :ref:`test suites <running.TestSuite>`, :ref:`test cases <running.TestCase>` 和 :ref:`keywords <running.Keyword>`. 342 | 343 | 下面的例子展示了如何使用模型修改器, 以及该功能的强大之处. 344 | 345 | .. sourcecode:: python 346 | 347 | ../code_examples/select_every_xth_test.py 348 | 349 | 当在命令行中使用 :option:`--prerunmodifier` 选项来指定一个模型修改器时, 既可以使用修改器的类名, 也可以是修改器的源文件. 如果是类名, 则包含该类的模块必须在 :ref:`模块搜索路径 <module search path>`, 并且如果模块名和类名不同, 则名称还必须包含模块名, 如 ``module.ModifierClass``. 如果是文件路径, 则类名必须和文件名一样. 大部分情况和 :ref:`指定导入库 <specifying library to import>` 一样. 350 | 351 | 如果一个修改器需要参数, 如上例, 则参数值跟在修改器的名字或路径后面给出, 使用冒号(`:`)或分号(`;`)来分隔. 如果同时出现了冒号和分号, 则最先出现的那个符号被视为分隔符. 352 | 353 | 例如, 如果上述模型修改器在文件 :file:`SelectEveryXthTest.py` 中定义, 则可以这样用:: 354 | 355 | # 通过文件路径指定修改器. 每次隔1个来运行测试. 356 | robot --prerunmodifier path/to/SelectEveryXthTest.py:2 tests.robot 357 | 358 | # 通过名称指定修改器. 从第2个开始, 每次隔2个运行的测试用例. 359 | # SelectEveryXthTest.py 必须在模块搜索路径内. 360 | robot --prerunmodifier SelectEveryXthTest:3:1 tests.robot 361 | 362 | 如果需要使用多个模型修改器, 则可以通过多次使用 :option:`--prerunmodifier` 选项来指定. 如果类似的变更需要在创建测试结果前执行, 则可以使用 :option:`--prerebotmodifier` 选项来启用 :ref:`编程修改结果`. 363 | 364 | If more than one model modifier is needed, they can be specified by using 365 | the :option:`--prerunmodifier` option multiple times. If similar modifying 366 | is needed before creating results, `programmatic modification of results`_ 367 | can be enabled using the :option:`--prerebotmodifier` option. 368 | 369 | __ `Specifying library to import`_ 370 | 371 | .. _Controlling console output: 372 | 373 | 控制台输出 374 | ----------- 375 | 376 | 有多个命令行选项可用来设置测控制台的报告输出. 377 | 378 | .. _console output type: 379 | 380 | 控制台输出类型 381 | ~~~~~~~~~~~~~~~ 382 | 383 | 大致的控制台输出类型通过 :option:`--console` 选项来设置. 支持以下大小写无关的几个值: 384 | 385 | ``verbose`` 386 | 每个测试套件和测试用例分别报告. 这是默认的情形. 387 | 388 | ``dotted`` 389 | 仅用点号 `.` 表示测试通过的用例, `f` 表示失败的非重要用例, `F` 表示失败的重要用例, `x` 表示由于 :ref:`测试执行退出 <stopping test execution gracefully>` 而跳过的用例. 失败的重要用例在执行后单独列出. 这种输出类型可以很容易地分辨出那些执行失败的测试用例, 即使用例数量很多. 390 | 391 | ``quiet`` 392 | 除了 :ref:`错误和警告` 没有其它输出. 393 | 394 | ``none`` 395 | 没有任何输出. 当创建自定义输出时(例如, 监听器_)很有用. 396 | 397 | 398 | 选项 :option:`--dotted (-.)` 和 :option:`--quiet` 分别是 `--console dotted` 和 `--console quiet` 的快捷选项. 399 | 400 | Examples:: 401 | 402 | robot --console quiet tests.robot 403 | robot --dotted tests.robot 404 | 405 | .. note:: :option:`--console`, :option:`--dotted` 和 :option:`--quiet` 是 406 | Robot Framework 2.9新增特性. 早期版本的输出总是相当于当前的 `verbose` 模式. 407 | 408 | .. _Console width: 409 | 410 | 控制台宽度 411 | ~~~~~~~~~~ 412 | 413 | 使用选项 :option:`--consolewidth (-W)` 来设置控制台输出的宽度. 默认的值是78个字符. 414 | 415 | .. tip:: 在很多类UNIX系统上, 可以方便地利用环境变量 `$COLUMNS`, 416 | 例如, `--consolewidth $COLUMNS`. 417 | 418 | .. note:: 在Robot Framework 2.9之前, 该功能通过 :option:`--monitorwidth` 选项 419 | 启用, 目前已经废弃并去除. 而短选项 :option:`-W` 在所有版本中都一样用. 420 | 421 | .. _Console colors: 422 | 423 | 控制台颜色 424 | ~~~~~~~~~~ 425 | 426 | 选项 :option:`--consolecolors (-C)` 用来设置是否在控制台输出中使用颜色. 除了在Windows中是使用的Windows API, 其它系统中颜色是通过 :ref:`ANSI colors <http://en.wikipedia.org/wiki/ANSI_escape_code>` 实现的. 在Jython中不能调用Windows的这些API, 所以在Windows中使用Jython是不支持颜色的. 427 | 428 | 该选项支持以下大小写无关的几个值: 429 | 430 | ``auto`` 431 | 当输出到控制台时启用颜色, 但是当重定向到文件或其它地方则没有颜色. 这是默认的情形. 432 | 433 | ``on`` 434 | 当输出重定向时也使用颜色. 在Windows中没有效果. 435 | Colors are used also when outputs are redirected. Does not work on Windows. 436 | 437 | ``ansi`` 438 | 和 `on` 一样. 但是在Windows中也同样使用ANSI颜色. 这在重定向输出到某个程序, 而该程序可以理解ANSI时会非常有用. 这是Robot Framework 2.7.5出现的新功能. 439 | 440 | ``off`` 441 | 不使用颜色. 442 | 443 | .. note:: 在Robot Framework 2.9之前, 该功能通过 :option:`--monitorcolors` 选项 444 | 启用, 目前已经废弃并去除. 而短选项 :option:`-C` 在所有版本中都一样用. 445 | 446 | 447 | .. _Console markers: 448 | 449 | 控制台标记 450 | ~~~~~~~~~~~ 451 | 452 | 从Robot Framework 2.7版本开始, 当控制台使用 :ref:`verbose输出 <console output type>` 时, 当测试用例中的顶层关键字执行结束时, 控制台中会显示特殊的标记 `.` (成功) 和 453 | `F` (失败). 这些标记让我们可以从高层次跟踪测试的执行情况, 并且它们在测试用例执行结束后自动清除掉. 454 | 455 | 从Robot Framework 2.7.4版本开始, 通过 :option:`--consolemarkers (-K)` 选项可以配置合适使用这些标记. 该选项支持以下大小写无关的几个值: 456 | 457 | ``auto`` 458 | 标记在标准输出到控制台时启用, 但是当重定向到文件和其它地方时不出现. 这是默认的情形. 459 | 460 | ``on`` 461 | 始终使用标记. 462 | 463 | ``off`` 464 | 禁用标记. 465 | 466 | .. note:: 在Robot Framework 2.9之前, 该功能通过 :option:`--monitormarkers` 选项 467 | 启用, 目前已经废弃并去除. 而短选项 :option:`-K` 在所有版本中都一样用. 468 | 469 | 470 | .. _setting listeners: 471 | 472 | 设置监听器 473 | ---------- 474 | 475 | 监听器_ 本用来监控测试执行. 当在命令行中使用它们时, 通过选项 :option:`--listener` 来指定. 该选项的值既可以是监听器的文件路径, 也可以是监听器的名字. 详情参见 :ref:`Listener interface` 章节. 476 | -------------------------------------------------------------------------------- /CreatingTestData/AdvancedFeatures.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. Advanced features 5 | 6 | 高级特性 7 | ======== 8 | 9 | .. contents:: 10 | :depth: 2 11 | :local: 12 | 13 | .. _handling keywords with same names: 14 | 15 | 处理同名关键字 16 | -------------- 17 | 18 | Robot Framework中的关键字分为 :ref:`库关键字 <using test libraries>` 和 :ref:`用户关键字 <creating user keywords>`. 前者来自 :ref:`standard libraries` 或 :ref:`external libraries`, 后者则要么在当前调用的文件中创建, 要么从 :ref:`resource files` 中导入. 19 | 20 | 当用到的关键字变得很多时, 难免会遇到重名的情况, 本节将说明如何处理这种冲突状况. 21 | 22 | .. Keyword scopes 23 | 24 | 关键字的范围 25 | ~~~~~~~~~~~~ 26 | 27 | 当仅使用关键字名称时, 如果存在若干同名的关键字, Robot Framework将试图决定哪个关键字的优先级最高. 关键字的优先级将由关键字的创建方式决定: 28 | 29 | 1. 在调用关键字的相同文件中创建. 此关键字拥有最高的优先级. 30 | 31 | 2. 在资源文件中创建并引入(可以是直接引入,也可以是导入的别的资源文件). 此是第二高优先级. 32 | 33 | 3. 在外部库中创建. 只有在没有其它同名的用户关键字存在的情况下才会用到. 而且, 34 | 如果标准库中存在了同名的关键字, 将显示警告. 35 | 36 | 4. 标准库中创建关键字. 这些关键字的优先级最低. 37 | 38 | .. Specifying a keyword explicitly 39 | 40 | 显式指定关键字 41 | ~~~~~~~~~~~~~~ 42 | 43 | 光靠作用域不能完美的解决重名问题, 因为相同作用域的若干库或者资源中也会有同名的关键字. 此时只能使用 *关键字全名*, 所谓全名就是在关键字名称的前面加上其所在的资源或库的名称作为前缀, 中间使用点(``.``)作为分隔. 44 | 45 | 对于库中的关键字, 长名称的格式是 :name:`LibraryName.Keyword Name`. 例如, 标准库 OperatingSystem_ 中的关键字 :name:`Run` 可以写作 :name:`OperatingSystem.Run`. 如果库是一个模块或者包, 则必须使用模块或包的全名(例如: :name:`com.company.Library.Some Keyword`). 如果在引用库的时候使用了 :ref:`WITH NAME syntax`, 则前缀名称必须是该自定义的名称. 46 | 47 | 资源文件中的关键字全名指定格式也是类似. 资源的名称取自资源文件的基础名称(basename)并去掉文件扩展名. 例如, 资源文件 :file:`myresources.html` 中的关键字 :name:`Example` 可以写作 :name:`myresources.Example`. 注意, 这种语法如果遇到多个资源文件的基础名称相同, 则必须修改文件名或者关键字名. 48 | 49 | 关键字的全名和关键字的普通名称一样, 同时忽略大小写, 空格和下划线. 50 | 51 | .. Specifying explicit priority between libraries and resources 52 | 53 | 为库和资源显式指定优先级 54 | ~~~~~~~~~~~~~~~~~~~~~~~~ 55 | 56 | 如果重名冲突的情况比较多, 全部使用全名称格式可能需要不少的工作量. 同时, 全名称格式将难以创建动态的(依赖可用库或资源的)测试用例和用户关键字. 一个针对这两个问题的解决方案是通过一个内置的关键字 :name:`Set Library Search Order` 显式地指定关键字的优先级. 57 | 58 | .. note:: 虽然该关键字的名字中包含了 *library*, 但是它不仅作用于库, 还对资源文件有效. 59 | 60 | :name:`Set Library Search Order` 接受一个有序列表作为参数, 列表中是库和资源的名称. 当关键字名称遭遇到重名的情况, 将依次在这个列表中的库或资源中查找, 一旦找到即被采用. 如果列表内指定的库和资源没有找到关键字, 则重名冲突造成的执行失败和正常情况一样. 61 | 62 | 更多的信息和示例请参阅该关键字的文档. 63 | 64 | .. Timeouts 65 | 66 | 超时处理 67 | -------- 68 | 69 | 关键字有可能会遇到执行时间超长或者执行被挂起的情况. Robot Framework允许为 :ref:`测试用例 <creating test cases>` 和 :ref:`用户关键字 <creating user keywords>` 设置超时时长, 如果用例或者关键字没有在指定时长内结束, 则当前还在执行的关键字会被强行终止. 这种情况有可能会导致测试库或系统进入不稳定的状态, 因此, 超时设置只在没有其它更好更安全的办法下才推荐使用. 70 | 71 | 通常用户在设计和实现库时, 应该仔细设计以避免出现关键字挂起的情况, 或者实现自身的超时处理机制. 72 | 73 | .. Test case timeout 74 | 75 | 测试用例的超时 76 | ~~~~~~~~~~~~~~ 77 | 78 | 测试用例的超时设置可以通过设置表格中的 :setting:`Test Timeout` 设置项, 或者用例表格中的 :setting:`[Timeout]` 设置项. 前者是为当前用例集下的所有的测试用例设定一个默认的超时时长, 而后者则只应用当前单个用例, 并且会覆盖可能存在的默认值. 79 | 80 | 使用空白的 :setting:`[Timeout]` 设置意味着测试永不超时, 即使已经设置了 :setting:`Test Timeout`. 除了空白还可以使用 `NONE`, 结果一样. 81 | 82 | 不管在哪里定义超时, 跟在设置项名称后面的第一个格子中包含的就是超时的时长. 该时长必须使用Robot Framework中的 :ref:`time format`, 可以是直接的秒数, 也可以是诸如 ``1 minute 30 seconds`` 这种格式. 值得注意的是, 框架本身总是会有时间消耗的, 所以不建议将超时时长设置短于1秒. 83 | 84 | 85 | 当超时发生时, 默认的错误提示信息是 ``Test timeout <time> exceeded``. 用户可以自定义错误消息, 只需要将错误消息跟在超时时长的后面格子中. 这里的消息设置和文档类似, 可以跨多个单元格. 86 | 87 | 超时值和错误消息中都可以包含变量. 88 | 89 | 如果有超时, 运行中的关键字被终止, 当前用例执行失败. 不过, 作为 :ref:`test teardown` 运行的关键字不会被中断, 因为teardown操作一般都是重要的清理动作. 如果有必要的话, 可以通过设置 :ref:`用户关键字的超时 <user keyword timeouts>` 来中断这些关键字. 90 | 91 | .. sourcecode:: robotframework 92 | 93 | *** Settings *** 94 | Test Timeout 2 minutes 95 | 96 | *** Test Cases *** 97 | Default Timeout 98 | [Documentation] Timeout from the Setting table is used 99 | Some Keyword argument 100 | 101 | Override 102 | [Documentation] Override default, use 10 seconds timeout 103 | [Timeout] 10 104 | Some Keyword argument 105 | 106 | Custom Message 107 | [Documentation] Override default and use custom message 108 | [Timeout] 1min 10s This is my custom error 109 | Some Keyword argument 110 | 111 | Variables 112 | [Documentation] It is possible to use variables too 113 | [Timeout] ${TIMEOUT} 114 | Some Keyword argument 115 | 116 | No Timeout 117 | [Documentation] Empty timeout means no timeout even when Test Timeout has been used 118 | [Timeout] 119 | Some Keyword argument 120 | 121 | No Timeout 2 122 | [Documentation] Disabling timeout with NONE works too and is more explicit. 123 | [Timeout] NONE 124 | Some Keyword argument 125 | 126 | .. User keyword timeout 127 | 128 | 用户关键字的超时 129 | ~~~~~~~~~~~~~~~~ 130 | 131 | 在关键字表格中通过设置项 :setting:`[Timeout]` 可以为用户关键字设定超时. 使用的语法格式, 包括时长的值的格式和自定义错误都和 :ref:`test case timeouts` 完全一样. 132 | 133 | 稍有不同的地方在于当超时发生且没有自定义错误提示信息时, 默认的错误提示信息是 ``Keyword timeout <time> exceeded``. 134 | 135 | 从Robot Framework3.0版本开始, 超时设置可以由一个变量来指定, 既而该变量可以是由参数来指定. 以前的版本中已经支持使用全局变量来指定超时时长. 136 | 137 | .. sourcecode:: robotframework 138 | 139 | *** Keywords *** 140 | Timed Keyword 141 | [Documentation] Set only the timeout value and not the custom message. 142 | [Timeout] 1 minute 42 seconds 143 | Do Something 144 | Do Something Else 145 | 146 | Wrapper With Timeout 147 | [Arguments] @{args} 148 | [Documentation] This keyword is a wrapper that adds a timeout to another keyword. 149 | [Timeout] 2 minutes Original Keyword didn't finish in 2 minutes 150 | Original Keyword @{args} 151 | 152 | Wrapper With Customizable Timeout 153 | [Arguments] ${timeout} @{args} 154 | [Documentation] Same as the above but timeout given as an argument. 155 | [Timeout] ${timeout} 156 | Original Keyword @{args} 157 | 158 | 用户关键字的超时可以在其执行的过程中应用. 如果整个关键字的执行时长长于指定的超时时长, 则当前正在执行的关键字会被终止. 用户关键字的超时在测试用例的teardown中同样生效, 而测试用例中的超时则不会影响teardown. 159 | 160 | 如果用例和关键字(包括嵌套调用的关键字)都设置了超时, 则其中所余时间最短的将首先触发超时. 161 | 162 | .. _for loop: 163 | 164 | FOR循环 165 | --------- 166 | 167 | 在自动化测试中, 将某些操作重复执行若干次是一个很常见的需求. 在Robot Framework中, 测试库中可以有任意形式的循环结构, 大多数时候循环操作本应该就在测试库中实现. 168 | 169 | Robot Framework也提供了for循环的语法, 这在重复执行来自不同测试库中的关键字的时候很有用. 170 | 171 | for循环既可用于测试用例, 也可以在用户关键字中使用. 除非场景特别简单, 不然还是推荐在用户关键字中使用, 这样可以隐藏for循环带来的复杂度. 基本的for循环语法 ``FOR item IN sequence`` 借鉴于Python, 不过其它脚本如Perl也有类似的语法. 172 | 173 | .. Normal for loop 174 | 175 | 普通FOR循环 176 | ~~~~~~~~~~~~ 177 | 178 | 普通的for循环语法中, 每次迭代都从列表中取一个值赋给变量. 语法以 ``:FOR`` 开始, 注意开始的冒号是必需的, 以便和其它普通关键字区分开. 跟在后面单元格中的是循环变量, 接下来的格子则必须是 ``IN``, 后面的格子(可能是多个)里则包含的是待迭代的值. 这些值中可以包含 :ref:`variables`, 包括 :ref:`list variables`. 179 | 180 | for循环中使用的关键字跟在下面的行中, 必须向右缩进一格. 当使用的是 :ref:`plain text format`, 缩进单元格必须使用 :ref:`反斜杠转义 <escaping>`, 而其它的数据格式则只需要保持空白就行. for循环结束于正常缩进(即不再缩进)的行, 或者是整个表格的结尾. 181 | 182 | .. sourcecode:: robotframework 183 | 184 | *** Test Cases *** 185 | Example 1 186 | :FOR ${animal} IN cat dog 187 | \ Log ${animal} 188 | \ Log 2nd keyword 189 | Log Outside loop 190 | 191 | Example 2 192 | :FOR ${var} IN one two 193 | ... ${3} four ${last} 194 | \ Log ${var} 195 | 196 | 上面 :name:`Example 1` 将迭代执行两次, 第一次循环变量 ``${animal}`` 被赋值 ``cat``, 接下来是 ``dog``. 循环体包含了两次 :name:`Log` 关键字调用. 第二个例子中, 循环值 :ref:`分成了多行 <dividing test data to several rows>`, 循环迭代了5次. 197 | 198 | 在for循环中使用 :ref:`list variables` 更方便. 如下面的例子, ``@{ELEMENTS}`` 是任意长度的列表, 每次迭代会依次对列表中的元素调用 :name:`Start Element`. 199 | 200 | .. sourcecode:: robotframework 201 | 202 | *** Test Cases *** 203 | Example 204 | :FOR ${element} IN @{ELEMENTS} 205 | \ Start Element ${element} 206 | 207 | .. TODO: 此处原文的链接反了 208 | 209 | .. Nested for loops 210 | 211 | FOR循环的嵌套 212 | ~~~~~~~~~~~~~~ 213 | 214 | Robot Framework的for语法并不支持嵌套, 不过可以通过用户关键字封装for循环, 然后在另一个for循环中调用. 215 | 216 | .. sourcecode:: robotframework 217 | 218 | *** Keywords *** 219 | Handle Table 220 | [Arguments] @{table} 221 | :FOR ${row} IN @{table} 222 | \ Handle Row @{row} 223 | 224 | Handle Row 225 | [Arguments] @{row} 226 | :FOR ${cell} IN @{row} 227 | \ Handle Cell ${cell} 228 | 229 | __ `Dividing test data to several rows`_ 230 | __ Escaping_ 231 | 232 | .. Using several loop variables 233 | 234 | 使用多个循环变量 235 | ~~~~~~~~~~~~~~~~~ 236 | 237 | 和Python的for语句类似, 循环变量可以有多个. 该语法和正常的循环语句一样, 只是在 ``:FOR`` 和 ``IN`` 之间有多个循环变量, 每个变量占一格. 循环变量的个数可以是任意个, 但是它们必须能够被值的个数整除. 238 | 239 | 如果有很多值需要迭代, 通常会把它们在循环变量的下面组织对齐, 以提高可读性, 如下面例子中第一个循环: 240 | 241 | .. sourcecode:: robotframework 242 | 243 | *** Test Cases *** 244 | Three loop variables 245 | :FOR ${index} ${english} ${finnish} IN 246 | ... 1 cat kissa 247 | ... 2 dog koira 248 | ... 3 horse hevonen 249 | \ Add to dictionary ${english} ${finnish} ${index} 250 | :FOR ${name} ${id} IN @{EMPLOYERS} 251 | \ Create ${name} ${id} 252 | 253 | .. For-in-range loop 254 | 255 | for-in-range 循环 256 | ~~~~~~~~~~~~~~~~~ 257 | 258 | 前面的for循环总是迭代一个序列, 这是最常见的形式, 但是有时候, 针对某个特定次数的for循环也很有用. Robot Framework提高了特殊的 ``FOR index IN RANGE limit`` 语法来实现这种目的. 同样, 该语法借鉴于Python. 259 | 260 | 和普通的for循环类似, for-in-range循环同样始于 ``:FOR``, 后面跟循环变量. 只是这种情况下, 循环变量只能有一个, 该变量将包含当前循环的下标(index). 循环变量后的格子中必须包含 ``IN RANGE``, 后面的格子包含的是循环的限定范围. 261 | 262 | 最简单的情况是只给出循环的上限, 这种情况下, 循环下标从0开始, 逐次递加1, 直到上限为止(不包括上限). 还可以同时给出起始值(start)和结束值(end), 这种情况下, 循环从start开始, 逐次递加1, 直到end-1. 再复杂一点的情况是通过第3个参数指定每次递进的值(step), 该值可以为负数. 263 | 264 | 对上下限值可以使用简单的算术操作, 如加法和减法, 这在这些值是变量的时候特别有用. 265 | 266 | 从Robot Framework 2.8.7版本开始, start, end 和 step 都可以使用浮点数. 267 | 268 | .. sourcecode:: robotframework 269 | 270 | *** Test Cases *** 271 | Only upper limit 272 | [Documentation] Loops over values from 0 to 9 273 | :FOR ${index} IN RANGE 10 274 | \ Log ${index} 275 | 276 | Start and end 277 | [Documentation] Loops over values from 1 to 10 278 | :FOR ${index} IN RANGE 1 11 279 | \ Log ${index} 280 | 281 | Also step given 282 | [Documentation] Loops over values 5, 15, and 25 283 | :FOR ${index} IN RANGE 5 26 10 284 | \ Log ${index} 285 | 286 | Negative step 287 | [Documentation] Loops over values 13, 3, and -7 288 | :FOR ${index} IN RANGE 13 -13 -10 289 | \ Log ${index} 290 | 291 | Arithmetics 292 | [Documentation] Arithmetics with variable 293 | :FOR ${index} IN RANGE ${var}+1 294 | \ Log ${index} 295 | 296 | Float parameters 297 | [Documentation] Loops over values 3.14, 4.34, and 5.34 298 | :FOR ${index} IN RANGE 3.14 6.09 1.2 299 | \ Log ${index} 300 | 301 | .. For-in-enumerate loop 302 | 303 | for-in-enumerate 循环 304 | ~~~~~~~~~~~~~~~~~~~~~ 305 | 306 | 有时候循环迭代某个列表的时候, 同时又想跟踪当前元素在列表中的位置, 这时候就可以用到Robot Framework的 ``FOR index ... IN ENUMERATE ...`` 语法. 该语法源于 `Python built-in function <https://docs.python.org/2/library/functions.html#enumerate>`_. 307 | 308 | For-in-enumerate循环和普通for循环一样, 只是在循环变量的前面增加一个额外的索引变量, 循环变量后面跟着的是 ``IN ENUMERATE`` 而不是 ``IN``. 索引值从``0``开始. 309 | 310 | 例如, 下面例子中两个测试用例做得是同一件事: 311 | 312 | .. sourcecode:: robotframework 313 | 314 | *** Variables *** 315 | @{LIST} a b c 316 | 317 | *** Test Cases *** 318 | Manage index manually 319 | ${index} = Set Variable -1 320 | : FOR ${item} IN @{LIST} 321 | \ ${index} = Evaluate ${index} + 1 322 | \ My Keyword ${index} ${item} 323 | 324 | For-in-enumerate 325 | : FOR ${index} ${item} IN ENUMERATE @{LIST} 326 | \ My Keyword ${index} ${item} 327 | 328 | 和普通的for循环一样, 一次迭代可以处理多个值, 只要列表元素的总数可以整除一次迭代的变量个数(当然索引变量是不算在内的). 329 | 330 | .. sourcecode:: robotframework 331 | 332 | *** Test Case *** 333 | For-in-enumerate with two values per iteration 334 | :FOR ${index} ${english} ${finnish} IN ENUMERATE 335 | ... cat kissa 336 | ... dog koira 337 | ... horse hevonen 338 | \ Add to dictionary ${english} ${finnish} ${index} 339 | 340 | For-in-enumerate 循环是 Robot Framework 2.9版本新增功能. 341 | 342 | .. For-in-zip loop 343 | 344 | for-in-zip循环 345 | ~~~~~~~~~~~~~~~ 346 | 347 | 有时候需要将几个相关的列表并在一起处理, Robot Framework 使用 ``FOR ... IN ZIP ...`` 语法来处理, 该方法来源于 :ref:`Python built-in zip function <https://docs.python.org/2/library/functions.html#zip>`. 348 | 349 | 来看个例子, 下面两个用例的作用是一样的: 350 | 351 | .. sourcecode:: robotframework 352 | 353 | *** Variables *** 354 | @{NUMBERS} ${1} ${2} ${5} 355 | @{NAMES} one two five 356 | 357 | *** Test Cases *** 358 | Iterate over two lists manually 359 | ${length}= Get Length ${NUMBERS} 360 | : FOR ${idx} IN RANGE ${length} 361 | \ Number Should Be Named ${NUMBERS}[${idx}] ${NAMES}[${idx}] 362 | 363 | For-in-zip 364 | : FOR ${number} ${name} IN ZIP ${NUMBERS} ${NAMES} 365 | \ Number Should Be Named ${number} ${name} 366 | 367 | 和其它循环的语法类似, for-in-zip要求跟在循环变量后面格子中的是 ``IN ZIP``. 368 | 369 | for-in-zip循环的值必须是列表或数组类型的序列, 并且循环变量的数量必须和列表的数量相同. 而迭代的停止取决于其中最短的那个列表. 370 | 371 | 注意, for-in-zip后面用到的列表通常都是以 :ref:`scalar variables` 的形式给出, 如 ``${list}``. 如果是 :ref:`list variable` 形式, 则要求这个列表中的元素本身也是列表. (这里需要对着两种变量的格式理解充分) 372 | 373 | For-in-zip 循环是 Robot Framework 2.9版本新增功能. 374 | 375 | .. Exiting for loop 376 | 377 | 退出for循环 378 | ~~~~~~~~~~~~ 379 | 380 | 通常for循环在所有元素都迭代完成后自然结束, 也有可能当其中的关键字执行失败而退出. 如果需要提前退出循环, 可以调用 BuiltIn_ 关键字 :name:`Exit For Loop` 和 :name:`Exit For Loop If`. 它们的作用类似于编程语言中的 ``break`` 语句. 381 | 382 | :name:`Exit For Loop` 和 :name:`Exit For Loop If` 可以直接在for循环内使用, 也可以在for循环中调用的关键字中使用. 这两种情况都可以让测试跳过循环继续往下执行. 不可以在for循环的外面使用了这两个关键字, 否则会引起错误. 383 | 384 | .. sourcecode:: robotframework 385 | 386 | *** Test Cases *** 387 | Exit Example 388 | ${text} = Set Variable ${EMPTY} 389 | :FOR ${var} IN one two 390 | \ Run Keyword If '${var}' == 'two' Exit For Loop 391 | \ ${text} = Set Variable ${text}${var} 392 | Should Be Equal ${text} one 393 | 394 | 上例中, 可以使用 :name:`Exit For Loop If` 来替代 :name:`Exit For Loop` 加 :name:`Run Keyword If` 的用法. 更多的信息和示例请参阅这些关键字的文档. 395 | 396 | .. note:: :name:`Exit For Loop If` 在Robot Framework 2.8版本新增. 397 | 398 | .. Continuing for loop 399 | 400 | 继续for循环 401 | ~~~~~~~~~~~~~ 402 | 403 | 除了退出整个for循环, 有时候需要的是略过本次迭代而进入下一轮迭代. 这时可以使用 BuiltIn_ 关键字 :name:`Continue For Loop` 和 :name:`Continue For Loop If`, 和编程语言中的 `continue` 语句类似. 404 | 405 | :name:`Continue For Loop` 和 :name:`Continue For Loop If` 可以直接在for循环内使用, 也可以在for循环中调用的关键字中使用. 两种情况下都可以使得本次迭代被跳过, 进入下一次迭代. 如果本次迭代就是最后一次, 则整个循环结束. 同样, 在循环外调用这些关键字是错误的. 406 | 407 | .. sourcecode:: robotframework 408 | 409 | *** Test Cases *** 410 | Continue Example 411 | ${text} = Set Variable ${EMPTY} 412 | :FOR ${var} IN one two three 413 | \ Continue For Loop If '${var}' == 'two' 414 | \ ${text} = Set Variable ${text}${var} 415 | Should Be Equal ${text} onethree 416 | 417 | 关于这些关键字更多的信息和示例请参阅它们在 BuiltIn_ 库的文档 418 | 419 | .. note:: :name:`Continue For Loop` 和 :name:`Continue For Loop If` 420 | 都是在Robot Framework 2.8版本新增. 421 | 422 | .. Removing unnecessary keywords from outputs 423 | 424 | 去除输出中不必要的关键字 425 | ~~~~~~~~~~~~~~~~~~~~~~~~ 426 | 427 | 拥有多次迭代的for循环可以产生大量的输出信息, 从而造成 output_ 和 log_ 文件大小的显著增加. 从Robot Framework 2.7版本开始, 可以使用命令行选项 :option:`--RemoveKeywords FOR` 从输出中 `remove unnecessary keywords`__. 428 | 429 | __ `Removing and flattening keywords`_ 430 | 431 | .. Repeating single keyword 432 | 433 | 重复执行单个关键字 434 | ~~~~~~~~~~~~~~~~~~ 435 | 436 | 当每次循环只需要重复调用一个关键字的时候, 使用for循环显得有点小题大做. 这时候可以使用 BuiltIn_ 关键字 :name:`Repeat Keyword`. 该关键字的第一个参数要重复的次数, 后面是要重复的关键字, 以及它的参数. 重复次数的值可以加上后缀 ``times`` 或者 ``x`` 以提高可读性. 437 | 438 | .. sourcecode:: robotframework 439 | 440 | *** Test Cases *** 441 | Example 442 | Repeat Keyword 5 Some Keyword arg1 arg2 443 | Repeat Keyword 42 times My Keyword 444 | Repeat Keyword ${var} Another Keyword argument 445 | 446 | .. Conditional execution 447 | 448 | 条件执行 449 | -------- 450 | 451 | 通常来说, 不建议在测试用例中使用条件判断的逻辑, 甚至在用户关键字中也不要用, 因为这会使得用例和关键字变得难以理解和维护. 这种逻辑应该放在测试库中, 这样就可以很自然地使用编程语言的语法结构来实现. 452 | 453 | 然而, 总会有些时候会发现条件判断逻辑是有用的, 虽然Robot Framework并没有提供if/else的语法结构, 但是我们可以通过其它几种方式来实现相同的效果. 454 | 455 | - 在 :ref:`测试用例 <test setup and teardown>` 和 :ref:`测试套件 <suite setup and teardown>` 的setup或teardown中的关键字名称可以使用变量来代替. 456 | 这样利于根据条件来改变关键字, 如通过命令行. 457 | 458 | - BuiltIn_ 关键字 :name:`Run Keyword` 把其它关键字作为参数来调用, 自然也可以是变量. 459 | 这个变量的值就可以动态的确立, 如根据前面的关键字结果或者是命令行. 460 | 461 | - BuiltIn_ 关键字 :name:`Run Keyword If` 和 :name:`Run Keyword Unless` 只在 462 | 特定的表达式结果是true或false的情况才调用指定的关键字. 所以简单的 if/else 结构, 463 | 完全可以由它们来完成. 详细的例子可以参考关键字的文档. 464 | 465 | - 另一个 BuiltIn_ 关键字 :name:`Set Variable If` 可以根据条件表达式的结果, 动态的 466 | 为变量赋值. 467 | 468 | - 还有几个 BuiltIn_ 关键字可以在测试用例/套件执行失败或成功的时候才调用指定的关键字. 469 | 470 | 471 | .. Parallel execution of keywords 472 | 473 | 关键字的并发执行 474 | ---------------- 475 | 476 | 如果有并发执行的需求, 必须在测试库中实现, 并且代码应该运行在后台. 通常这意味着测试库应该有一个关键字如 :name:`Start Something` 来启动执行, 并且立即返回, 然后通过另一个关键字如 :name:`Get Results From Something`, 等待获取执行的结果并返回. 477 | 478 | 可以参考 OperatingSystem_ 库中的 :name:`Start Process` 和 :name:`Read Process Output` 实现. 479 | -------------------------------------------------------------------------------- /ExecutingTestCases/OutputFiles.rst: -------------------------------------------------------------------------------- 1 | .. _created outputs: 2 | 3 | 输出文件 4 | ======== 5 | 6 | 测试执行完成后会创建多个输出文件, 所有这些文件都和测试结果相关. 本章将讨论什么输出文件会被创建, 如何配置创建地点, 以及如何调整输出内容. 7 | 8 | .. contents:: 9 | :depth: 2 10 | :local: 11 | 12 | .. _different output files: 13 | 14 | 不同输出文件 15 | ------------ 16 | 17 | 本节将说明有哪几种不同的输出文件, 以及如何配置它们输出的目录. 18 | 19 | 输出文件都是通过命令行选项来配置, 选项的参数就是输出文件的路径. 一个特殊值 ``NONE`` (大小写无关)可被用来禁止输出某种文件. 20 | 21 | 22 | .. _output directory: 23 | 24 | 输出目录 25 | ~~~~~~~~ 26 | 27 | 所有的输出文件都可设置为绝对路径, 也就是可以分别指定创建到不同的地方. 此外, 路径也可以是相对输出目录的相对路径. 28 | 29 | 默认的输出目录是测试执行开始的地方, 可以通过选项 :option:`--outputdir (-d)` 指定. 该选项指定的路径, 同样既可以是绝对路径, 也可以是相对执行路径的位置. 30 | 31 | 不管输出文件的路径是以何种方式给出, 其所在的文件夹都会自动被创建(如果不存在的话). 32 | 33 | .. _output.xml: 34 | .. _output file: 35 | 36 | 输出文件(Output.xml) 37 | ~~~~~~~~~~~~~~~~~~~~~ 38 | 39 | .. note:: 译注: 40 | 本小节讨论的是特指XML格式的输出文件, 为了区分泛指的输出文件(日志,报告等), 41 | 接下来当特指XML格式的输出文件时, 将不做翻译, 直接称Output文件. 42 | 43 | 44 | Output文件包含了测试执行的所有结果, 以XML格式保存. :ref:`日志 <log file>`, :ref:`报告 <report file>` 和 :ref:`xUnit <xunit file>` 这些都是基于XML文件创建, 并且还可以使用 Rebot_ 进一步组合和后处理. 45 | 46 | 47 | .. tip:: 从Robot Framework 2.8, 生成 :ref:`报告 <report file>` 和 :ref:`xUnit <xunit file>` 文件不再需要处理output文件. 48 | 这样在测试执行时禁用 :ref:`日志 <log file>` 的话就可以减少内存使用. 49 | 50 | 命令行选项 :option:`--output (-o)` 决定了output文件创建的路径, 如果不是绝对路径的话, 该路径是相对于 :ref:`output directory`. 默认的output文件名称是 :file:`output.xml`. 51 | 52 | 当使用Rebot :ref:`post-processing outputs` 时, 除非明确使用 :option:`--output` 选项, 否则不会创建新的output文件. 53 | 54 | 为选项 :option:`--output` 指定特殊值 ``NONE`` 可以禁止output文件生成. 在Robot Framework 2.8版本之前, 这同样会禁止日志和报告文件的生成, 不过现今的版本不会这样了. 如果想禁用所有, 必须明确的分别指定 ``--output NONE --report NONE --log NONE``. 55 | 56 | .. _log file: 57 | 58 | 日志文件 59 | ~~~~~~~~ 60 | 61 | 日志文件以HTML格式记录了测试用例执行的细节, 以层次的结构展示测试套件, 测试用例和关键字的细节. 当每次需要详细地研究测试结果时, 日志文件几乎都是必需的. 此外, 尽管日志文件也包含了统计, 更高层次的概览信息也是参考报告文件比较好. 62 | 63 | 命令行选项 :option:`--log (-l)` 指定了日志文件创建的位置. 除非使用了特殊值 ``NONE``, 日志文件总是会创建, 其默认名称是 :file:`log.html`. 64 | 65 | .. figure:: src/ExecutingTestCases/:ref:`日志 <log file>`passed.png 66 | :target: src/ExecutingTestCases/:ref:`日志 <log file>`passed.html 67 | :width: 500 68 | 69 | An example of beginning of a log file 70 | 71 | .. figure:: src/ExecutingTestCases/:ref:`日志 <log file>`failed.png 72 | :target: src/ExecutingTestCases/:ref:`日志 <log file>`failed.html 73 | :width: 500 74 | 75 | An example of a log file with keyword details visible 76 | 77 | .. _report file: 78 | 79 | 报告文件 80 | ~~~~~~~~ 81 | 82 | 报告(Report)文件也是HTML格式, 包含测试执行结果的概况. 其中有基于标签和测试套件的统计结果, 还有所有执行的测试用例列表. 83 | 84 | 当同时生成日志文件和报告文件时, 报告文件内会有指向日志文件的链接, 可以轻松的导航到更详细的信息. 85 | 86 | 当所有 :ref:`critical tests` 通过时, 报告页面的背景是绿色, 反之则是红色, 这使得通过报告可以轻松了解到测试执行的总体状态. 87 | 88 | 命令行选项 :option:`--report (-r)` 指定了报告文件创建的位置. 除非使用了特殊值 ``NONE``, 报告文件总是会创建, 其默认名称是 :file:`report.html`. 89 | 90 | .. figure:: src/ExecutingTestCases/:ref:`报告 <report file>`passed.png 91 | :target: src/ExecutingTestCases/:ref:`报告 <report file>`passed.html 92 | :width: 500 93 | 94 | An example report file of successful test execution 95 | 96 | .. figure:: src/ExecutingTestCases/:ref:`报告 <report file>`failed.png 97 | :target: src/ExecutingTestCases/:ref:`报告 <report file>`failed.html 98 | :width: 500 99 | 100 | An example report file of failed test execution 101 | 102 | .. _xunit: 103 | .. _xunit file: 104 | .. _XUnit compatible result file: 105 | 106 | 兼容XUnit的结果文件 107 | ~~~~~~~~~~~~~~~~~~~~ 108 | 109 | XUnit结果文件包含了兼容 :ref:`xUnit <http://en.wikipedia.org/wiki/XUnit>` 的XML格式的测试执行概况. 这些文件可以作为那些处理xUnit报告的外部工具的输入. 例如, 持续集成工具 :ref:`Jenkins <http://jenkins-ci.org>` 服务器就支持基于xUnit相容的结果生成统计. 110 | 111 | .. tip:: Jenkins also has a separate :ref:`Robot Framework plugin <https://wiki.jenkins-ci.org/display/JENKINS/Robot+Framework+Plugin>`. 112 | 113 | XUnit输出文件只在明确的使用了命令行选项 :option:`--xunit (-x)` 之后才会创建. 该选项需要指定生成xUnit文件的路径, 相对于 :ref:`output directory`. 114 | 115 | 因为xUnit报告没有所谓 :ref:`non-critical tests <setting criticality>` 的概念, 所有的测试都会被标记为通过或失败, 而没有关键的和非关键的之分. 如果这样处理有问题, 可以使用选项 :option:`--xunitskipnoncritical` 将非关键的用例标记为略过. 被略过的测试将会获得一个包含了实际状态以及可能的测试用例发出的消息(message), 整个消息的格式类似于 ``FAIL: Error message``. 116 | 117 | .. note:: :option:`--xunitskipnoncritical` 是Robot Framework 2.8才有的新选项. 118 | 119 | 120 | .. _debug file: 121 | 122 | 调试文件 123 | ~~~~~~~~~~ 124 | 125 | 调试(Debug)文件是纯文本文件, 在测试执行过程中被写入. 所有的测试库产生的消息都会被写入, 同时还包括测试套件, 测试用例以及关键字的启动和结束信息. 调试文件可被用来监控测试执行. 例如使用 :ref:`fileviewer.py <https://bitbucket.org/robotframework/robottools/src/master/fileviewer/>` 工具, 或者在类UNIX系统中, ``tail -f`` 命令即可. 126 | 127 | 调试文件只在明确的使用了选项 :option:`--debugfile (-b)` 后才会被创建. 128 | 129 | .. _timestamping output files: 130 | 131 | 给输出文件打时间戳 132 | ~~~~~~~~~~~~~~~~~~ 133 | 134 | 本章提到的所有输出文件都可以自动打上时间戳, 使用 :option:`--timestampoutputs (-T)` 选项, 时间戳的格式为 ``YYYYMMDD-hhmmss``, 位于文件扩展名和基础名之间. 135 | 136 | 例如, 下面的例子中的输出文件分别是 :file:`output-20080604-163225.xml` 和 :file:`mylog-20080604-163225.html`:: 137 | 138 | robot --timestampoutputs --log mylog.html --report NONE tests.robot 139 | 140 | .. _setting titles: 141 | 142 | 设置标题 143 | ~~~~~~~~ 144 | 145 | :ref:`日志 <log file>` 和 :ref:`报告 <report file>` 文件的标题(title)由顶层测试套件名加上 :name:`Test Log` 或 :name:`Test Report` 组成. 自定义的标题可以通过命令行选项 :option:`--logtitle` 和 :option:`--reporttitle` 分别指定. 146 | 147 | Example:: 148 | 149 | robot --logtitle Smoke_Test_Log --reporttitle Smoke_Test_Report --include smoke my_tests/ 150 | 151 | .. _setting background colors: 152 | 153 | 设置背景色 154 | ~~~~~~~~~~ 155 | 156 | 默认情况下, :ref:`report file` 在所有 :ref:`关键测试 <setting criticality>` 都通过的时候背景色为绿色, 否则背景是红色. 这些颜色可以通过命令行选项 :option:`--reportbackground` 自定义, 该选项接受以冒号分隔的两个或三个颜色参数:: 157 | 158 | --reportbackground blue:red 159 | --reportbackground green:yellow:red 160 | --reportbackground #00E:#E00 161 | 162 | 当指定两个颜色时, 第一个用来替代默认的绿色, 第二个用来替代默认的红色. 这样就可以使用蓝色替代绿色背景, 对色盲人群来说更容易区分. 163 | 164 | 如果指定三个颜色, 第一个在所有用例都成功时使用, 第二个在只有非关键用例失败的时候, 而最后一个在有关键用例失败的时候使用. 这样, 如果想识别出非关键测试失败的情况, 就可以单独为此指定个颜色, 如黄色. 165 | 166 | 颜色值是针对HTML页面的 ``body`` 元素的 ``background`` CSS属性. 该值可以是HTML支持的颜色名称(如: ``red``), 十六进制的值(如: ``#f00`` 或 ``#ff0000``), 或者是一个RGB值(如: ``rgb(255,0,0)``). 默认的绿色和红色分别对应的十六进制值是 ``#9e9`` 和 ``#f66``. 167 | 168 | .. _log levels: 169 | .. _log level: 170 | 171 | 日志级别 172 | ---------- 173 | 174 | .. _available log levels: 175 | 176 | 可用的日志级别 177 | ~~~~~~~~~~~~~~ 178 | 179 | :ref:`log file` 中的消息可以有不同的日志级别. 这些消息有些是Robot Framework自己写入, 有的是被执行的关键字打印的不同的级别 :ref:`日志消息 <logging information>`. 可用的日志级别包括: 180 | 181 | ``FAIL`` 182 | 当关键字失败时使用. 只能由Robot Framework自己使用. 183 | 184 | ``WARN`` 185 | 用来展示警告. 警告消息同样会出现在 :ref:`控制台以及日志文件的测试执行错误区 <errors and warnings during execution>`, 186 | 不过它们不会影响到测试用例的状态. 187 | 188 | ``INFO`` 189 | 默认的消息级别. 默认情况下日志文件中不会显示低于此级别的消息. 190 | 191 | ``DEBUG`` 192 | 用于调试目的. 当需要记录测试库内部执行过程时很有用. 当关键字失败时, 代码失败的地方会自动使用该级别打印traceback信息. 193 | 194 | ``TRACE`` 195 | 更详细的调试级别. 使用该级别时, 关键字的参数和返回值会自动写入日志. 196 | 197 | 198 | .. _setting log level: 199 | 200 | 设置日志级别 201 | ~~~~~~~~~~~~ 202 | 203 | 默认情况下, 低于 ``INFO`` 级别的日志消息不会写日志, 不过这个阈值可以通过命令行选项 :option:`--loglevel (-L)` 修改. 该选项接受任意的日志级别作为参数. 还可以使用 ``NONE`` 这个特殊值来禁止所有日志. 204 | 205 | 在使用Rebot :ref:`post-processing outputs` 时也可以使用 :option:`--loglevel` 选项. 这样可以做到, 例如, 在测试执行时使用 ``TRACE`` 级别, 产生详细的日志信息, 但是要在随后普通查看时使用 ``INFO`` 级别生成更小的日志文件. 默认情况下所有执行阶段产生的消息在Rebot处理时也都包含. 反之则不行, 执行阶段省略的消息不可能再恢复. 206 | 207 | 在测试数据中使用 BuiltIn_ 关键字 :name:`Set Log Level` 也可以改变日志级别. 该关键字的参数和 :option:`--loglevel` 一样, 并且会返回原来的日志级别以备后续(如teardown)恢复. 208 | 209 | .. _visible log level: 210 | 211 | 可见的日志级别 212 | ~~~~~~~~~~~~~~ 213 | 214 | 自Robot Framework 2.7.2版本开始, 如果日志文件中包含 ``DEBUG`` 或 ``TRACE`` 级别的消息, 则在右上角会出现一个下拉框, 让用户选择低于某个级别的日志不可见. 这在使用 ``TRACE`` 级别运行测试时特别有用. 215 | 216 | .. figure:: ./visible_log_level.png 217 | :target: ./visible_log_level.html 218 | :width: 500 219 | 220 | An example log showing the visible log level drop down 221 | 222 | 默认情况下, 下拉框被设置选中最低级别, 以显示日志文件中的所有消息. 默认的可视日志级别可通过选项 :option:`--loglevel` 更改, 将其值设置为如下的格式:: 223 | 224 | --loglevel DEBUG:INFO 225 | 226 | 可视日志级别跟在正常的日志级别之后, 用冒号分隔, 上例中, 测试运行的日志级别是 ``DEBUG``, 但是默认的可视级别是 ``INFO``. 227 | 228 | .. Splitting logs 229 | 230 | 分割日志 231 | -------- 232 | 233 | 正常情况下, 日志文件就是一个单个HTML文件. 随着测试用例的数量增长, 文件的大小也越来越大, 以至于不方便(甚至不可能)用浏览器打开. 因此, 可以使用选项 :option:`--splitlog` 来将日志文件分割成若干部分到外部文件, 当浏览器需要时再加载. 234 | 235 | 分割日志最大的好处是每个独立的日志部分都很小, 所以即使整个测试数据很庞大, 打开和浏览日志文件也会很容易. 一个小缺点是, 当日志文件增长时, 全部文件大小会较多. 236 | 237 | 技术上讲, 每个测试用例相关的测试数据保存在一个JavaScript文件中, 该文件位于主日志文件相同目录内. 这些文件的命名如 :file:`log-42.js`, 其中 :file:`log` 主日志文件的基础名称, 而 :file:`42` 是递增的序号. 238 | 239 | .. note:: 当拷贝日志文件时, 必须将所有的 :file:`log-*.js` 文件都带上. 240 | 241 | 242 | .. _configuring statistics: 243 | 244 | 配置统计 245 | -------- 246 | 247 | 有几个命令行选项可用来配置和调整输出文件中统计相关的内容, 包括 :name:`Statistics by Tag`, :name:`Statistics by Suite` 和 :name:`Test Details by Tag` 表格. 所有这些选项都可同时用于测试执行和后处理输出. 248 | 249 | .. Configuring displayed suite statistics 250 | 251 | 配置测试套件统计 252 | ~~~~~~~~~~~~~~~~ 253 | 254 | 当一个层次较深的测试套件被执行后, 要在 :name:`Statistics by Suite` 表中显示所有的测试套件级别会让表格变得很难看. 默认情况下所有的测试套件都显示, 但是可以通过命令行选项 :option:`--suitestatlevel` 来控制, 该选项接受的参数值表示套件的级别:: 255 | 256 | --suitestatlevel 3 257 | 258 | .. Including and excluding tag statistics 259 | 260 | 包括和排除标签统计 261 | ~~~~~~~~~~~~~~~~~~ 262 | 263 | 如果使用了很多的标签, :name:`Statistics by Tag` 表也会变得非常拥挤. 命令行选项 :option:`--tagstatinclude` 和 :option:`--tagstatexclude` 可被用来选择哪些标签要展示或不展示. 类似于选项 :option:`--include` and :option:`--exclude` 被用来 :ref:`选择测试用例 <by tag names>`:: 264 | 265 | --tagstatinclude some-tag --tagstatinclude another-tag 266 | --tagstatexclude owner-* 267 | --tagstatinclude prefix-* --tagstatexclude prefix-13 268 | 269 | 270 | .. Generating combined tag statistics 271 | 272 | 生成组合标签统计 273 | ~~~~~~~~~~~~~~~~ 274 | 275 | 命令行选项 :option:`--tagstatcombine` 可用来生成标签集合, 将多个标签的统计组合起来. 276 | 277 | 标签组合使用 :ref:`tag patterns` 指定, 其中 ``*`` 和 ``?`` 作为通配符, 并可使用 ``AND``, ``OR`` 和 ``NOT`` 操作符将单个标签或模式结合起来. 278 | 279 | 下面的例子展示了使用不同的模式来组合标签统计, 下面的图片显示了结果的 :name:`Statistics by Tag` 表的片段:: 280 | 281 | --tagstatcombine owner-* 282 | --tagstatcombine smokeANDmytag 283 | --tagstatcombine smokeNOTowner-janne* 284 | 285 | .. figure:: ./tagstatcombine.png 286 | :width: 550 287 | 288 | Examples of combined tag statistics 289 | 290 | 如上所示, 添加的组合统计的名字默认就是给出的模式. 如果这样还不够, 还可以自定义名字, 在模式的后面用冒号(``:``)分隔紧接着跟上名字. 名字中的下划线会被转换为空格:: 291 | 292 | --tagstatcombine prio1ORprio2:High_priority_tests 293 | 294 | .. Creating links from tag names 295 | 296 | 标签统计链接 297 | ~~~~~~~~~~~~ 298 | 299 | 使用命令行选项 :option:`--tagstatlink` 可以在 :name:`Statistics by Tag` 表格中添加外部链接. 该选项的参数值的格式是 ``tag:link:name``, 其中 ``tag`` 是要添加链接的标签, ``link`` 是要创建的链接, ``name`` 是链接的名字. 300 | 301 | ``tag`` 可以是单个标签, 但更多时候是使用 :ref:`simple pattern`, ``*`` 匹配任意内容, ``?`` 匹配任意的单个字符. 当 ``tag`` 是一个模式时, 通配符匹配的内容可以在 ``link`` 和 ``title`` 使用 ``%N`` 替代, 其中"N"是从1开始计数的匹配序号. 302 | 303 | 下面的例子展示了该选项的用法, 下面的图片展示了使用这些选项执行测试后的 :name:`Statistics by Tag` 表的结果片段:: 304 | 305 | 306 | --tagstatlink mytag:http://www.google.com:Google 307 | --tagstatlink jython-bug-*:http://bugs.jython.org/issue_%1:Jython-bugs 308 | --tagstatlink owner-*:mailto:%1@domain.com?subject=Acceptance_Tests:Send_Mail 309 | 310 | .. figure:: ./tagstatlink.png 311 | :width: 550 312 | 313 | Examples of links from tag names 314 | 315 | .. Adding documentation to tags 316 | 317 | 给标签添加文档 318 | ~~~~~~~~~~~~~~ 319 | 320 | 标签可以使用命令行选项 :option:`--tagdoc` 给定文档, 该选项的参数格式是 ``tag:doc``. 其中 `tag` 是标签的名字, 也可以是表示多个标签的 :ref:`simple pattern`. `doc` 是要指定的文档. 文档中的下划线自动转为空格, 并且文档中可以包含 :ref:`HTML formatting`. 321 | 322 | 给定的文档将和匹配的标签在 :name:`Test Details by Tag` 表格中展示, 同时在 :name:`Statistics by Tag` 表格中作为这些标签的提示. 323 | 324 | 如果一个标签有多个文档, 则这些文档将使用 ``&`` 连在一起. 325 | 326 | 示例:: 327 | 328 | --tagdoc mytag:My_documentation 329 | --tagdoc regression:*See*_http://info.html 330 | --tagdoc owner-*:Original_author 331 | 332 | .. Removing and flattening keywords 333 | 334 | Remove和Flatten关键字 335 | ---------------------- 336 | 337 | :ref:`output files` 大部分的内容来自于关键字和它们的日志消息. 当创建更高层的报告时, 日志文件完全可以忽略, 这时关键字和它们的消息只是占用无谓的空间. 日志文件本身也有可能会变得非常庞大, 特别是其中包含了 :ref:`for loops`, 或者是其它重复执行多次某个关键字的结构. 338 | 339 | 这种情况下, 命令行选项 :option:`--removekeywords` 和 :option:`--flattenkeywords` 可被用来丢弃或压平(flatten)非必要的关键字. 340 | 341 | 这两个选项都可用在 :ref:`executing test cases` 和 :ref:`post-processing outputs`. 当用在测试执行时, 只影响日志文件, 不影响XML输出文件. 而用在 ``rebot`` 命令时, 日志文件和可能新建的XML文件都会影响. 342 | 343 | .. _removing keywords: 344 | 345 | Remove关键字 346 | ~~~~~~~~~~~~~ 347 | 348 | 选项 :option:`--removekeywords` 将关键字连同它们的消息一起删除. 该选项可以有以下几种操作模式, 并且可以指定多次来启用多种模式. 包含了 :ref:`错误和警告 <errors and warnings>` 的关键字不会删除, 除非使用的是 ``ALL`` 模式. 349 | 350 | ``ALL`` 351 | 无条件地删除所有关键字的数据 352 | 353 | ``PASSED`` 354 | 删除成功通过的测试用例的关键字. 大多数情况下, 使用该选项创建的日志文件包含了足够信息来调查可能的故障. 355 | 356 | ``FOR`` 357 | 删除 :ref:`for loops` 所有通过的迭代, 除了最后一个. 358 | 359 | ``WUKS`` 360 | 删除在内置关键字 :name:`Wait Until Keyword Succeeds` 之中失败的关键字, 除了最后一个. 361 | 362 | ``NAME:<pattern>`` 363 | 删除所有匹配模式的关键字数据, 不管该关键字的状态是什么. 模式匹配针对关键字的全名, 也就是说可能包括了库名或资源文件名的前缀. 模式不区分大小写, 并且忽略空格和下划线, 并且支持 :ref:`simple patterns`, 可使用 ``*`` 和 ``?`` 做通配符. 364 | 365 | ``TAG:<pattern>`` 366 | 删除所有标签匹配上给定模式的关键字数据. 标签对大小写和空格都不敏感, 并且可以使用 :ref:`tag patterns`, 也就是说可以使用 ``*`` 和 ``?`` 做通配符, 以及 ``AND``, ``OR`` 和 ``NOT`` 操作符. :ref:`库关键字的标签 <keyword tags>` 和 :ref:`user keyword tags` 都可以. 367 | 368 | 369 | 示例:: 370 | 371 | rebot --removekeywords all --output removed.xml output.xml 372 | robot --removekeywords passed --removekeywords for tests.robot 373 | robot --removekeywords name:HugeKeyword --removekeywords name:resource.* tests.robot 374 | robot --removekeywords tag:huge tests.robot 375 | 376 | 删除关键字是在解析完 :ref:`output file` 并且生成了内部模型之后. 所以不会像 :ref:`flattening keywords` 那样减少对内存的占用. 377 | 378 | .. note:: 在执行测试时可用选项 :option:`--removekeywords` 379 | 以及 `FOR` 和 `WUKS` 两种模式是在 Robot Framework 2.7 新增. 380 | 381 | .. note:: `NAME:<pattern>` 模式在 Robot Framework 2.8.2 版本新增, 382 | `TAG:<pattern>` 在 2.9 版本新增. 383 | 384 | 385 | .. _flattening keywords: 386 | 387 | Flatten关键字 388 | ~~~~~~~~~~~~~~ 389 | 390 | 选项 :option:`--flattenkeywords` 将匹配的关键字"压平", 也就是说, 只保留该关键字全部的日志消息, 包括所有子关键字(递归)的日志, 而子关键字自身则都被丢弃. 391 | 392 | .. this means that matching keywords get all log messages from their child 393 | .. keywords, recursively, and child keywords are discarded otherwise. Flattening 394 | .. supports the following modes: 395 | 396 | Flatten支持以下几种模式: 397 | 398 | ``FOR`` 399 | Flatten :ref:`for loops` fully. 400 | 401 | ``FORITEM`` 402 | Flatten individual for loop iterations. 403 | 404 | ``NAME:<pattern>`` 405 | 压平匹配模式的关键字. 模式匹配的规则和 :ref:`removing keywords` 和 `NAME:<pattern>` 模式一样. 406 | 407 | ``TAG:<pattern>`` 408 | 409 | 压平标签匹配上的关键字, 规则和 :ref:`removing keywords` 的 `TAG:<pattern>` 模式一样. 410 | 411 | 示例:: 412 | 413 | robot --flattenkeywords name:HugeKeyword --flattenkeywords name:resource.* tests.robot 414 | rebot --flattenkeywords foritem --output flattened.xml original.xml 415 | 416 | 压平关键字是在 :ref:`output file` 初始解析之前就已经完成, 所以可以节约大量的内存, 特别是当关键字嵌套比较深的时候. 417 | 418 | 419 | .. note:: Flattening keywords is a new feature in Robot Framework 2.8.2, `FOR` 420 | and `FORITEM` modes were added in 2.8.5 and `TAG:<pattern>` in 2.9. 421 | 422 | .. _setting start and end time of execution: 423 | 424 | 设置执行的起始和结束时间 425 | ------------------------ 426 | 427 | .. hint:: 译注: 没太明白这个选项有什么作用, 待测试后理解了再补充. 428 | 429 | 430 | 431 | 当使用Rebot来 :ref:`combining outputs` 时, 可以通过设定选项 :option:`--starttime` 和 :option:`--endtime` 来分别指定组合测试套件的开始和结束时间. 432 | 433 | 默认情况下, 组合的测试套件不包含这两个值. 当给定了这两个值之后, 整个执行的消耗时间也就基于此来计算. 否则只能通过累加子套件的耗时来计算. 434 | 435 | 该选项也可以用在单个测试套件上, 同样也会影响到测试套件的消耗时间. 436 | 437 | 时间戳的格式为必须是 ``YYYY-MM-DD hh:mm:ss.mil``, 所有的分隔符都是可选的, 毫秒到小时的部分也是可以忽略的. 例如, ``2008-06-11 17:59:20.495`` 和 ``20080611-175920.495`` 和 ``20080611175920495`` 都是等价的, 仅 ``20080611`` 也可以. 438 | 439 | 示例:: 440 | 441 | rebot --starttime 20080611-17:59:20.495 output1.xml output2.xml 442 | rebot --starttime 20080611-175920 --endtime 20080611-180242 *.xml 443 | rebot --starttime 20110302-1317 --endtime 20110302-11418 myoutput.xml 444 | 445 | .. _pre-Rebot modifier: 446 | .. _programmatic modification of results: 447 | 448 | 结果的编程式修改 449 | ------------------- 450 | 451 | 如果内置的修改测试结果的功能无法满足需求, Robot Framework 2.9 以及更新的版本提供了编程式地自定义修改途径. 使用 :option:`--prerebotmodifier` 选项来创建一个模型修改器(model modifier). 452 | 453 | 该功能的原理和使用 :option:`--prerunmodifier` 选项来启用 :ref:`programmatic modification of test data` 几乎一样. 明显的区别在于这次修改器操作的是 :ref:`result model` 而不是 :ref:`running model`. 454 | 455 | 例如, 下面的修改器将所有虽然执行通过但是耗时超过一定限制的测试用例标记为失败: 456 | 457 | .. sourcecode:: python 458 | 459 | from robot.api import SuiteVisitor 460 | 461 | 462 | class ExecutionTimeChecker(SuiteVisitor): 463 | 464 | def __init__(self, max_seconds): 465 | self.max_milliseconds = float(max_seconds) * 1000 466 | 467 | def visit_test(self, test): 468 | if test.status == 'PASS' and test.elapsedtime > self.max_milliseconds: 469 | test.status = 'FAIL' 470 | test.message = 'Test execution took too long.' 471 | 472 | 假设上面的修改器是保存在文件 :file:`ExecutionTimeChecker.py` 之中, 则像这样指定:: 473 | 474 | # Specify modifier as a path when running tests. Maximum time is 42 seconds. 475 | robot --prerebotmodifier path/to/ExecutionTimeChecker.py:42 tests.robot 476 | 477 | # Specify modifier as a name when using Rebot. Maximum time is 3.14 seconds. 478 | # ExecutionTimeChecker.py must be in the module search path. 479 | rebot --prerebotmodifier ExecutionTimeChecker:3.14 output.xml 480 | 481 | 如果需要应用多个模型修改器, 则 :option:`--prerebotmodifier` 可以指定多次. 482 | 483 | 当执行测试时, :option:`--prerunmodifier` 和 :option:`--prerebotmodifier` 可以同时使用. 484 | 485 | 486 | .. _system log: 487 | .. _syslog: 488 | 489 | 系统日志 490 | -------- 491 | 492 | Robot Framework 有自己的系统日志, 其中包含的信息主要关于: 493 | 494 | - 被处理和被跳过的测试数据文件 495 | - 导入的测试库, 资源文件和变量文件 496 | - 执行的测试套件和测试用例 497 | - 创建的输出 498 | 499 | 通常情况下用户永远不需要知道这些信息, 只有在定位测试库的问题, 亦或者是Robot Framework自身的问题时, 才显得有用. 500 | 501 | 系统日志默认并不会创建, 通过设置环境变量 ``ROBOT_SYSLOG_FILE`` 的值为包含日志的路径名来启用该日志. 502 | 503 | 系统之日和普通的日志文件拥有一样的 :ref:`log levels`, 例外在于没有 ``FAIL`` 级别, 取而代之的是 ``ERROR`` 级别. 系统日志级别通过环境变量 ``ROBOT_SYSLOG_LEVEL`` 来指定. 504 | 505 | 可能的 :ref:`未预期的错误和警告 <errors and warnings during execution>` 除了写入控制台和普通日志文件外也会写入系统日志. 506 | 507 | .. sourcecode:: bash 508 | 509 | #!/bin/bash 510 | 511 | export ROBOT_SYSLOG_FILE=/tmp/syslog.txt 512 | export ROBOT_SYSLOG_LEVEL=DEBUG 513 | 514 | robot --name Syslog_example path/to/tests 515 | -------------------------------------------------------------------------------- /SupportingTools/Libdoc.rst: -------------------------------------------------------------------------------- 1 | .. role:: name(emphasis) 2 | .. role:: setting(emphasis) 3 | 4 | .. _libdoc: 5 | 6 | 库文档工具(Libdoc) 7 | =================== 8 | 9 | `原文 <http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#library-documentation-tool-libdoc>`_ 10 | 11 | .. contents:: 12 | :depth: 1 13 | :local: 14 | 15 | Libdoc是Robot Framework内置的工具, 用来为测试库和资源文件生成关键字的文档. 文档分为HTML和XML格式, 前者供人阅读, 后者供 RIDE_ 和其它工具使用. Libdoc还提供了几个特别的命令来在控制台显示库和资源的信息. 16 | 17 | 可以创建的文档包括: 18 | 19 | - 使用 :ref:`Python <Python libraries>` 或 :ref:`Java <Java libraries>` 开发的静态测试库, 20 | - :ref:`动态API <dynamic libraries>` 测试库, 包括远程库, 21 | - :ref:`resource files` 22 | 23 | 此外, 还可以使用以前Libdoc创建的XML spec文件作为输入. 24 | 25 | 26 | 通常用法 27 | -------- 28 | 29 | .. Synopsis 30 | 31 | 总览 32 | ~~~~ 33 | 34 | :: 35 | 36 | python -m robot.libdoc [options] library_or_resource output_file 37 | python -m robot.libdoc [options] library_or_resource list|show|version [names] 38 | 39 | .. Options 40 | 41 | 选项 42 | ~~~~ 43 | 44 | -f, --format <html|xml> Specifies whether to generate HTML or XML output. 45 | If this options is not used, the format is got 46 | from the extension of the output file. 47 | -F, --docformat <robot|html|text|rest> 48 | Specifies the source documentation format. Possible 49 | values are Robot Framework's documentation format, 50 | HTML, plain text, and reStructuredText. Default value 51 | can be specified in test library source code and 52 | the initial default value is `robot`. 53 | New in Robot Framework 2.7.5. 54 | -N, --name <newname> Sets the name of the documented library or resource. 55 | -V, --version <newversion> Sets the version of the documented library or 56 | resource. The default value for test libraries is 57 | :ref:`got from the source code <specifying library version>`. 58 | -P, --pythonpath <path> Additional locations where to search for libraries 59 | and resources similarly as when :ref:`running tests <Using --pythonpath option>`. 60 | -E, --escape <what:with> Escapes characters which are problematic in console. 61 | `what` is the name of the character to escape 62 | and `with` is the string to escape it with. 63 | Available escapes are listed in the :option:`--help` 64 | output. 65 | -h, --help Prints this help. 66 | 67 | 68 | .. Alternative execution 69 | 70 | 其它执行方式 71 | ~~~~~~~~~~~~ 72 | 73 | 虽然上面的总览中只用Python来执行Libdoc, 但是还可以使用Jython和IronPython. 实际上, 要为Java库生成文档时, Jython是必需的. 74 | 75 | 上面Libdoc是作为一个安装模块(``python -m robot.libdoc``)来执行, 此外还可以作为脚本来执行:: 76 | 77 | python path/robot/libdoc.py [options] arguments 78 | 79 | 如果你是 :ref:`manual installation`, 或者只是把 :file:`robot` 目录拷贝到系统某个目录时, 按脚本执行就会非常有用. 80 | 81 | 82 | .. Specifying library or resource file 83 | 84 | 指定测试库或资源文件 85 | ~~~~~~~~~~~~~~~~~~~~ 86 | 87 | .. Python libraries and dynamic libraries with name or path 88 | 89 | Python库和动态库的名字或路径 90 | '''''''''''''''''''''''''''''''''''' 91 | 92 | 当测试库是用Python实现的, 或者使用了 :ref:`dynamic library API`, 那么可以通过库的名字或者库源码所在路径来指定. 当使用名字时, 将在 :ref:`module search path` 内搜索测试库, 并且格式必须和在Robot Framework的测试数据中一样. 93 | 94 | 如果测试库的导入需要参数, 这些参数必须跟在名字或路径的后面, 使用双冒号连接, 像 ``MyLibrary::arg1::arg2`` 这样. 如果参数的变化导致库中关键字变化, 或者是文档变化, 则最好使用 :option:`--name` 相应修改库的名字. (也就是说为不同参数生成不同名字的文档.) 95 | 96 | .. Java libraries with path 97 | 98 | Java库的路径 99 | ''''''''''''' 100 | 101 | 使用 :ref:`static library API` 实现的Java测试库可以指定源文件的路径, 此外, 当Libdoc运行时, 必须要能在 ``CLASSPATH``内找到 :file:`tools.jar` (Java JDK的一部分). 102 | 103 | 注意, 为Java测试库生成文档只能使用Jython. 104 | 105 | .. Resource files with path 106 | 107 | 资源文件的路径 108 | '''''''''''''' 109 | 110 | 资源文件必须总是通过路径指定. 如果路径不存在, 资源文件还是会像执行测试用例时一样, 尝试在 :ref:`module search path` 内进行搜索. 111 | 112 | .. Generating documentation 113 | 114 | 生成文档 115 | ~~~~~~~~ 116 | 117 | 当要生成HTML或XML格式的文档时, 输出文件必须作为第2参数指定, 跟在测试库/资源文件的名字或路径后面. 输出的格式将自动通过文件扩展名来判断, 也可以通过选项 :option:`--format` 设置. 118 | 119 | 一些例子:: 120 | 121 | python -m robot.libdoc OperatingSystem OperatingSystem.html 122 | python -m robot.libdoc --name MyLibrary Remote::http://10.0.0.42:8270 MyLibrary.xml 123 | python -m robot.libdoc test/resource.html doc/resource_doc.html 124 | jython -m robot.libdoc --version 1.0 MyJavaLibrary.java MyJavaLibrary.html 125 | jython -m robot.libdoc my.organization.DynamicJavaLibrary my.organization.DynamicJavaLibrary.xml 126 | 127 | .. Viewing information on console 128 | 129 | 在控制台查看信息 130 | ~~~~~~~~~~~~~~~ 131 | 132 | Libdoc有3个特别的命令在控制台显示信息. 这些命令被用来取代输出文件的名字, 并且它们也可以带上额外的参数. 133 | 134 | ``list`` 135 | 列出测试库或资源文件所包含的关键字列表. 可以传递表示模式的参数来过滤展示结果, 只有那些名字包含了给定模式的关键字才会列出来. 136 | ``show`` 137 | 显示测试库或资源文件的文档. 也可以传递表示名字的参数(可以是多个). 名字匹配上的关键字才会展示. 特殊参数值 `intro` 可用来只显示测试库的介绍(introduction)和导入章节. 138 | ``version`` 139 | 显示测试的版本. 140 | 141 | ``list`` 和 ``show`` 命令支持的可选名字模式都是大小写和空格无关的, 并且都支持使用 ``*`` 和 ``?`` 作为通配符. 142 | 143 | 例如:: 144 | 145 | python -m robot.libdoc Dialogs list 146 | python -m robot.libdoc Selenium2Library list browser 147 | python -m robot.libdoc Remote::10.0.0.42:8270 show 148 | python -m robot.libdoc Dialogs show PauseExecution execute* 149 | python -m robot.libdoc Selenium2Library show intro 150 | python -m robot.libdoc Selenium2Library version 151 | 152 | .. Writing documentation 153 | 154 | 编写文档 155 | -------- 156 | 157 | 本章讨论如何为基于 :ref:`Python <Python libraries>` 和 :ref:`Java <Java libraries>` 的测试库(静态和动态)和 :ref:`资源文件 <resource file documentation>` 编写文档. 158 | 159 | :ref:`Creating test libraries` 和 :ref:`resource files` 的更多细节在本手册其它章节讨论. 160 | 161 | 162 | .. _Python libraries: 163 | 164 | Python测试库 165 | ~~~~~~~~~~~~~ 166 | 167 | 使用 :ref:`static library API` 的Python测试库的文档就是实现关键字的类或模块或方法的文档字符串. 文档的第一行被视作关键字的简短介绍(例如, 可以是某个工具提示的链接), 所以要求尽可能有概括性, 不要太长. 168 | 169 | 下面这个简单的例子展示了通常文档是怎么写的, 本章最后还有一个 :ref:`略长的例子 <Libdoc example>`. 170 | 171 | .. sourcecode:: python 172 | 173 | class ExampleLib: 174 | """Library for demo purposes. 175 | 176 | This library is only used in an example and it doesn't do anything useful. 177 | """ 178 | 179 | def my_keyword(self): 180 | """Does nothing.""" 181 | pass 182 | 183 | def your_keyword(self, arg): 184 | """Takes one argument and *does nothing* with it. 185 | 186 | Examples: 187 | | Your Keyword | xxx | 188 | | Your Keyword | yyy | 189 | """ 190 | pass 191 | 192 | .. tip:: 如果你要Python库的文档里使用non-ASCII字符(比如中文), 193 | 必须设置 `源码的encoding <http://www.python.org/dev/peps/pep-0263>`_ 为UTF-8, 或者以Unicode创建文档字符串. 194 | 195 | 关于Python文档字符串更多内容, 请参阅 `PEP-257`_. 196 | 197 | .. _PEP-257: http://www.python.org/dev/peps/pep-0257 198 | 199 | .. _Java libraries: 200 | 201 | Java测试库 202 | ~~~~~~~~~~~ 203 | 204 | 使用 :ref:`static library API` 的Java测试库的文档就是实现关键字的类或方法的 `文档注释 <http://en.wikipedia.org/wiki/Javadoc>`_. 205 | 206 | 此时Libdoc内部实际使用的是Javadoc工具, 因此才要求 :file:`tools.jar` 必须包含在 ``CLASSPATH``. 该jar文件是Java SDK的一部分, 应该可以在SDK安装路径的 :file:`bin` 目录下. 207 | 208 | 下面这个简单例子中的文档和上面的Python例子完全一样(功能也是一样的). 209 | 210 | .. sourcecode:: java 211 | 212 | /** 213 | * Library for demo purposes. 214 | * 215 | * This library is only used in an example and it doesn't do anything useful. 216 | */ 217 | public class ExampleLib { 218 | 219 | /** 220 | * Does nothing. 221 | */ 222 | public void myKeyword() { 223 | } 224 | 225 | /** 226 | * Takes one argument and *does nothing* with it. 227 | * 228 | * Examples: 229 | * | Your Keyword | xxx | 230 | * | Your Keyword | yyy | 231 | */ 232 | public void yourKeyword(String arg) { 233 | } 234 | } 235 | 236 | 237 | .. _dynamic libraries: 238 | 239 | 动态测试库 240 | ~~~~~~~~~~ 241 | 242 | 为了给动态测试库生成有意义的文档, 测试库必须使用 ``get_keyword_arguments`` 和 ``get_keyword_documentation`` 这两个方法返回关键字的参数名字和文档(方法名还可是camelCase命名 ``getKeywordArguments`` 和 ``getKeywordDocumentation``). 243 | 244 | 还可以为 ``get_keyword_documentation`` 设置两个特殊的属性 ``__intro__`` 和 ``__init__`` 来实现测试库的通用文档. 245 | 246 | 更多信息和示例请参见 :ref:`Dynamic library API` 章节. 247 | 248 | .. _importing section: 249 | 250 | 导入段落 251 | ~~~~~~~~ 252 | 253 | 文档中有一个单独的章节用来说明测试库是如何导入的, 这部分是基于库的初始化方法. 254 | 255 | 对Python库而言, 如果 ``__init__`` 方法除了 ``self`` 还有其它参数, 则方法的文档和参数都会展示. 对Java库来说, 如果有接受public的构造函数, 所有public构造函数都会展示. 256 | 257 | .. sourcecode:: python 258 | 259 | class TestLibrary: 260 | 261 | def __init__(self, mode='default') 262 | """Creates new TestLibrary. `mode` argument is used to determine mode.""" 263 | self.mode = mode 264 | 265 | def some_keyword(self, arg): 266 | """Does something based on given `arg`. 267 | 268 | What is done depends on the `mode` specified when `importing` the library. 269 | """ 270 | if self.mode == 'secret': 271 | # ... 272 | 273 | .. _Resource file documentation: 274 | 275 | 资源文件的文档 276 | ~~~~~~~~~~~~~~ 277 | 278 | 资源文件中的关键字可以使用 :setting:`[Documentation]` 来设置文档. 279 | 280 | 文档的第一行(直到 :ref:`implicit newline <Newlines in test data>` 或显式地 ``\n``)被视作关键字的简短介绍, 和测试库类似. 281 | 282 | 资源文件还可以在Setting表格中通过 :setting:`Documentation` 为整个资源文件设置文档. 283 | 284 | 资源文件还可能包含变量, 这些变量不会记入文档. 285 | 286 | .. sourcecode:: robotframework 287 | 288 | *** Settings *** 289 | Documentation Resource file for demo purposes. 290 | ... This resource is only used in an example and it doesn't do anything useful. 291 | 292 | *** Keywords *** 293 | My Keyword 294 | [Documentation] Does nothing 295 | No Operation 296 | 297 | Your Keyword 298 | [Arguments] ${arg} 299 | [Documentation] Takes one argument and *does nothing* with it. 300 | ... 301 | ... Examples: 302 | ... | Your Keyword | xxx | 303 | ... | Your Keyword | yyy | 304 | No Operation 305 | 306 | 307 | .. Documentation syntax 308 | 309 | 文档的语法 310 | ---------- 311 | 312 | Libdoc支持的文档语法包括Robot Framework自身的 :ref:`documentation syntax`, HTML, 纯文本和 reStructuredText_. 测试库文档的格式可以通过在 :ref:`测试库源码 <Specifying documentation format>` 中设置属性 ``ROBOT_LIBRARY_DOC_FORMAT`` 来指定, 也可以通过命令行选项 :option:`--docformat (-F)` 来指定. 这两种情况下, 对应上面4种类型的值分别是: ``ROBOT`` (默认值), ``HTML``, ``TEXT`` and ``reST``. 注意这些值是大小写无关的. 313 | 314 | Robot Framework自己的文档格式是默认的, 也是推荐使用的格式. 如果测试库代码是已存在并且已经包含了文档, 则其它的格式就会很有用. 315 | 316 | 其它格式是在 Robot Framework 2.7.5开始支持的. 317 | 318 | .. Robot Framework documentation syntax 319 | 320 | Robot Framework文档语法 321 | ~~~~~~~~~~~~~~~~~~~~~~~~ 322 | 323 | Robot Framework自己的 :ref:`documentation syntax` 中最最重要的特性就是使用 ``*bold*`` and ``_italic_``, 自定义链接, 自动转换URL, 创建表格, 以及使用竖线的格式化文本块(常用来展示例子). 如果文档篇幅略长, 则Robot Framework 2.7.5版本后开始支持的章节标题功能也很方便. 324 | 325 | 下面的例子展示了一些最重要的格式化功能. 注意, 由于这是默认的格式, 所以没有必要设置 `ROBOT_LIBRARY_DOC_FORMAT` 属性, 也无需在命令行指定格式. 326 | 327 | .. sourcecode:: python 328 | 329 | """Example library in Robot Framework format. 330 | 331 | - Formatting with *bold* and _italic_. 332 | - URLs like http://example.com are turned to links. 333 | - Custom links like [http://robotframework.org|Robot Framework] are supported. 334 | - Linking to `My Keyword` works. 335 | """ 336 | 337 | def my_keyword(): 338 | """Nothing more to see here.""" 339 | 340 | .. HTML documentation syntax 341 | 342 | HTML文档语法 343 | ~~~~~~~~~~~~~ 344 | 345 | 当使用HTML格式时, 基本上可以自由使用HTML的语法来创建文档. 主要的缺点是HTML的标记符号可读性不高, 所以源代码中的文档维护和阅读会比较困难. 346 | 347 | 以HTML写成的文档Libdoc不做转换和转义处理, 直接使用. 不过还支持一个特殊的语法用来 :ref:`链接到关键字 <linking to keywords>`, 格式如: ```My Keyword```. 348 | 349 | 下面的例子包含了前面例子中相同的格式. 这里必须要设定 ``ROBOT_LIBRARY_DOC_FORMAT`` 属性, 或者要在命令行中给定 ``--docformat HTML``. 350 | 351 | .. sourcecode:: python 352 | 353 | """Example library in HTML format. 354 | 355 | <ul> 356 | <li>Formatting with <b>bold</b> and <i>italic</i>. 357 | <li>URLs are not turned to links automatically. 358 | <li>Custom links like <a href="http://www.w3.org/html">HTML</a> are supported. 359 | <li>Linking to `My Keyword` works. 360 | </ul> 361 | """ 362 | ROBOT_LIBRARY_DOC_FORMAT = 'HTML' 363 | 364 | def my_keyword(): 365 | """Nothing more to see here.""" 366 | 367 | .. Plain text documentation syntax 368 | 369 | 纯文本文档语法 370 | ~~~~~~~~~~~~~~ 371 | 372 | 使用纯文本格式时, Libdoc基本上是照原来的样子使用. 换行和其它空格也保留, 除了缩进. HTML特殊字符 (``<>&``) 将转义处理. 唯一做的格式化操作是将URL转换为可点击的链接, 并且支持 :ref:`internal linking` 如 ```My Keyword```. 373 | 374 | 375 | .. sourcecode:: python 376 | 377 | """Example library in plain text format. 378 | 379 | - Formatting is not supported. 380 | - URLs like http://example.com are turned to links. 381 | - Custom links are not supported. 382 | - Linking to `My Keyword` works. 383 | """ 384 | ROBOT_LIBRARY_DOC_FORMAT = 'text' 385 | 386 | def my_keyword(): 387 | """Nothing more to see here""" 388 | 389 | .. reStructuredText documentation syntax 390 | 391 | reStructuredText文档语法 392 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | 394 | reStructuredText_ 是一个简单但是又很强大的标记语言, 被广泛用在Python项目的文档中(包括本用户手册). 使用该格式的最大限制是必须要安装 docutils_ 模块才能生成文档. 395 | 396 | 因为反引号(backtick)在reStructuredText中也有特殊意义, 所以要使用 `链接到关键字`_ 时, 必须要进行转义, 如: ``\`My Keyword\```. 397 | 398 | 399 | .. sourcecode:: python 400 | 401 | """Example library in reStructuredText format. 402 | 403 | - Formatting with **bold** and *italic*. 404 | - URLs like http://example.com are turned to links. 405 | - Custom links like reStructuredText__ are supported. 406 | - Linking to \`My Keyword\` works but requires backtics to be escaped. 407 | 408 | __ http://docutils.sourceforge.net 409 | """ 410 | ROBOT_LIBRARY_DOC_FORMAT = 'reST' 411 | 412 | def my_keyword(): 413 | """Nothing more to see here""" 414 | 415 | .. _internal linking: 416 | 417 | 内部链接 418 | -------- 419 | 420 | Libdoc支持在文档的不同部分生成关键字的内部链接. 使用反引号将目标的名字括起来即可, 例如 ```target```. 目标名字是大小写无关的, 支持哪些目标将在下面的章节介绍. 421 | 422 | 如果要链接的目标没有找到, Libdoc也不会报错或警告, 只是将文字设为斜体. 早期的时候, 曾经推荐使用这种方式来引用关键字的参数, 但是这有可能导致无意中创建了内部链接. 现在则推荐使用双反引号来标示参数, 例如 ````argument````. 使用单反引号而没有找到的链接目标的情况在未来的版本中有可能会以报错处理. 423 | 424 | 除了下面小节中的例子, 内部链接和参数格式化都将在本章结尾的 :ref:`长篇实例 <Libdoc example>` 中展示. 425 | 426 | 427 | .. _linking to keywords: 428 | 429 | 链接到关键字 430 | ~~~~~~~~~~~~ 431 | 432 | 测试库中所有的关键字都会自动创建链接目标, 可通过诸如 ```Keyword Name``` 的语法链接到. 下面的例子展示了两个关键字之间互相链接. 433 | 434 | 435 | .. sourcecode:: python 436 | 437 | def keyword(log_level="INFO"): 438 | """Does something and logs the output using the given level. 439 | 440 | Valid values for log level` are "INFO" (default) "DEBUG" and "TRACE". 441 | 442 | See also `Another Keyword`. 443 | """ 444 | # ... 445 | 446 | def another_keyword(argument, log_level="INFO"): 447 | """Does something with the given argument else and logs the output. 448 | 449 | See `Keyword` for information about valid log levels. 450 | """ 451 | # ... 452 | 453 | .. note:: 当使用 `reStructuredText文档语法`_ 时, 反引号必须要转义. 454 | 455 | .. Linking to automatic sections 456 | 457 | 链接到段落 458 | ~~~~~~~~~~ 459 | 460 | Libdoc生成的文档总是自动包含了几个段落, 包括库的概述, 关键字的快捷方式, 和实际关键字. 如果测试库导入还需参数, 则还有单独的一个 :ref:`importing section`. 461 | 462 | 所有这些段落都是可作为链接目标的, 目标名字参见下表. 如何使用参见下一节的示例. 463 | 464 | 465 | .. table:: Automatic section link targets 466 | :class: tabular 467 | 468 | ================ =========================================================== 469 | Section Target 470 | ================ =========================================================== 471 | Introduction ```introduction``` and ```library introduction``` 472 | Importing ```importing``` and ```library importing``` 473 | Shortcuts ```shortcuts``` (New in Robot Framework 2.7.5.) 474 | Keywords ```keywords``` (New in Robot Framework 2.7.5.) 475 | ================ =========================================================== 476 | 477 | .. Linking to custom sections 478 | 479 | 链接到自定义段落 480 | ~~~~~~~~~~~~~~~~ 481 | 482 | 从2.7.5版本开始, Robot Framework的 :ref:`documentation syntax` 开始支持自定义 :ref:`section titles`, 其中的标题自动创建为链接目标. 483 | 484 | 下面的例子展示了如何链接到自动段落和自定义段落. 485 | 486 | .. sourcecode:: python 487 | 488 | """Library for Libdoc demonstration purposes. 489 | 490 | This library does not do anything useful. 491 | 492 | = My section = 493 | 494 | We do have a custom section in the documentation, though. 495 | """ 496 | 497 | def keyword(): 498 | """Does nothing. 499 | 500 | See `introduction` for more information and `My section` to test how 501 | linking to custom sections works. 502 | """ 503 | pass 504 | 505 | .. note:: 链接到自定义段落只在使用 `Robot Framework文档语法`_ 时可用. 506 | 507 | .. note:: Robot Framework 2.8版本之前, 段落标题只有第一级标题可以链接. 508 | 509 | .. Representing arguments 510 | 511 | 表示参数 512 | -------- 513 | 514 | Libdoc自动处理关键字的参数, 测试库中方法的参数和资源文件中用户关键字的参数, 将这些参数单独一列展示. 用户关键字的参数将去除 ``${}`` 或 ``@{}``, 以使得这些参数不管是来自哪里看起来都一个样. 515 | 516 | 不管关键字是如何实现的, Libdoc都如同在Python中创建关键字那样的展示. 这个格式用下面的表格展示会更直接点. 517 | 518 | 519 | .. table:: How Libdoc represents arguments 520 | :class: tabular 521 | 522 | +--------------------+----------------------------+--------------------------+ 523 | | Arguments | Now represented | Examples | 524 | +====================+============================+==========================+ 525 | | No arguments | Empty column. | | 526 | +--------------------+----------------------------+--------------------------+ 527 | | One or more | List of strings containing | | ``one_argument`` | 528 | | argument | argument names. | | ``a1, a2, a3`` | 529 | +--------------------+----------------------------+--------------------------+ 530 | | Default values | Default values separated | | ``arg=default value`` | 531 | | for arguments | from names with ``=``. | | ``a, b=1, c=2`` | 532 | +--------------------+----------------------------+--------------------------+ 533 | | Variable number | Last (or second last with | | ``*varargs`` | 534 | | of arguments | kwargs) argument has ``*`` | | ``a, b=42, *rest`` | 535 | | (varargs) | before its name. | | 536 | +--------------------+----------------------------+--------------------------+ 537 | | Free keyword | Last arguments has | | ``**kwargs`` | 538 | | arguments (kwargs) | ``**`` before its name. | | ``a, b=42, **kws`` | 539 | | | | | ``*varargs, **kwargs`` | 540 | +--------------------+----------------------------+--------------------------+ 541 | 542 | 当要在文档中引用关键字的参数时, 推荐使用 :ref:`行内代码样式 <inline styles_>` 来表示, 例如 ````argument````. 543 | 544 | 545 | .. _Libdoc example: 546 | 547 | Libdoc示例 548 | ----------- 549 | 550 | 下面的例子比较完整的展示了如何使用 `文档格式化`_ 中最有用的功能, :ref:`internal linking` 等等. 551 | 552 | 点击 `这里 <../examples/LoggingLibrary.html>`_ 查看生成的文档是什么样. 553 | 554 | .. literalinclude:: LoggingLibrary.py 555 | 556 | 557 | 558 | 所有 `标准库`_ 都提供了由Libdoc生成的文档, 这些文档(以及源代码)都可作为更加真实的例子来参考学习. 559 | 560 | --------------------------------------------------------------------------------