Python 2.7 UnitTest 在 运行 单个脚本文件时运行良好,但在 运行 Pycharm Run/Debug 配置中的文件夹时失败

Python 2.7 UnitTest works well when run the single script file, but it failed when run the folder in Pycharm Run/Debug Configurations

Python 2.7 unittest 在 运行 单个脚本文件时运行良好,但在 运行 Pycharm Run/Debug 配置中的文件夹时失败。

单元测试用例:

import unittest
import sys
import os
import time

from tests import test_config
from test_config import LOGGING_FILE_PATH, LOGGING_FILE_NAME


class LogTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        sys.modules["config"] = test_config
        from lib import log
        cls.log = log

def check_log(self, msg):
    try:
        fp = open(os.path.join(LOGGING_FILE_PATH, LOGGING_FILE_NAME))
    except IOError as e:
        raise e
    else:
        with fp:
            self.assertIn(msg, fp.read())

def tearDown(self):
    try:
        fp = open(os.path.join(LOGGING_FILE_PATH, LOGGING_FILE_NAME), 'w')
    except IOError as e:
        raise e
    else:
        with fp:
            fp.truncate()

def setUp(self):
    time.sleep(0)

@classmethod
def tearDownClass(cls):
    if os.path.isfile(os.path.join(LOGGING_FILE_PATH, LOGGING_FILE_NAME)):
        os.remove(os.path.join(LOGGING_FILE_PATH, LOGGING_FILE_NAME))

def test_log_debug(self):
    msg = 'test log debug'
    self.log.debug(msg)
    self.check_log(msg)

def test_log_info(self):
    msg = 'test log info'
    self.log.info(msg)
    self.check_log(msg)

def test_log_warning(self):
    msg = 'test log warning'
    self.log.warning(msg)
    self.check_log(msg)

def test_log_error(self):
    msg = 'test log error'
    self.log.error(msg, exc_info=False)
    self.check_log(msg)

def test_log_critical(self):
    msg = 'test log critical'
    self.log.critical(msg)
    self.check_log(msg)


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

当我在 'Jetbrains Pycharm Run/Debug Configurations' 中设置 Python 测试脚本时,这很有效。所有 5 个测试都通过了。

但是当我在 'Run/Debug Configurations' 中设置 Python 测试文件夹时,其中包含上面的 'LogTestCase' 脚本。 5 次测试失败(全部 10 次测试。另外 5 次在另一个文件中)。

结果:

2016-02-20 23:08:59,901 - test_log.py:65:test_log_critical - CRITICAL - test log critical

2016-02-20 23:08:59,902 - log.py:136:error - ERROR - test log error

2016-02-20 23:08:59,903 - test_log.py:50:test_log_info - INFO - test log info

Error
Traceback (most recent call last):
  File "project_path/tests/test_log.py", line 66, in test_log_critical
    self.check_log(msg)
  File "project_path/tests/test_log.py", line 21, in check_log
    raise e
IOError: [Errno 2] No such file or directory: 'project_path/tests/test_log'


Failure
Expected :'test log debug'
Actual   :''
 <Click to see difference>

Traceback (most recent call last):
  File "project_path/tests/test_log.py", line 46, in test_log_debug
    self.check_log(msg)
  File "project_path/tests/test_log.py", line 24, in check_log
    self.assertIn(msg, fp.read())
AssertionError: 'test log debug' not found in ''


Failure
Expected :'test log error'
Actual   :''
 <Click to see difference>

Traceback (most recent call last):
  File "project_path/tests/test_log.py", line 61, in test_log_error
    self.check_log(msg)
  File "project_path/tests/test_log.py", line 24, in check_log
    self.assertIn(msg, fp.read())
AssertionError: 'test log error' not found in ''


Failure
Expected :'test log info'
Actual   :''
 <Click to see difference>

Traceback (most recent call last):
  File "project_path/tests/test_log.py", line 51, in test_log_info
    self.check_log(msg)
  File "project_path/tests/test_log.py", line 24, in check_log
    self.assertIn(msg, fp.read())
AssertionError: 'test log info' not found in ''


Failure
Expected :'test log warning'
Actual   :''
 <Click to see difference>

Traceback (most recent call last):
  File "project_path/tests/test_log.py", line 56, in test_log_warning
    self.check_log(msg)
  File "project_path/tests/test_log.py", line 24, in check_log
    self.assertIn(msg, fp.read())
AssertionError: 'test log warning' not found in ''

2016-02-20 23:08:59,903 - test_log.py:55:test_log_warning - WARNING - test log warning

Process finished with exit code 0

以上,谢谢。

我能猜到的是,在另一个测试中你又遇到了类似这样的事情

@classmethod
def setUpClass(cls):
    sys.modules["config"] = test_config
    from lib import log
    cls.log = log

当您 运行 单独进行测试时,您没有问题。但是当你 运行 像 pycharm 这样的测试套件中的所有这些都这样做时,第二个 from lib import log 没有效果(模块已经加载): log 我的模块可以猜到config模块得到的配置还是用之前测试配置的。

我的建议是查看 mock framework (available by pip in python 2.7) and its patch 方法:通过这种方式,您可以完全控制要应用 hack 更改的上下文。

您也可以尝试使用 reload 来解决这个问题,但是 我强烈反对您 如果您开始使用这些技巧,很难保持测试隔离你会遇到一些非常奇怪的行为。深入学习patch:你会喜欢的

[编辑]

如果不了解 log 如何使用 config,我无法通过真正的修复来真正回答您的问题。我只能猜测最好打补丁的地方是 log 模块,但是如何打补丁是不可能的。

  • config 模块使用什么日志?
  • 如何导入?

这里您真正需要的是以某种方式配置记录器并设置路径和文件名的方法。我想你可以通过在 log 模块中引入一个新函数或通过补丁来做到这一点,但细节确实扭曲了 log 模块代码。