Python: unittest, AttributeError 试图从 __init__ of tested class 访问 self 属性
Python: unittest, AttributeError trying to access self property from __init__ of tested class
使用 unittest 测试 class 的 属性 时遇到一些问题。这是一个简单的例子
示例class:
class Company(object):
def __init__(self, name):
self.name = name
这个 class 的 TestSuite 用一个简单的案例来检查它的 name
属性 值:
import unittest
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = Company
def tearDown(self):
del self.company
def test_company_name(self):
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
和main
模块:
if __name__ == "__main__":
firm = Company("NewestCompany")
print(firm.name)
unittest.main()
一共给出了主模块的执行结果:
NewestCompany
E
======================================================================
ERROR: test_company_name (__main__.CompanySuite)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/test/main 2.py", line 19, in test_company_name
self.assertEqual(check_name, self.company.name, "Name isn't correct")
AttributeError: type object 'Company' has no attribute 'name'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
找不到它的问题所在 - 如何从 __init__
正确访问此 name
属性?
已编辑:
好的,事实证明它可以通过以下方式修复:
将固定的name
属性添加到SetUp
方法中的Company
:
def setUp(self):
self.company = Company(name="NewestCompany")
添加具体实例作为 company
值:
def setUp(self):
self.company = firm
如此更新的问题 - 有什么方法可以定义 SetUp
以便它与实例一起工作,这将取决于 main 中的用户定义?
在 setUp
中执行 self.company = Company(name="NewestCompany")
是 正确的 初始化每个测试的方法。 (因为它是在 class 中的每个测试之前执行的。)
当您在 if __name__ == "__main__":
中创建 firm
时,setUp
中的 self.company = firm
将针对所有测试引用同一个全局 firm
实例。因此,如果您更改一个测试中的属性,它将影响其他测试中的该属性。例如,第二个测试 test_company_name_two
将失败:
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = firm # this is the global firm instance, created just once in main
def tearDown(self):
del self.company # this won't prevent the failure in test_company_name_two
# since it's the same `firm` instance in setUp()
def test_company_name(self):
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
self.company.name = "Newer Name" # changes the global `firm` instance
def test_company_name_two(self): # this will fail since company name is now "Newer Name"
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
您编辑中的选项 1 是解决方案:
Add fixed name
attribute to the Company
in SetUp
method:
def setUp(self):
self.company = Company(name="NewestCompany")
这会为每个测试创建一个公司的新实例。
So updated question - is there any way to define SetUp so it works with instances, that will be defined depend on the user in main?
是的,您编辑的第二个选项就是这样做的;但错误地。你想达到什么目的?如果您希望公司的名称或其他属性被全局定义,您总是可以将其作为全局或在 if-main 中,连同您希望在测试实例中通用的任何其他属性:
if __name__ == "__main__":
FIRM_NAME = "NewestCompany"
FIRM_OTHER_ATTR = "something else"
unittest.main()
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = Company(FIRM_NAME, other_attr=FIRM_OTHER_ATTR)
使用 unittest 测试 class 的 属性 时遇到一些问题。这是一个简单的例子
示例class:
class Company(object):
def __init__(self, name):
self.name = name
这个 class 的 TestSuite 用一个简单的案例来检查它的 name
属性 值:
import unittest
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = Company
def tearDown(self):
del self.company
def test_company_name(self):
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
和main
模块:
if __name__ == "__main__":
firm = Company("NewestCompany")
print(firm.name)
unittest.main()
一共给出了主模块的执行结果:
NewestCompany
E
======================================================================
ERROR: test_company_name (__main__.CompanySuite)
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:/test/main 2.py", line 19, in test_company_name
self.assertEqual(check_name, self.company.name, "Name isn't correct")
AttributeError: type object 'Company' has no attribute 'name'
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
找不到它的问题所在 - 如何从 __init__
正确访问此 name
属性?
已编辑:
好的,事实证明它可以通过以下方式修复:
将固定的
name
属性添加到SetUp
方法中的Company
:def setUp(self): self.company = Company(name="NewestCompany")
添加具体实例作为
company
值:def setUp(self): self.company = firm
如此更新的问题 - 有什么方法可以定义 SetUp
以便它与实例一起工作,这将取决于 main 中的用户定义?
在 setUp
中执行 self.company = Company(name="NewestCompany")
是 正确的 初始化每个测试的方法。 (因为它是在 class 中的每个测试之前执行的。)
当您在 if __name__ == "__main__":
中创建 firm
时,setUp
中的 self.company = firm
将针对所有测试引用同一个全局 firm
实例。因此,如果您更改一个测试中的属性,它将影响其他测试中的该属性。例如,第二个测试 test_company_name_two
将失败:
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = firm # this is the global firm instance, created just once in main
def tearDown(self):
del self.company # this won't prevent the failure in test_company_name_two
# since it's the same `firm` instance in setUp()
def test_company_name(self):
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
self.company.name = "Newer Name" # changes the global `firm` instance
def test_company_name_two(self): # this will fail since company name is now "Newer Name"
check_name = "NewestCompany"
self.assertEqual(check_name, self.company.name, "Name isn't correct")
您编辑中的选项 1 是解决方案:
Add fixed
name
attribute to theCompany
inSetUp
method:def setUp(self): self.company = Company(name="NewestCompany")
这会为每个测试创建一个公司的新实例。
So updated question - is there any way to define SetUp so it works with instances, that will be defined depend on the user in main?
是的,您编辑的第二个选项就是这样做的;但错误地。你想达到什么目的?如果您希望公司的名称或其他属性被全局定义,您总是可以将其作为全局或在 if-main 中,连同您希望在测试实例中通用的任何其他属性:
if __name__ == "__main__":
FIRM_NAME = "NewestCompany"
FIRM_OTHER_ATTR = "something else"
unittest.main()
class CompanySuite(unittest.TestCase):
def setUp(self):
self.company = Company(FIRM_NAME, other_attr=FIRM_OTHER_ATTR)