Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Повторная инициализация класса при импорте библиотеки и вызове метода в RF


(Natalia_scc) #1

Добрый день!
Возникла следующая ситуация:
в Robot Framework импортируется библиотека, написанная на Python. По сути, бибилиотека представляет из себя класс следующего вида:

class A(object):
def __init__ (self):
	действия-0
	
def method_1(self):
	действия-1

В RF, соответственно, обращение такое:

*** Settings ***
Library          А.py

*** Test Cases ***
rf_case
     method_1

И при выполнении данного теста происходит следующее:
при импорте библиотеки сразу вызывается экземпляр класса, выполняются действия из метода init,
а при вызове метода method_1 - создается еще один, новый экземпляр класса, в котором снова, само собой, происходит выполнение действий из метода init и затем - из метода method_1.

Можно ли как-то избежать повторной инициализации, т.е. чтобы в дальнейшем все методы работали именно с экземпляром класса, созданным при импорте?


(Dmitriy Zverev) #2

test.py

# -*- coding: utf-8 -*-
from robot.api import logger
class test:
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'
    def __init__ (self):
        logger.info ("===From init===")

    def method_1(self):
        print '===From method1==='

tst.txt

*** Settings ***
Library           test.py

*** Test Cases ***
case1
    test.method_1

tst.bat

SET ROBOT_SYSLOG_FILE=c:/syslog.log
SET ROBOT_SYSLOG_LEVEL=DEBUG
pybot --loglevel DEBUG:INFO --debugfile c:/dbg.log c:\tst.txt

syslog.log

20131016 16:32:19.570 | INFO  | Imported library 'Reserved' with arguments [ ] (version <unknown>, dynamic type, global scope, 10 keywords)
20131016 16:32:19.570 | INFO  | Imported test library module 'Easter' from 'c:\Python27\lib\site-packages\robot\libraries\Easter.pyc'.
20131016 16:32:19.571 | DEBUG | Created keyword 'None Shall Pass'
20131016 16:32:19.571 | INFO  | Imported library 'Easter' with arguments [ ] (version <unknown>, module type, global scope, 1 keywords)
20131016 16:32:19.572 | INFO  | Imported test library class 'c:\test.py' from 'c:\test.py'.
**20131016 16:32:19.573 | INFO  | ===From init===**
20131016 16:32:19.573 | DEBUG | Created keyword 'Method 1'
20131016 16:32:19.573 | INFO  | Imported library 'c:\test.py' with arguments [ ] (version <unknown>, class type, global scope, 1 keywords)
20131016 16:32:19.573 | INFO  | Started test suite 'Tst'
20131016 16:32:19.575 | INFO  | Started test case 'case1'
20131016 16:32:19.575 | DEBUG | Started keyword 'test.Method 1'
20131016 16:32:19.576 | DEBUG | Ended keyword 'test.Method 1'
20131016 16:32:19.576 | INFO  | Ended test case 'case1'
20131016 16:32:19.577 | INFO  | Ended test suite 'Tst'

dbg.log

==============================================================================
+ START SUITE: Tst [ ]
==============================================================================
+- START TEST: case1 [ ]
------------------------------------------------------------------------------
+-- START KW: test.Method 1 [ ]
===From method1===
+-- END KW: test.Method 1 (1)
------------------------------------------------------------------------------
+- END TEST: case1 (2)
------------------------------------------------------------------------------
+ END SUITE: Tst (31)
==============================================================================

Конструктор выполнился один раз


(Mykhailo Poliarush) #3

Ответ уже есть, я просто хочу показать альтернативу, где инициализация происходить всего один раз и переменная добавляется в глобальное пространство. Это больше хак, но все равно хочу рассказать.

Я использовал этот подоход, когда мне надо была переменная в виде объекта и нужно чтобы объект инициализировался всего лишь один раз для выполнения тестов. Для этого я использовал Import Variables.
Вот пример циклического выделения айдишников для тестов с одиночной инициализацией.

import random
from robot.api import logger

__all__ = ['generate_iccid']

class ICCIDProvider(object):
    _used_iccid = set()
    _iccid_list = {
        "89462046811000250243",
        "89462046811000250250",
        "89462046811000250268"
        #another 100 ids
    }

    def get(self):
        unused_iccid = self._iccid_list - self._used_iccid
        if not unused_iccid:
            self._used_iccid = set([])
            unused_iccid = self._iccid_list - self._used_iccid
        choosen_iccid = random.choice(list(unused_iccid))
        self._used_iccid.add(choosen_iccid)
        return choosen_iccid

generate_iccid = ICCIDProvider()

Сам ресурс с использованием этой переменной:

*** Settings ***
Resource          ../../project_keywords.txt

*** Keywords ***
Get Clean Up Iccid
    Import Variables    ${CURDIR}${/}iccid.py
    ${new_iccid}    Set Variable    ${generate_iccid.get()}