如何对读取命令行参数的 class 进行单元测试?
How to unittest a class that reads a command line arg?
我想为 Python 脚本编写单元测试。脚本本身运行正确。
该脚本包含一个 class,它从命令行读取一个值到 class 变量。
当我将 class 导入我的测试文件时,我在 class 从 sys.argv[] 读取的位置收到错误 'list index out of range'。
我在 Python 和一般情况下是测试新手。在过去的几天里,我已经阅读了很多关于此的文档和 SO 页面。
代码如下:
文件bongo.py--
import sys
class Bongo:
my_int = int(sys.argv[1])
def __init__(self, n):
self.n = n
def get_sum(self):
return self.n + Bongo.my_int
if __name__ == '__main__':
bongo = Bongo(5)
m = bongo.get_sum()
print('bongo.get_sum() returns {}'.format(m))
文件bongo_test.py--
import unittest
from bongo import Bongo
class TestBongoMethods(unittest.TestCase):
def setUp(self):
self.bongo = Bongo(10)
self.bongo.my_int = 5
def test_get_n(self):
self.assertEqual(self.bongo.get_sum(), 15)
if __name__ == '__main__':
unittest.main()
运行python bongo_test.py
的输出是
Traceback (most recent call last):
File "bongo_test.py", line 2, in <module>
from bongo import Bongo
File "/home/me/class_for_testing/bongo.py", line 4, in <module>
class Bongo:
File "/home/me/class_for_testing/bongo.py", line 6, in Bongo
my_int = int(sys.argv[1])
IndexError: list index out of range
我已经尝试了所有我能想到的;我一直在 PyCharm Pro 2016.1 中使用 Py 2.7,
但是使用 Py 3.4 或从命令行 运行 结果没有什么不同。
这可以使用 unittest 完成吗?或者我还需要其他东西吗?
如有任何帮助,我们将不胜感激!
通常,单元测试有助于确定 classes 的边界。如果您的 class 难以进行单元测试,您应该考虑:"how can I make it easier to test?" 几乎总是这会导致结构更好的 classes.
这些症状之一是您有难以控制的外部依赖性,例如 sys.argv。通常,您希望将这样的依赖项注入 class。这是面向对象编程的优势之一——您可以隔离依赖关系并最大限度地降低对象本身的复杂性。
__main__
块非常适合命令行特定逻辑,例如 sys.argv。我建议读取那里的变量,并将其传递给 Bongo
的构造函数。然后,您可以将 Bongo 单元测试为带有两个变量的 class,并使其忽略 sys.argv.
对于命令行参数,我建议你使用 argparse 包(包含在普通 Python 中)
__main__
部分将包含主要方法的解析和调用。
您可以分别测试两者:
- arg 解析
- 具有给定参数的业务逻辑
我想为 Python 脚本编写单元测试。脚本本身运行正确。
该脚本包含一个 class,它从命令行读取一个值到 class 变量。
当我将 class 导入我的测试文件时,我在 class 从 sys.argv[] 读取的位置收到错误 'list index out of range'。
我在 Python 和一般情况下是测试新手。在过去的几天里,我已经阅读了很多关于此的文档和 SO 页面。
代码如下:
文件bongo.py--
import sys
class Bongo:
my_int = int(sys.argv[1])
def __init__(self, n):
self.n = n
def get_sum(self):
return self.n + Bongo.my_int
if __name__ == '__main__':
bongo = Bongo(5)
m = bongo.get_sum()
print('bongo.get_sum() returns {}'.format(m))
文件bongo_test.py--
import unittest
from bongo import Bongo
class TestBongoMethods(unittest.TestCase):
def setUp(self):
self.bongo = Bongo(10)
self.bongo.my_int = 5
def test_get_n(self):
self.assertEqual(self.bongo.get_sum(), 15)
if __name__ == '__main__':
unittest.main()
运行python bongo_test.py
的输出是
Traceback (most recent call last):
File "bongo_test.py", line 2, in <module>
from bongo import Bongo
File "/home/me/class_for_testing/bongo.py", line 4, in <module>
class Bongo:
File "/home/me/class_for_testing/bongo.py", line 6, in Bongo
my_int = int(sys.argv[1])
IndexError: list index out of range
我已经尝试了所有我能想到的;我一直在 PyCharm Pro 2016.1 中使用 Py 2.7, 但是使用 Py 3.4 或从命令行 运行 结果没有什么不同。
这可以使用 unittest 完成吗?或者我还需要其他东西吗?
如有任何帮助,我们将不胜感激!
通常,单元测试有助于确定 classes 的边界。如果您的 class 难以进行单元测试,您应该考虑:"how can I make it easier to test?" 几乎总是这会导致结构更好的 classes.
这些症状之一是您有难以控制的外部依赖性,例如 sys.argv。通常,您希望将这样的依赖项注入 class。这是面向对象编程的优势之一——您可以隔离依赖关系并最大限度地降低对象本身的复杂性。
__main__
块非常适合命令行特定逻辑,例如 sys.argv。我建议读取那里的变量,并将其传递给 Bongo
的构造函数。然后,您可以将 Bongo 单元测试为带有两个变量的 class,并使其忽略 sys.argv.
对于命令行参数,我建议你使用 argparse 包(包含在普通 Python 中)
__main__
部分将包含主要方法的解析和调用。
您可以分别测试两者:
- arg 解析
- 具有给定参数的业务逻辑