如何在单元测试中使用 argparse 参数调用函数?

Posted

技术标签:

【中文标题】如何在单元测试中使用 argparse 参数调用函数?【英文标题】:How to call function with argparse arguments in unittests? 【发布时间】:2021-04-29 09:15:10 【问题描述】:

请帮我编写单元测试:

我有一个带有一个函数的简单程序,当运行带有 argparse 参数 --double 的程序时,它只返回双倍的“name”。否则返回单个名称

    # code.py
    import argparse
    
    parser = argparse.ArgumentParser()
    parser.add_argument("name")
    parser.add_argument('-d', '--double', action="store_true")
    
    args = parser.parse_args()
    
    def double_name(new_name):
      if args.double:
        return new_name + new_name
      else:
        return new_name
    
    print(double_name(args.name))
    在cmd中运行python code.py test-name我有结果:test-name 在cmd中运行python code.py test-name -d我有结果:test-nametest-name

我想编写 unittest 来检查这个函数,但我不知道如何在单元测试中使用 argparse 参数调用这个函数

    # test_code.py
    import unittest
    import code
    
    class Test_Code(unittest.TestCase):
    
      def test_double_name(self):
        # without -d
        self.assertEqual(code.double_name('test-name'), 'test-name')
        # with -d
        self.assertEqual(code.double_name('test-name'), 'test-nametest-name')
    
    if __name__ == "__main__":
      unittest.main()

这个测试的run命令应该怎么看?如果我添加到代码:

    code.args = code.parser.parse_args(["test-name", "-d"])

标准命令python -m unittest test_code.py raise AttributeError

AttributeError: 'module' 对象没有属性 'py'

【问题讨论】:

【参考方案1】:

在函数外访问解析后的数据,把数据传入。那么数据从哪里来就无所谓了:

def double_name(new_name, double):
  if double:
    return new_name + new_name
  else:
    return new_name

print(double_name(args.name, args.double))

然后:

self.assertEqual(code.double_name('test-name', False), 'test-name')

【讨论】:

【参考方案2】:

你可以用你自己的参数列表调用parse_args,让它产生一个合适的值来使用。这需要稍微重写code 以避免在导入时调用parse_arg

# code.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("name")
parser.add_argument('-d', '--double', action="store_true")


def double_name(new_name):
  if args.double:
    return new_name + new_name
  else:
    return new_name


if __name__ == "__main__":
    args = parser.parse_args()
    print(double_name(args.name))

然后

# test_code.py
import unittest
import code


class Test_Code(unittest.TestCase):

  def test_double_name(self):
    code.args = code.parser.parse_args([])
    self.assertEqual(code.double_name('test-name'), 'test-name')

    code.args = code.parser.parse_args(["-d"])
    self.assertEqual(code.double_name('test-name'), 'test-nametest-name')


if __name__ == "__main__":
  unittest.main()

在您的测试函数中,您需要确保设置了code.args 的值,因为这是code.double_name 使用的变量。

【讨论】:

以上是关于如何在单元测试中使用 argparse 参数调用函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 argparse 中嵌套自定义参数解析器实例

如何运行单元测试来测试具有 argparse 属性的脚本?

如何测试我的代码是不是引发了适当的 argparse 异常?

如何在使用 argparse 的文件上使用指定的测试目录运行 pytest?

用于argparse的python单元测试

带有 argparse 的 Python 单元测试