You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python unittest重写__init__实例化类报参数数量错误排查

问题背景

实践简单测试驱动开发过程中,基于Python unittest框架编写多场景测试用例验证计算器程序逻辑,尝试通过重写测试类的__init__方法实例化被测Calculator类时,执行测试命令抛出报错,开发工具为Visual Studio Code,要求保留__init__方法实现实例化逻辑。

复现代码

测试文件 Calculator_tests.py

import unittest
import Calculator_steps as CalculatorClass

class TestCalculator(unittest.TestCase):
    
    def __init__(self):
        self.calculator = CalculatorClass.Calculator()  # 实例化被测Calculator类
    
    def test_DecimalValues(self):
        with self.assertRaises(Exception):
            self.calculator.addNumbers('3.55,8.76')
            
    def test_NonNumeric(self):
        with self.assertRaises(Exception):
            self.calculator.addNumbers('7,8,e')    
            
    def test_MoreThanThreeIntegers(self):
        with self.assertRaises(Exception):
            self.calculator.addNumbers('5,7,2,8')   
            
    def test_MoreThan100(self):
        with self.assertRaises(Exception):
            self.calculator.addNumbers('109,76,90')

被测逻辑文件 Calculator_steps.py

class Calculator:

    def addNumbers(self, numberlist):
        total = 0 
        if numberlist=="":
            numberlist ="0"
        numbers = numberlist.split(",")
        if len(numbers)>3:
            raise TypeError("Only three values can be entered")
        for i in range(len(numbers)):
            if int(numbers[i])>100:
                raise TypeError("Only values less than 100 is allowed")
            try:
                total = total +int(numbers[i])
            except ValueError:
                TypeError("Only integers can be entered")

        return total

执行报错信息

执行命令py -m unittest Calculator_tests.py后抛出核心错误:

TypeError: TestCalculator.__init__() takes 1 positional argument but 2 were given

完整报错栈:

PS C:\Users\mudit> py -m unittest Calculator_tests.py
Traceback (most recent call last):
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\__main__.py", line 18, in <module>
    main(module=None)
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\main.py", line 100, in __init__   
    self.parseArgs(argv)
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\main.py", line 147, in parseArgs
    self.createTests()
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\main.py", line 158, in createTests
    self.test = self.testLoader.loadTestsFromNames(self.testNames,
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\loader.py", line 220, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\loader.py", line 220, in <listcomp>
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\loader.py", line 191, in loadTestsFromName
    return self.loadTestsFromModule(obj)
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\loader.py", line 124, in loadTestsFromModule
    tests.append(self.loadTestsFromTestCase(obj))
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\loader.py", line 93, in loadTestsFromTestCase
    loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\suite.py", line 24, in __init__
    self.addTests(tests)
  File "C:\Users\mudit\AppData\Local\Programs\Python\Python310\lib\unittest\suite.py", line 57, in addTests
    for test in tests:
TypeError: TestCalculator.__init__() takes 1 positional argument but 2 were given
错误原因

unittest框架加载测试用例时,会为每个测试方法单独实例化一次测试类,实例化时自动传入当前待执行的测试方法名作为入参。重写的__init__方法仅定义了self参数,既未匹配父类构造方法的参数签名,也未调用父类初始化逻辑,参数传入时数量不匹配,直接抛出类型错误。

解决方案

保留__init__实例化的修复方式

如果必须通过__init__方法完成被测类实例化,需要修改__init__方法的参数签名,接收框架传入的方法名参数,同时通过super()调用父类unittest.TestCase的构造方法完成基础初始化,修改后的__init__代码如下:

def __init__(self, methodName='runTest'):
    super().__init__(methodName)
    self.calculator = CalculatorClass.Calculator()  # 实例化被测Calculator类

被测代码额外bug修复

修改完构造方法后测试仍会存在失败场景,原因是Calculator_steps.py中捕获非数字输入的ValueError时,仅创建了TypeError对象但没有使用raise抛出,需要修改对应代码:

try:
    total = total +int(numbers[i])
except ValueError:
    # 补充raise关键字抛出异常
    raise TypeError("Only integers can be entered")

框架推荐写法(更稳妥)

unittest框架原生提供了setUp()实例方法,会在每个测试方法执行前自动运行,专门用于测试前置资源初始化,不需要重写构造方法,还能保证每个测试方法使用全新的被测对象实例,避免测试用例之间的状态污染,写法如下:

class TestCalculator(unittest.TestCase):
    def setUp(self):
        self.calculator = CalculatorClass.Calculator()
    
    # 其余测试方法保持不变

内容的提问来源于stack exchange,提问作者JMB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:06:08