自动化测试 RobotFramework自定义静态测试类库总结

news/2024/11/15 11:45:19/文章来源:https://www.cnblogs.com/shouke/p/18417792

实践环境

win11 家庭中文版

Python 3.9.13

robotframework6.1.1

说明:为了方便的使用robot命令,安装好robotframwork后,修改系统环境,添加robot.exe(PYTHON_HOME/Scripts/robot.exe)所在路径到系统环境变量path

安装参考连接:https://github.com/robotframework/robotframework/blob/master/INSTALL.rst

docutils-0.21.2-py3-none-any.whl

pip install docutils==0.21.2

robotframework-ride 2.0.8.1

创建测试类库

创建测试库类或者模块

可通过Python模块或者类实现测试类库

类库名称

当某个库被导入时库时使用的测试库的名称与实现它的模块或类的名称相同。例如,如果您有一个Python模块MyLibrary(即文件MyLibrary.py),它将创建一个名为MyLibrary的库。

Python类总是在模块内部。如果实现库的类的名称与模块的名称相同,则Robot Framework允许在导入库时省略类名。例如,MyLib.py文件中的类MyLib可以用作名为MyLib的库。这也适用于子模块,例如,如果parent.MyLib模块具有类MyLib,也可以仅使用parent.MyLib导入。如果模块名称和类名不同,则必须同时使用模块和类名,如mymodule.MyLibrary 或者parent.submodule.MyLib

建议:

如果类库名称比较长,推荐给类库取个简单的别名。

为类库设置别名

如果多个关键字具有相同的名称,则必须关键字名称前面加上库名称作前缀。库名称通常来自实现它的模块或类名,但在某些情况下需要更改它:

  1. 需要使用不同的参数多次导入同一个库。
  2. 库名称太长,不方便使用。
  3. 希望使用变量在不同的环境中导入不同的库,但使用相同的名称引用它们。
  4. 该库的名称具有误导性,或者在其他方面很差。在这种情况下,更改实际名称当然是更好的解决方案。

指定新名称的基本语法是在库名称后面加上文本AS(区分大小写),然后再加上新名称。指定的名称显示在日志中,当使用关键字的全名(LibraryName.Keyword name)时,必须在测试数据中使用。

*** Settings ***
Library    packagename.TestLib    AS    TestLib
Library    ${LIBRARY}    AS    MyName

使用不同参数多次导入相同类库

*** Settings ***
Library    SomeLibrary    localhost        1234    AS    LocalLib
Library    SomeLibrary    server.domain    8080    AS    RemoteLib*** Test Cases ***
ExampleLocalLib.Some Keyword     some arg       second argRemoteLib.Some Keyword    another arg    whateverLocalLib.Another Keyword

为类库提供参数

所有作为类实现的测试类库,都可以接收参数。在Setting部分,类库名称后面指定这些参数,当Robot Framework创建导入库的实例时,会将这些参数传递给其构造函数。如果作为模块实现的库不能接受任何参数,因此尝试为类库指定参数会导致错误。

类库所需的参数数量与类库的构造函数所接受的参数数量相同。默认值和可变数量的参数与关键字参数的工作方式类似。传递给库的参数以及库名称本身都可以使用变量来指定,因此可以通过命令行进行更改。

*** Settings ***
Library    MyLibrary     10.0.0.1    8080
Library    AnotherLib    ${VAR}

上述使用的类库实现

from example import Connectionclass MyLibrary:def __init__(self, host, port=80):self._conn = Connection(host, int(port))def send_message(self, message):self._conn.send(message)class AnotherLib:def __init__(self, environment):self.environment = environmentdef do_something(self):if self.environment == 'test':# do something in test environmentelse:# do something in other environments

类库作用范围

