为什么没有引发 ValueError?

Why is no ValueError raised?

提问人:Enter name here 提问时间:11/11/2023 更新时间:11/15/2023 访问量:67

问:

我目前正在处理 python 课程的作业,需要一些帮助。我写了以下函数:

def get_funcs(funcs: dict, file_name: str, table_name: str) -> None:
    '''
    Read the given *.csv file, store the data inside the database and store the functions in a dict
    
    Args:
        functions dict: Dictionary to store the functions object
        file_name str: The file name of the csv-file with file extension
        table_name str: The name of the SQL table
    '''    
    
    global update_database

    try:
        if file_name == "test.csv" or file_name == "test":
            raise ValueError("The function for the test data is not neccessary.")
        elif file_name != "train.csv" and file_name != "train" and file_name != "ideal.csv" and file_name != "ideal":
            raise ValueError("Given a completly wrong / empty file or a directorys.")
        
        # store the complete path to the file in a variable
        complete_path = os.path.join(dataset_dir, file_name)
        # check file to be correct
        file_extension = os.path.splitext(file_name)[1]
        if file_extension == "":
            print_log(MessageType.Warn, "get_funcs", "Missing file extension. Added "".csv"" automatically!")
            complete_path += ".csv"        
        if not os.path.exists(complete_path):
            raise FileNotFoundError()
        
        # read csv file and store it in a data frame
        data = pd.read_csv(complete_path, sep=",")
        print_log(MessageType.Info, "get_funcs", "Successfully read \"" + file_name + "\"!")
    except PermissionError as error:
        print_log(MessageType.Error, "get_funcs", "Cannot open the given csv file!")
        return
    except Exception as error:
        print_log(MessageType.Error, "get_funcs", error)
        return

部分任务是编写单元测试。所以我写了以下内容:

import main
import unittest

class UnitTestPythonTask(unittest.TestCase):
    def test_check_test_function(self):
        '''
        Checks the file validation of the given .csv files
        '''
        self.assertRaises(ValueError, main.get_funcs({}, "test.csv", "TestFunction"))

测试失败,因为未引发 ValueError。如果我设置一个断点并观察单个步骤,我可以看到 ValueError 被引发并被记录 ()。print_log

我试图设置尝试的外部......除了。。。阻止,没有运气。测试成功后,当我检查是否引发异常时,我添加了一个 addtionall,但 ValueError 除外。也没有运气。raise ValueError("Given a completly wrong / empty file or a directorys.")

谁能告诉我,为什么测试失败,尽管引发了 ValueError?

单元 单元测试 python-3.11

评论

2赞 Alexander 11/11/2023
因为你自己抓住了它except Exception as error
0赞 Enter name here 11/11/2023
是的,我也这么认为。但正如我所描述的,它试图将其设置在 try catch 块之外,因此它不会被捕获。没有运气..
0赞 MrBean Bremen 11/12/2023
应测试调用,而不是测试未在函数外部传播的实现详细信息的异常。print_log
0赞 Enter name here 11/12/2023
但是我怎么能确定,为什么被召唤呢?print_log
0赞 MrBean Bremen 11/12/2023
测试日志消息,即函数的用户获得的内容。

答:

0赞 ukBaz 11/12/2023 #1

函数中有一个广泛的异常,该异常捕获了调用 后从函数引发和返回的任何错误。这就是为什么您在测试中没有看到任何异常的原因。except Exception as error: Noneprint_log

在你的问题中,你还没有说什么,所以我实现了一个占位符,假设你正在打印到 .然后,测试应查找 上的输出内容。例如print_logstdoutstdout

from datetime import datetime
import io
import unittest.mock
import main


