Python:unittest,AttributeError试图从已测试类的__init __

时间:2018-11-11 21:17:12

标签: python class python-unittest

具有带有unittest的类的问题测试属性。这是简单的例子

示例类:

class Company(object):
    def __init__(self, name):
        self.name = name

该类的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)

找不到问题所在-如何从name正确访问此__init__属性?


已编辑:

好吧,事实证明它可以通过以下方式解决:

  1. 将固定的name属性添加到Company方法中的SetUp

    def setUp(self):
        self.company = Company(name="NewestCompany")
    
  2. 添加具体实例作为company值:

    def setUp(self):
        self.company = firm
    

如此更新的问题-是否有任何方法可以定义SetUp,使其可以与实例一起使用,实例将取决于main中的用户?

1 个答案:

答案 0 :(得分:1)

self.company = Company(name="NewestCompany")中进行setUp是初始化每个测试的正确方法。 (因为它是在该类中的每个测试之前执行的。)

firm中创建if __name__ == "__main__":时,self.company = firm中的setUp将为所有测试引用相同的全局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是解决方案:

  
      
  1. 将固定的name属性添加到Company方法中的SetUp

    def setUp(self):
        self.company = Company(name="NewestCompany")
    
  2.   

这将为每个测试创建公司的新实例。


  

如此更新的问题-有什么方法可以定义SetUp,以便它可以与实例一起使用,而实例将取决于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)