Как вы решаете проблему передачи переменных между модулями/тестами

python
execution
unittest
Теги: #<Tag:0x00007fedc7adfd60> #<Tag:0x00007fedc7adfbf8> #<Tag:0x00007fedc7adfab8>

(Виталий Коряков) #1

Добрый день.
Как вы решаете проблему передачи переменных между модулями/тестами?
А именно, в одном тесте происходит магия.
Второй тест необходимо запустить с учетом некоторых переменных из теста 1.
Как это реализовывается?


(Mykhailo Poliarush) #2

Какой фреймворк для запуска тестов используешь?

Вот похожая тема когда-то была для #pytest в параллельном режиме


(Виталий Коряков) #3

Юниттест, и тесты запускаются последовательно.


(Mykhailo Poliarush) #4

Тогда мне кажется все очень просто, например вот так вот

import unittest


class SharedObject(object):
    _data = {}

    @classmethod
    def set(cls, **kw):
        cls._data.update(kw)

    @classmethod
    def get(cls, key):
        return cls._data.get(key)


class TestSomething(unittest.TestCase):
    def test1(self):
        SharedObject.set(a='a')

    def test2(self):
        print("test2 has {}".format(SharedObject.get('a')))
        SharedObject.set(b='b')

    def test3(self):
        print("test3 has {}".format(SharedObject.get('a')))
        print("test3 has {}".format(SharedObject.get('b')))


if __name__ == '__main__':
    unittest.main(verbosity=2)

(Виталий Коряков) #5

Забыл уточнить... а если тесты находятся в разных файлах...?


(Mykhailo Poliarush) #6

Выносишь SharedObject в отдельный модуль и постоянно импортируешь, а вообще можно просто использовать переменную в модуле для этого и не заморачиваться


(Mykhailo Poliarush) #7

shared.py

sharing_variables = {}

test.py

import unittest
from shared import sharing_variables


class TestSomething(unittest.TestCase):
    def test1(self):
        sharing_variables['a'] = 'a'

    def test2(self):
        print("test2 has {}".format(sharing_variables.get('a')))
        sharing_variables['b'] = 'b'

    def test3(self):
        print("test3 has {}".format(sharing_variables.get('a')))
        print("test3 has {}".format(sharing_variables.get('b')))


if __name__ == '__main__':
    unittest.main(verbosity=2)

ouput

test1 (__main__.TestSomething) ... ok
test2 (__main__.TestSomething) ... test2 has a
ok
test3 (__main__.TestSomething) ... test3 has a
test3 has b
ok

----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

***Repl Closed***

(Виталий Коряков) #8

Не, Миша, я не это имею в виду.
test.py и test2.py - это разные модули, и запускаются каждый отдельно.

примерно вот так

module_consts.py

var = ''

test1.py

import module_consts
module_consts.var = 'test1'

test2.py

import module_consts
print module_consts.var

Само собой, print module_consts.var отдаст пустую строку. А надо получить 'test1'


(Mykhailo Poliarush) #9

отдаст только если test2.py будет запущен после test1.py, а вообще твой код должен работать, ведь главный принцип что модуль импортируется один раз, а потом переиспользуется если был уже загружен


(Виталий Коряков) #10

именно так, запускается все последовательно, запускаем test1.py, затем test2.py, и получаю пустую строку.


(Виталий Коряков) #11

нашел ошибку.
В данном случае забыл импортнуть test1.py
должно выглядеть вот так:

test2.py

import module_consts
test1.py
print module_consts.var

В этом простом случае отдается нужная строка 'test1'.

Но проблема все равно остается при работе с классами, не понимаю как разрулить...
Расширим этот пример:

module_consts.py

var = ''

test1.py

import module_consts
class Test1(object):
    def test1(self):
        module_consts.var = 'test1'

test2.py

import module_consts
import test1
class Test2(object):
    def test2(self):
        print module_consts.var

тут тоже пустая строка... как получить test1?


(Mykhailo Poliarush) #12

Напишу логику как запускаются тесты


(Виталий Коряков) #13

import unittest

from test1 import Test1
from test2 import Test2


def suite():
    suite = unittest.TestSuite()
    suite.addTest(Test1('test1'))
    suite.addTest(Test2('test2'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner(failfast=True)
    runner.run(suite())

UPD: о, а ты знаешь, таким способом все ок, запускается и работает как надо со сьюта. Я их запускал по отдельности, потому ничего не работало.


(Mykhailo Poliarush) #14

Только что хотел написать, что все должно работать

module_consts.py

var = ''

test1.py

import module_consts
import unittest

class Test1(unittest.TestCase):
    def test1(self):
        module_consts.var = 'text in test1'

test2.py

import module_consts
import unittest


class Test2(unittest.TestCase):
    def test2(self):
        print module_consts.var

run.py

import unittest

from test1 import Test1
from test2 import Test2


def suite():
    suite = unittest.TestSuite()
    suite.addTest(Test1("test1"))
    suite.addTest(Test2("test2"))
    return suite


if __name__ == '__main__':
    runner = unittest.TextTestRunner(failfast=True, verbosity=2)
    runner.run(suite())

output

test1 (test1.Test1) ... ok
test2 (test2.Test2) ... text in test1
ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

***Repl Closed***

(Виталий Коряков) #15

Ага, спасибо, что привел к верному результату )))