我有一个需要测试功能变量的灯具。使用内省并在函数名称空间/上下文中声明变量应该有效,如果函数级别的内省工作,就像模块级别一样,但每次运行代码时我最终都会使用None而不是字符串" Fancy Table& #34;
在灯具中,我将范围设置为'功能'然后通过getattr和request.function进行内省:
#conftest.py
@pytest.fixture(scope='function')
def table(request):
from data_setup import create_table
table_name = getattr(request.function, "table_name", None)
create_table(request, table_name)
我在测试函数中声明了变量table_name:
#test_file.py
class TestTable():
@pytest.mark.tags("table")
def test_create_table(self, test_db):
table_name = "Fancy Table"
current_page = TablePage(self.test_driver, test_db)
current_page.go_to_kitchen("Eva", "Evas Kitchen")
current_page.create_first_table(expected_table_name)
Validation.assert_equal(expected_table_name, current_page.get_name(), "Table had the wrong name!")
在模块级别上执行此操作已经起作用,但是在我尝试在功能级别上执行此操作时,夹具再次吐出无。我在功能级别上使用夹具内省是错误的吗?如果不是这样的话怎么用?
答案 0 :(得分:2)
函数变量是本地的,在函数返回后被销毁,它们不以任何方式绑定到函数对象......这就是Python的工作原理,与py.test
无关。
如果将table_name
局部变量明确地绑定到测试函数,那么您的示例将起作用,有效地使其比其通常的生命周期更长:
@pytest.mark.tags("table")
def test_create_table(self, test_db):
test_create_table.table_name = "Fancy Table"
另一方面,明确地将table_name
传递给TablePage
会不会更简单?它会更简单,更直接,更明确。 :)
答案 1 :(得分:0)
将本地变量显式绑定到测试函数导致我的IDE抱怨未解析的引用。我们需要知道还有什么可以使这项工作?
在给出的示例中,当我写test_create_table
时,print "Found %d objects: %s" % (len(objects), [x.value() for x in objects])
#-----------------------------CUTOFF FOR BAD ATTRIBUTE TYPE----------------------------
all_attributes = PyKCS11.CKA.keys()
# only use the integer values and not the strings like 'CKM_RSA_PKCS'
all_attributes = [e for e in all_attributes if isinstance(e, int)]
attributes = [
["CKA_ENCRYPT", PyKCS11.CKA_ENCRYPT],
["CKA_CLASS", PyKCS11.CKA_CLASS],
["CKA_DECRYPT", PyKCS11.CKA_DECRYPT],
["CKA_SIGN", PyKCS11.CKA_SIGN],
["CKA_VERIFY", PyKCS11.CKA_VERIFY],
["CKA_ID", PyKCS11.CKA_ID],
["CKA_MODULUS", PyKCS11.CKA_MODULUS],
["CKA_MODULUS", PyKCS11.CKA_MODULUS],
["CKA_MODULUS_BITS", PyKCS11.CKA_MODULUS_BITS],
["CKA_PUBLIC_EXPONENT", PyKCS11.CKA_PUBLIC_EXPONENT],
["CKA_PRIVATE_EXPONENT", PyKCS11.CKA_PRIVATE_EXPONENT],
]
for o in objects:
print
print (red + "==================== Object: %d ====================" + normal) % o.value()
attributes = session.getAttributeValue(o, all_attributes)
attrDict = dict(zip(all_attributes, attributes))
if attrDict[PyKCS11.CKA_CLASS] == PyKCS11.CKO_PRIVATE \
and attrDict[PyKCS11.CKA_KEY_TYPE] == PyKCS11.CKK_RSA:
m = attrDict[PyKCS11.CKA_MODULUS]
e = attrDict[PyKCS11.CKA_PUBLIC_EXPONENT]
if m and e:
mx = eval('0x%s' % ''.join(chr(c) for c in m).encode('hex'))
ex = eval('0x%s' % ''.join(chr(c) for c in e).encode('hex'))
if sign:
try:
toSign = "12345678901234567890" # 20 bytes, SHA1 digest
print "* Signing with object 0x%08X following data: %s" % (o.value(), toSign)
signature = session.sign(o, toSign)
s = ''.join(chr(c) for c in signature).encode('hex')
sx = eval('0x%s' % s)
print "Signature:"
print hexdump(''.join(map(chr, signature)), 16)
if m and e:
print "Verifying using following public key:"
print "Modulus:"
print hexdump(''.join(map(chr, m)), 16)
print "Exponent:"
print hexdump(''.join(map(chr, e)), 16)
decrypted = pow(sx, ex, mx) # RSA
print "Decrypted:"
d = hexx(decrypted).decode('hex')
print hexdump(d, 16)
if toSign == d[-20:]:
print "*** signature VERIFIED!\n"
else:
print "*** signature NOT VERIFIED; decrypted value:"
print hex(decrypted), "\n"
else:
print "Unable to verify signature: MODULUS/PUBLIC_EXP not found"
except:
print "Sign failed, exception:", str(sys.exc_info()[1])
if decrypt:
if m and e:
try:
toEncrypt = "12345678901234567890"
# note: PKCS1 BT2 padding should be random data,
# but this is just a test and we use 0xFF...
padded = "\x00\x02%s\x00%s" % ("\xFF" * (128 - (len(toEncrypt)) - 3), toEncrypt)
print "* Decrypting with 0x%08X following data: %s" % (o.value(), toEncrypt)
print "padded:\n", dump(padded, 16)
encrypted = pow(eval('0x%sL' % padded.encode('hex')), ex, mx) # RSA
encrypted1 = hexx(encrypted).decode('hex')
print "encrypted:\n", dump(encrypted1, 16)
decrypted = session.decrypt(o, encrypted1)
decrypted1 = ''.join(chr(i) for i in decrypted)
print "decrypted:\n", dump(decrypted1, 16)
if decrypted1 == toEncrypt:
print "decryption SUCCESSFULL!\n"
else:
print "decryption FAILED!\n"
except:
print "Decrypt failed, exception:", str(sys.exc_info()[1])
else:
print "ERROR: Private key don't have MODULUS/PUBLIC_EXP"
print "Dumping attributes:"
for q, a in zip(all_attributes, attributes):
if a == None:
# undefined (CKR_ATTRIBUTE_TYPE_INVALID) attribute
continue
if q == PyKCS11.CKA_CLASS:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKO[a], a)
elif q == PyKCS11.CKA_CERTIFICATE_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKC[a], a)
elif q == PyKCS11.CKA_KEY_TYPE:
print format_long % (PyKCS11.CKA[q], PyKCS11.CKK[a], a)
elif session.isBin(q):
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print dump(''.join(map(chr, a)), 16),
elif q == PyKCS11.CKA_SERIAL_NUMBER:
print format_binary % (PyKCS11.CKA[q], len(a))
if a:
print hexdump(a, 16),
else:
print format_normal % (PyKCS11.CKA[q], a)
部分是我的IDE抱怨的部分有一个未解析的引用。因此,鉴于我收到了Unresolved引用错误,如何成功显式绑定局部变量?
答案 2 :(得分:0)
出于某种原因,Bruno提供的解决方案对我不起作用。这就是我所做的
import inspect
@pytest.fixture(scope='function')
def custom_fixture(request):
sig = inspect.signature(request.function)
my_fixture_obj = None
if 'fixture_data' in sig.parameters:
fixture_data = sig.parameters['fixture_data'].default
my_fixture_obj = MyFixtureObject(fixture_data['data'])
yield my_fixture_obj
# cleanup my_fixture_obj
def test_sample1(custom_fixture, fixture_data = {'data': ['s1', 's2', 's3']}):
...
def test_sample2(custom_fixture, fixture_data = {'data': ['a1', 'a2', 'a3']}):
...