在机器人框架中的 FOR 循环中导入库

Posted

技术标签:

【中文标题】在机器人框架中的 FOR 循环中导入库【英文标题】:Importing Library inside FOR loop in Robot Framework 【发布时间】:2020-11-15 18:14:15 【问题描述】:

我正在尝试为网站的消息传递功能编写测试。 在这个测试中,我使用了一个关键字,它应该遍历一个用户列表,找到每个用户的聊天窗口,然后导入一个用 Python 编写的自定义库,其中包含测试的通过/失败逻辑。自定义库应将消息发送者的订阅类型、接收消息的用户的订阅类型和初始发送的消息作为参数。

测试用例如下所示:

*** Settings ***
Variables   ../resources/usersToMessage.py
Variables  ../resources/messageSenders.py
Resource  ../chatTests/chatTests.resource

*** Test Cases ***

DemoTest
    [Documentation]     send messages to other users
    [tags]  demo
    [Template]  Log in as user and send messages
    FOR     $user     IN      @messageSenders
            $user
    END



*** Keywords ***
Log in as user and send messages
    [Arguments]     $testcase
    Send Messages

Send Messages
    $randomString=   generate string
    Set Global Variable  $SENT_MESSAGE  $randomString
    $arguments=      Create List     LogMany      conversationBox    $randomString
    Locate Conversations  $arguments       @usersToMessage


Locate Conversations
    [Arguments]   $arguments   @users
    FOR     $user     IN   @users
        Log Many      $user   @arguments
        Log     $user[username]
        Import Library     Services.ChatTestCase  BASIC  $user[subscription]    $SENT_MESSAGE
        $expected_chat_message=   expected chat message
        Log Many    the current user subscription is $user[subscription]  the expected chat message is $expected_chat_message
        Log     /messages/$user[userid]
        Log    $HOMEPAGE$messages$user[userid]
        Run Keyword     @arguments
    END




Send
    [Arguments]     $message
    Log     The random message is $message

ChatTestCase 库如下所示:

class ChatTestCase:


    ROBOT_LIBRARY_SCOPE = "TEST"

    unlimited_messaging_subscriptions = ("VIP","PREMIUMPLUS","PLATINUM","GOLD")

    def __init__(self, subscription_of_sender, subscription_of_receiver, sent_message):
        self.subscription_of_sender=subscription_of_sender.upper()
        self.subscription_of_receiver=subscription_of_receiver.upper()
        self.sent_message=sent_message
        self.should_deliver_message = True
        self.count = 0


    def expected_chat_message(self):
        self.count+=1
        print(f'no of expected_chat_message method passes is self.count')
        #print(f'value of variable should_deliver_message is self.should_deliver_message')
        if self.subscription_of_sender == "BASIC" and self.subscription_of_receiver not in self.unlimited_messaging_subscriptions:
            self.should_deliver_message = False
        elif self.subscription_of_receiver == "BASIC" and self.subscription_of_sender not in self.unlimited_messaging_subscriptions:
            self.should_deliver_message = False

        if self.should_deliver_message:
            print(f'value of variable should_deliver_message is self.should_deliver_message')
            return self.sent_message
        else:
            print(f'value of variable should_deliver_message is self.should_deliver_message')
            self.should_deliver_message = True
            return "CONTACT+"

问题在于,Import Library 关键字似乎只在第一次迭代中实例化 ChatTestCase 类一次。在 Robot Framework 文档中,它说如果使用不同的参数多次导入库,它将在 FOR 循环内为每次迭代实例化该类。

Robot Framework log

我尝试用虚拟库替换正在导入的自定义库,但发生了同样的事情

有人知道是否有任何方法可以从 FOR 循环中动态导入自定义库吗?

【问题讨论】:

尝试在循环中调用Reload Library - 我不知道会不会(还没有查看源代码),但感觉它可能会对您有所帮助。如果它不能完成这项工作,那么您可能会考虑在 py 类中实现工厂模式,以根据运行时值为您生成不同的对象类型。 您提到文档声明该库将被导入。你能链接到那个部分吗?据我所知,情况并非如此。 【参考方案1】:

你确定它应该被实例化多次吗?关键字Import Library 没有提到类似的东西。您已经在library scope 下的用户指南中阅读了它,但这并不意味着它甚至适用于关键字。

我发现这个解决方案充其量是笨拙的,但它可以按您的预期工作,即您在运行时在 for 循环中创建一个库的多个实例。

我的示例库:

from robot.api import logger


class TestLibrary(object):
    

    ROBOT_LIBRARY_VERSION = 1.0
    ROBOT_LIBRARY_SCOPE = 'TEST' 

    def __init__(self, num):
        self.count = 0
        self.num = num

    def log_params(self):          
        logger.console('count: 0 - num: 1'.format(self.count, self.num))
        self.count += 1

测试用例:

*** Test Cases ***
Library Imports
    FOR    $i    IN RANGE    1    5     
        $name=    Set Variable    Test$i   
        Import Library    $CURDIR/../../Libraries/TestLibrary.py    $i    WITH NAME    $name          
        Set Library Search Order    $name
        Log Params
    END

输出是:

count: 0 - num: 1
count: 0 - num: 2
count: 0 - num: 3
count: 0 - num: 4

这与您的情况不同,其中 self.count 在 for 循环的每次迭代中递增。

这里的关键是我为每个实例分配了一个不同的名称($name),并从最后创建的实例开始搜索关键字Log Params

【讨论】:

以上是关于在机器人框架中的 FOR 循环中导入库的主要内容,如果未能解决你的问题,请参考以下文章

如何使用python在机器人框架中导入和使用用户定义的类

机器人框架中的 Python 库文件

将 Xpath 转换为列表变量并使用 For 循环

Pycharm for Robot 框架中的自动完成

无法在机器人文件中导入 Selenium2Library

在机器人框架内找到元素变量中的 xpath