作为类实现的库可以具有内部状态,该状态可以通过关键字和传递给库构造函数的参数进行更改。因为状态会影响关键字的实际行为,所以确保一个测试用例中的更改不会意外影响其他测试用例是很重要的。这种依赖关系可能会产生难以调试的问题,例如,当添加新的测试用例时,它们不一致地使用库。
Robot Framework试图保持测试用例彼此独立:默认情况下,它为每个测试用例创建新的测试库实例。然而,这种行为并不总是可取的,因为有时测试用例应该能够共享一个公共状态。此外,所有库都没有状态时,根本不需要创建库的新实例。
测试库可以控制何时使用类属性ROBOT_IBRARY_SCOPE创建库。此属性必须是字符串,并且可以具有以下三个值:

  • TEST

    为每个测试用例创建一个新实例。套件setup和套件teardown共享另一个实例。在Robot Framework 3.2之前,此值为TEST CASE,但现在建议使用TEST。因为所有未识别的值都被认为与TEST相同,所以这两个值都适用于所有版本。出于同样的原因,如果库的目标用于RPA,而非测试时,也可以使用值TASK。如果未设置ROBOT_LIBRARY_COPE属性时,默认为TEST

  • SUITE

    将为每个测试套件创建一个新实例。从测试用例文件创建并包含测试用例的最低级别的测试套件都有自己的实例,而更高级别的套件都有各自的实例用于可能的setupteardown。在Robot Framework 3.2之前,此值为TEST SUITE。该值仍然有效,但建议将SUITE用于面向Robot Framework 3.2及更新版本的库。

  • GLOBAL

    在整个测试执行过程中只创建一个实例,它由所有测试用例和测试套件共享。从模块创建的库始终是全局的

注意:

如果使用不同的参数多次导入同一个库,则每次都会创建一个新的实例,忽略ROBOT_LIBRARY_COPE配置。

SUITEGLOBAL作用域与具有状态的库一起使用时,建议库使用一些特殊关键字来清除状态。例如,可以在套件setupteardown中使用此关键字,以确保下一个测试套件中的测试用例可以从已知状态开始。例如,SeleniumLibrary使用GLOBAL作用域可以在不同的测试用例中使用同一个浏览器,而无需重新打开它,而且它还具有Close All Browsers关键字,可以轻松关闭所有打开的浏览器。

使用SUITE作用域的示例类库:

class ExampleLibrary:ROBOT_LIBRARY_SCOPE = 'SUITE'def __init__(self):self._counter = 0def count(self):self._counter += 1print(self._counter)def clear_counter(self):self._counter = 0

类库版本

当使用测试库时,Robot Framework会尝试确定其版本。然后将这些信息写入syslog,以提供调试信息。库文档工具Libdoc也将这些信息写入它生成的关键字文档中。

从属性ROBOT_IBRARY_VERSION读取版本信息,类似于从ROBOT_LIBARY_som读取库作用范围。如果ROBOT_IBRARY_VERSION不存在,则尝试从__version__属性读取信息。这些属性必须是类或模块属性,这取决于库是作为类还是模块实现的。

使用__version__的示例模块:

__version__ = '0.1'def keyword():pass

创建关键字

什么方法被视为关键字

当使用静态库API时,Robot Framework使用反射来找出库类或模块实现了哪些关键字。默认情况下,它不包括以下划线开头的方法和函数所有未被忽略的方法和函数都被视为关键字。例如,下面的库实现了单个关键字My keyword

class MyLibrary:def my_keyword(self, arg):return self._helper_method(arg)def _helper_method(self, arg):return arg.upper()

限制public方法成为关键字

自动将所有公有方法和函数视为关键字通常效果良好,但有时候我们不期望这样。例如,当将库实现为类时,可能基类中的方法也被视为关键字,当将库实现为模块时, 当将库实现为模块时,导入到模块名称空间的函数也会自动成为关键字,这些可能不是我们想要的。

本节介绍如何防止方法和函数成为关键字。

基于类实现的类库

当库被实现为类时,可以通过将类属性ROBOT_AUTO_KEYWORDS 设置为False来告诉Robot Framework不要自动将方法暴露为关键字:

class Example:ROBOT_AUTO_KEYWORDS = False

ROBOT_AUTO_KEYWORDS属性被设置为False时,仅被使用@keyword 装饰器 显式修饰或以拥有robot_name属性的方法才会变成关键字。 @keyword 装饰器可以用于给关键字设置 自定义名称, 标签 和 参数类型 )。

