assertRaises(AttributeError,...)无法正常工作。模块“ myModule”没有属性“ main”(Python单元测试)

时间:2020-09-27 20:01:13

标签: python unit-testing python-unittest attributeerror

我是Python的新手。我的第一个单元测试无效。

这是我的telegram.py

#!/usr/bin/python3
import socket
import sys
import urllib.parse

import certifi
import pycurl
from io import BytesIO

# telegram API key and chat id
TELEGRAM_API_KEY = 'xxx'
TELEGRAM_CHAT_ID = 'xxx'

DEBUG_MODE: bool = False


# stuff to run always here such as class/def
def main(msg):
    if not msg:
        print("No message to be sent has been passed.")
        exit(1)

    def debug(debug_type, debug_msg):
        if DEBUG_MODE:
            print(f"debug({debug_type}): {debug_msg}")

    def send_message(message):
        print("sending telegram...")

        c = pycurl.Curl()

        if DEBUG_MODE:
            c.setopt(pycurl.VERBOSE, 1)
            c.setopt(pycurl.DEBUGFUNCTION, debug)

        params = {
            'chat_id': TELEGRAM_CHAT_ID,
            'text': message
        }

        telegram_url = f"https://api.telegram.org/bot{TELEGRAM_API_KEY}/sendMessage?" + urllib.parse.urlencode(params)
        c.setopt(pycurl.CAINFO, certifi.where())
        storage = BytesIO()
        c.setopt(c.WRITEDATA, storage)
        c.setopt(c.URL, telegram_url)
        c.perform()
        c.close()

        print(storage.getvalue())

    send_message(f"{socket.gethostname()}: {msg}")


if __name__ == "__main__":
    # stuff only to run when not called via 'import' here
    if len(sys.argv) > 1:
        main(sys.argv[1])
    else:
        print("No message to be sent has been passed.")
        exit(1)

我要测试此脚本。我可以直接使用命令行参数从shell调用此脚本,oder可以在其他Python脚本(如telegram.main("Test Message")中调用此脚本。

我的单元测试不起作用。我期望出现AttributeError,因为我没有给出telegram.main()的参数。

这是单元测试:

import unittest
import telegram
import subprocess


class TelegramTestCase(unittest.TestCase):
    """Tests for 'telegram.py'"""

    def test_empty_telegram(self):
        """call telegram directly without an argument"""
        self.assertRaises(AttributeError, telegram.main())

    def test_string_telegram(self):
        """call telegram directly with correct argument"""
        telegram.main("TästString...123*ß´´OK")
        self.assertTrue(True)

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

第一个测试用例的结果是:

错误回溯(最近一次通话最近):文件 “ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, 第60行,在testPartExecutor中 产生文件“ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, 676行,正在运行 self._callTestMethod(testMethod)文件“ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, _callTestMethod中的第633行 method()在test_empty_telegram中的第11行,文件“ G:\ Repositories \ python \ unittests \ telegram.py” self.assertRaises(AttributeError,telegram.main())AttributeError:模块“电报”没有属性“ main”

在0.003秒内进行了1次测试

失败(错误= 1)

以退出代码1完成的过程

这是什么问题?我认为找不到telegram.main()telegram.main("Test"),但为什么呢?

我想测试telegram.main(),并且声明AttributeError,因为我没有给出参数,因此应该通过测试。

谢谢。

更新:

我将第一种测试方法更改为

def test_empty_telegram(self):
    """call telegram directly without an argument"""
    with self.assertRaises(AttributeError):
        telegram.main()

,并且有效。但是以下测试方法具有相同的错误。

def test_string_telegram(self):
    """call telegram directly with correct argument"""
    with self.assertRaises(SystemExit) as cm:
        telegram.main("TästString...123*ß´´OK")
        self.assertEqual(cm.exception.code, 0)

输出:

测试于22:43开始... C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ python.exe C:\ Users \ XXX \ AppData \ Roaming \ JetBrains \ IntelliJIdea2020.2 \ plugins \ python \ helpers \ pycharm_jb_unittest_runner.py --target telegram.TelegramTestCase.test_string_telegram使用参数python -m unittest启动单元测试 电报.TelegramTestCase.test_string_telegram在 G:\ Repositories \ python \ unittests

错误回溯(最近一次通话最近):文件 “ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, 第60行,在testPartExecutor中 产生文件“ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, 676行,正在运行 self._callTestMethod(testMethod)文件“ C:\ Users \ XXX \ AppData \ Local \ Programs \ Python \ Python38-32 \ lib \ unittest \ case.py”, _callTestMethod中的第633行 method()在test_string_telegram中的第17行,文件“ G:\ Repositories \ python \ unittests \ telegram.py” telegram.main(“TästString... 123 * ß´´OK”)AttributeError:模块'telegram'没有属性'main'

在0.003秒内进行了1次测试

失败(错误= 1)

以退出代码1完成的过程

断言失败

断言失败

断言失败

更新2

问题是我将模块命名为telegram.py。测试文件在子文件夹中具有相同的名称。通过重命名测试文件可以解决该问题。感谢评论员的帮助!

0 个答案:

没有答案