class UnitTestPythonTask(unittest.TestCase):
    @unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
    @unittest.mock.patch(
        "main.get_log_time", unittest.mock.MagicMock(return_value=datetime(1972, 1, 1))
    )
    def test_check_test_function(self, mock_stdout):
        """
        Checks the file validation for test.csv file
        """
        expected_output = ("MessageType.Error "
                           "- 1972-01-01 00:00:00 - get_funcs "
                           "- The function for the test data is not necessary.\n")
        main.get_funcs(funcs={}, file_name="test.csv", table_name="TestFunction")
        self.assertEqual(mock_stdout.getvalue(), expected_output)

    @unittest.mock.patch("sys.stdout", new_callable=io.StringIO)
    @unittest.mock.patch(
        "main.get_log_time", unittest.mock.MagicMock(return_value=datetime(1972, 1, 1))
    )
    def test_check_wrong_file(self, mock_stdout):
        """
        Checks the file validation for a bad .csv file
        """
        expected_output = ("MessageType.Error "
                           "- 1972-01-01 00:00:00 - get_funcs "
                           "- Given a completly wrong / empty file or a directory.\n")
        main.get_funcs(funcs={}, file_name="bad_file.csv", table_name="TestFunction")
        self.assertEqual(mock_stdout.getvalue(), expected_output)

        

作为参考,这是我所包含的:main.py

from datetime import datetime
from enum import Enum, auto
import os

dataset_dir = "/tmp"


class MessageType(Enum):
    Warn = auto()
    Error = auto()


def get_log_time():
    return datetime.now()


def print_log(msg_type, func, msg):
    print(f"{msg_type} - {get_log_time()} - {func} - {msg}")


def get_funcs(funcs: dict, file_name: str, table_name: str) -> None:
    """
    Read the given *.csv file, store the data inside the database and store the functions in a dict

    Args:
        functions dict: Dictionary to store the functions object
        file_name str: The file name of the csv-file with file extension
        table_name str: The name of the SQL table
    """
    global update_database

    try:
        if file_name == "test.csv" or file_name == "test":
            raise ValueError("The function for the test data is not necessary.")
        elif (
            file_name != "train.csv"
            and file_name != "train"
            and file_name != "ideal.csv"
            and file_name != "ideal"
        ):
            raise ValueError("Given a completly wrong / empty file or a directorys.")

        # store the complete path to the file in a variable
        complete_path = os.path.join(dataset_dir, file_name)
        # check file to be correct
        file_extension = os.path.splitext(file_name)[1]
        if file_extension == "":
            print_log(
                MessageType.Warn,
                "get_funcs",
                "Missing file extension. Added " ".csv" " automatically!",
            )
            complete_path += ".csv"
        if not os.path.exists(complete_path):
            raise FileNotFoundError()

        # read csv file and store it in a data frame
        data = pd.read_csv(complete_path, sep=",")
        print_log(
            MessageType.Info, "get_funcs", 'Successfully read "' + file_name + '"!'
        )
    except PermissionError as error:
        print_log(MessageType.Error, "get_funcs", "Cannot open the given csv file!")
        return
    except Exception as error:
        print_log(MessageType.Error, "get_funcs", error)
        return

评论

0赞 Enter name here 11/13/2023
谢谢你的回答。基本上是你的权利,我正在打印一个,但这包括一个时间戳。似乎,这不会删除时间戳。即使不是,如果我将其转换为字符串......你知道为什么吗?stdoutmock_stdout.getvalue()[20:]
0赞 ukBaz 11/15/2023
该命令应该有效,尽管很难知道您是否没有显示代码。您可以使用最小、可重现的示例来更新您的问题,以便其他人可以运行它。我已经更新了答案以模拟日志记录中给出的日期时间,以便可以测试完整的输出。
0赞 Enter name here 11/17/2023
该函数将颜色日志消息打印到控制台:。颜色取决于 ,这是一个枚举。更新后的代码出现错误:print_logget_log_time() + " " + method + " [" + msg_type.name + "]: " + str(msg)msg_typeAssertionError: '\x1b[31m01/01/1900 00:00:00 get_funcs [Er[65 chars]7m\n' != '1900-01-01 00:00:00 get_funcs [Error]: Gi[46 chars]ory.'
0赞 Enter name here 11/19/2023
我发现,问题出在格式上。我正在使用 colorama 包为输出着色。这导致字符串以一些字节开头。感谢您的帮助:D