from robot.api.deco import keywordclass Example:ROBOT_AUTO_KEYWORDS = False@keyworddef this_is_keyword(self):pass@keyword('This is keyword with custom name')def xxx(self):print('关键字: This is keyword with custom name')def this_is_not_keyword(self):pass

除了使用ROBOT_AUTO_KEYWORDS 属性,还可以使用更方便的 @library 装饰器来设置不要自动将方法暴露为关键字

from robot.api.deco import keyword, library@library
class Example:@keyworddef this_is_keyword(self):pass@keyword('This is keyword with custom name')def xxx(self):passdef this_is_not_keyword(self):pass

注意:

在ROBOT Framework 3.2中,使用ROBOT_AUTO_KEYWORDS 属性和 @library 装饰器来限制哪些方法成为关键字都是ROBOT Framework 3.2中新增的。
显式指定库实现的关键字的另一种方法是使用dynamic或者 hybrid 库api。

基于模块实现的类库

默认情况下,将库实现为模块时,模块命名空间中的所有函数都将成为关键字。对于导入的函数也是如此。例如,如果将以下模块用作类库,则它将包含关键字 Example Keyword,此外还包含关键字Current Thread

from threading import current_threaddef example_keyword():print('Running in thread "%s".' % current_thread().name)

避免导入的函数成为关键字的一个简单方法是只导入模块(例如import threading),并通过模块使用函数(例如threading.current_thread())或者,可以在导入时为函数提供一个以下划线开头的别名(例如from threading import current_thread as _current_thread

限制函数成为关键字的一种更明确的方法是使用模块级__all__属性,Python本身也将其用于类似的目的。如果使用它,则只有该属性列出的函数才可以成为关键字。例如,下面的库只实现了一个关键字Example Keyword

from threading import current_thread__all__ = ['example_keyword']def example_keyword():print('Running in thread "%s".' % current_thread().name)def this_is_not_keyword():pass

如果类库很大,那么在添加、删除或重命名关键字时维护__all__属性可能是一项艰巨的任务。显式标记哪些函数是关键字的另一种方法是使用ROBOT_AUTO_KEYWORDS 属性。当该属性设置为False值时,只有用 [@keyword装饰器显式修饰的函数才会成为关键字。例如,此库也仅实现一个关键字Example Keyword

from threading import current_threadfrom robot.api.deco import keywordROBOT_AUTO_KEYWORDS = False@keyword
def example_keyword():print('Running in thread "%s".' % current_thread().name)def this_is_not_keyword():pass

注意:

使用 ROBOT_AUTO_KEYWORDS 限制哪些函数成为关键字是ROBOT Framework 3.2中的一项新功能。

使用@not_keyword 装饰器

模块中的函数和类中的方法可以通过使用@not_keyword装饰器显式标记为非关键字。当一个库被实现为模块时,这个装饰器也可以用来避免导入的函数变成关键字。

from threading import current_threadfrom robot.api.deco import not_keywordnot_keyword(current_thread)    # Don't expose `current_thread` as a keyword.def example_keyword():print('Running in thread "%s".' % current_thread().name)@not_keyword
def this_is_not_keyword():pass

与使用@library装饰器禁用自动关键字发现或将ROBOT_AUTO_KEYWORDS设置为False值相比,使用@not_keyword装饰器是避免函数或方法成为关键字的完全相反的方法。使用哪一个取决于上下文。

注意:

@not_keyword 是ROBOT Framework 3.2中新增功能。

关键字名称

Similarly both the do_nothing and doNothing methods can be used as the Do Nothing keyword in the test data.

将测试数据中使用的关键字名称与方法名称进行比较,以找到实现这些关键字的方法。名称比较不区分大小写,并且会忽略空格和下划线。例如,方法hello映射到关键字名称Hellohello甚至h e l l o。类似地,do_nothingdoNothing方法都可以用作测试数据中的Do Nothing关键字。

示例库在MyLibrary.py文件中实现为模块:

def hello(name):print("Hello, %s!" % name)def do_nothing():pass

以下示例说明了如何使用上面的示例库。如果您想自己尝试,请确保库位于模块搜索路径.

*** Settings ***
Library    MyLibrary*** Test Cases ***
My TestDo NothingHello    world
设置自定义名称

可以为关键字暴露一个不同的名称,而不是映射到方法名称的默认关键字名称。这可以通过将方法上的robot_name属性设置为所需的自定义名称来实现

def login(username, password):print('login')login.robot_name = 'Login via user panel'
*** Test Cases ***
My TestLogin Via User Panel    ${username}    ${password}

相比上述显示设置robot_name 属性,通常最简单的是使用 @keyword 装饰器:

from robot.api.deco import keyword@keyword('Login via user panel')
def login(username, password):# ...

使用不带参数的该装饰器不会对暴露的关键字名称产生影响,但仍会设置robot_name属性。这允许标记方法为关键字,但不会真的更改关键字名称。即使方法名称本身以下划线开头,具有robot_name属性的方法也会创建关键字。

设置自定义关键字名称还可以使库关键字使用嵌入式参数 语法接收参数。

关键字标签(tag)

类库关键字和用户关键字 可以拥有标签。可以通过在方法上设置 robot_tags 属性来定义类库关键字的标签:

from robot.api.deco import keyword@keyword(tags=['tag1', 'tag2'])
def login(username, password):# ...@keyword('Custom name', ['tags', 'here'])
def another_example():# ...

Another option for setting tags is giving them on the last line of keyword documentation with Tags: prefix and separated by a comma. For example:

设置tag的另一个方法是在关键字文档的最后一行添加标签:Tags:打头,以逗号分隔的标签名称。

例如

def login(username, password):"""Log user in to SUT.Tags: tag1, tag2"""# ...

关键字参数

使用静态和混合(hybrid)API,可以直接从实现关键字的方法获得关键字需要多少个参数的信息。使用 动态库API (https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#dynamic-libraryapi)有其他方式来共享这些信息,因此本节与它们无关。

最常见也是最简单的情况是关键字需要确切数量的参数,在这种情况下,该方法只需接受这些参数。例如,一个实现不带参数的关键字方法也不接收参数,一个实现只带一个参数的关键字实现方法也接收一个参数,依此类推。

接收不同数量的参数的关键字示例

def no_arguments():print("Keyword got no arguments.")def one_argument(arg):print("Keyword got one argument '%s'." % arg)def three_arguments(a1, a2, a3):print("Keyword got three arguments '%s', '%s' and '%s'." % (a1, a2, a3))

关键字默认值

关键字使用的某些参数具有默认值,这通常很有用。

在Python中,一个方法总是只有一个实现,并且可能的默认值在方法定义中指定。下面展示了所有Python程序员都熟悉的语法

def one_default(arg='default'):print("Argument has value %s" % arg)def multiple_defaults(arg1, arg2='default 1', arg3='default 2'):print("Got arguments %s, %s and %s" % (arg1, arg2, arg3))

上面的第一个示例关键字可以与零个或一个参数一起使用。如果没有给定任何参数,arg将取默认值default。如果有一个参数,arg将获得该值,并且使用多个参数调用关键字将失败。在第二个示例中,始终需要一个参数,但第二个和第三个参数具有默认值,因此可以将关键字与一到三个参数一起使用。

*** Test Cases ***
DefaultsOne DefaultOne Default    argumentMultiple Defaults    required argMultiple Defaults    required arg    optionalMultiple Defaults    required arg    optional 1    optional 2

可变数量的参数 (*varargs)

Robot Framework还支持接受任意数量参数的关键字。
Python支持接受任意数量参数的方法。相同的语法在库中也有效,如下面的示例所示,它也可以与其他指定参数的方式组合使用:

def any_arguments(*args):print("Got arguments:")for arg in args:print(arg)def one_required(required, *others):print("Required: %s\nOthers:" % required)for arg in others:print(arg)def also_defaults(req, def1="default 1", def2="default 2", *rest):print(req, def1, def2, rest)
*** Test Cases ***
VarargsAny ArgumentsAny Arguments    argumentAny Arguments    arg 1    arg 2    arg 3    arg 4    arg 5One Required     required argOne Required     required arg    another arg    yet anotherAlso Defaults    requiredAlso Defaults    required    these two    have defaultsAlso Defaults    1    2    3    4    5    6

自由关键词参数(**kwargs)

Robot Framework支持Python的**kwargs语法。在本节中,我们将了解如何创建这样的关键字。
如以下示例显示了基本功能:

def example_keyword(**stuff):for name, value in stuff.items():print(name, value)
*** Test Cases ***
Keyword ArgumentsExample Keyword    hello=world        # Logs 'hello world'.Example Keyword    foo=1    bar=42    # Logs 'foo 1' and 'bar 42'.

通常,位于关键字最后的所有参数都使用命名语法规则name=value,并且与任何其他参数都不匹配的,将作为kwargs传递给关键字。为了避免使用像foo=quux这样的字面值作为自由关键字参数,必须对其进行转义比如foo\=quux

以下示例说明了普通位置参数、可变参数和关键词参数

def various_args(arg=None, *varargs, **kwargs):if arg is not None:print('arg:', arg)for value in varargs:print('vararg:', value)for name, value in sorted(kwargs.items()):print('kwarg:', name, value)*** Test Cases ***
PositionalVarious Args    hello    world                # Logs 'arg: hello' and 'vararg: world'.NamedVarious Args    arg=value                     # Logs 'arg: value'.KwargsVarious Args    a=1    b=2    c=3             # Logs 'kwarg: a 1', 'kwarg: b 2' and 'kwarg: c 3'.Various Args    c=3    a=1    b=2             # Same as above. Order does not matter.Positional and kwargsVarious Args    1    2    kw=3                # Logs 'arg: 1', 'vararg: 2' and 'kwarg: kw 3'.Named and kwargsVarious Args    arg=value      hello=world    # Logs 'arg: value' and 'kwarg: hello world'.Various Args    hello=world    arg=value      # Same as above. Order does not matter.

仅限关键词参数

从Robot Framework 3.1开始,可以对关键字使用仅命名参数。Python的仅关键字参数提供了这种支持。 仅关键字参数在的*varargs之后指定,或者在不需要*varargs时在专用的*标记之后指定。可能的**kwargs是在仅关键字参数之后指定的。

例子:

def sort_words(*words, case_sensitive=False):key = str.lower if case_sensitive else Nonereturn sorted(words, key=key)def strip_spaces(word, *, left=True, right=True):if left:word = word.lstrip()if right:word = word.rstrip()return word*** Test Cases ***
ExampleSort Words    Foo    bar    baZSort Words    Foo    bar    baZ    case_sensitive=TrueStrip Spaces    ${word}    left=False

仅限位置参数

Python支持所谓的仅限位置参数 ,这让指定指定某个参数智能作为位置参数提供,而非命名参数入 name=value。仅限位置参数在普通参数之前指定,并且在它们之后必须指定特殊的/标记

def keyword(posonly, /, normal):print(f"Got positional-only argument {posonly} and normal argument {normal}.")

可以这样使用上面的关键字:

*** Test Cases ***
Example# Positional-only and normal argument used as positional arguments.Keyword    foo    bar# Normal argument can also be named.Keyword    foo    normal=bar

如果仅限位置参数与包含等号的值(如example=usage)一起使用,则不被认为是命名参数语法,即使=之前的部分与参数名称匹配。此规则仅适用于仅限位置参数在其正确位置使用而没有其他参数在其前面使用名称参数语法的情况。

*** Test Cases ***
Example# Positional-only argument gets literal value `posonly=foo` in this case.Keyword    posonly=foo    normal=bar# This fails.Keyword    normal=bar    posonly=foo

从Robot Framework 4.0开始,完全支持仅限位置参数。将它们用作位置参数也适用于早期版本,但将它们用作命名参数会导致Python方面的错误。

......

更多详细信息请参考官方文档

参考连接

https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#creating-test-libraries

https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#setting-custom-name-to-library

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/798883.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Marvelous Designer基础操作2 - 制板编辑

Marvelous Designer基础操作,本篇涉及到具体的板片编辑、合并、分割、扩展等等,也包含添加洞、做省、加纽扣、拉链、明线等。​--本篇导航--板片绘制、编辑 缝线 省 内部线、打洞、做褶皱 折叠安排、假缝 扣子 拉链 明线操作可以配合这个视频看一下,注意快捷键。基础操作 双…

图解软件开发的八大模型

图解软件开发的八大模型

[rCore学习笔记 027]地址空间

写在前面 本随笔是非常菜的菜鸡写的。如有问题请及时提出。 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 引言 兜兜转转又是新的一章的开始,还是首先要看官方手册里的理论介绍和内容. 这里主要还是提纲挈领地摘抄里面的部分内容,在下面…

如何查找 18 个月之前的 Apple 订单 All In One

如何查找 18 个月之前的 Apple 订单 All In One 为什么 Apple Store 不支持查找 18 个月之前的订单?如何查找 18 个月之前的 Apple 订单 All In One为什么 Apple Store 不支持查找 18 个月之前的订单?errorssolutionsemail history ✅demos(🐞 反爬虫测试!打击盗版⚠️)…

编程日记 更改redis存储默认序列化器

编程日记 更改redis存储默认序列化器 package com.haole.usercenter.service;import com.haole.usercenter.model.domain.User; import jakarta.annotation.Resource; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframewor…

结对对对项目

结对对对项目这个作业属于哪个课程 软件工程课程这个作业要求在哪里 个人项目 - 作业 - 计科22级34班 - 班级博客 - 博客园 (cnblogs.com)这个作业的目标 按照要求写一个四则运算生成器成员一 3122004883许億驰任务列表1. 实现命令行程序:创建一个命令行程序,能够生成小学四则…

闯关提交02

任务:Python实现wordcount1 import re2 from collections import defaultdict3 4 def wordcount(text):5 # 将文本转换为小写6 text = text.lower()7 8 # 使用正则表达式分割单词9 words = re.findall(r\b\w+\b, text) 10 11 # 使用 defaultdict…

M:接口耗时很短,页面数据回显慢?

1、页面卡顿,需要好长一段时间才能加载完成,可能是资源请求过多,再加上请求响应慢的原因。 每个浏览器都有资源请求并发数的限制,如何查看请求阻塞情况 到前端如何针对该限制进行优化? 先看问题: 1、设置服务端请求耗时(3S)客户端并发调用20个请求。(预留问题-见下方:…

中秋 -2024/9/17

今天是中秋假期最后一天,今天主要学习了动态规划算法,写了几个模板题 新算法学了迪杰斯特拉(Dijkstra)算法,只是过程了解了过程,还是不能用代码描述出来 寻找最短路径的算法

干盛辉的第一次作业

这个作业属于哪个课程 https://edu.cnblogs.com/campus/zjlg/rjjc这个作业的目标 介绍自己并进行评估,阐明自己的技能、薄弱点,表明期望的课程收获以及课程实践角色扮演姓名-学号 干盛辉-2022329301011一、自我介绍 (1)个人信息 大家好,我叫干盛辉,来自于浙江温州,是 22…

vscode配置java简易教程

java的新手快速配置一、下载jdk java官方地址:https://www.oracle.com/java/technologies/downloads/ 选择适合自己电脑的版本,并下载到一个自己喜欢的地方。二、配置环境变量 记住自己 jdk 的地址,例:我的 jdk 下载到了 D:\app\java 1、JAVA_HOME配置 点击 win 键后,搜索…

GitHub 配置 ssh key 的步骤及原理解释

原文:Github 配置 ssh key 的步骤(大白话+包含原理解释)本文涉及 SSH 相关知识,建议先阅读 SSH 原理与运用(一):远程登录 或者将其作为扩展资料。 前言 在 GitHub 上配置 ssh key 很容易,网上一大堆教程,但基本没有详细解释其原理的,为什么要配?每使用一台主机都要配…