标签: python-unittest

单元测试模拟.补丁仅一次

我正在测试一个执行两次“requests.post”的函数。Si 我存根对此函数的调用。但是,我希望第一个存根返回一个假数据,第二个存根返回另一个假数据。怎么做 ?目前,我有:

@mock.patch('requests.post', side_effect=mocked_object)
def test_function_ok(self, mock_post):
    ...
Run Code Online (Sandbox Code Playgroud)

我想要这样的东西:

@mock.patch_once('requests.post', side_effect=mocked_1)
@mock.patch_once('requests.post', side_effect=mocked_2)
def test_function_ok(self, mock_post):
    ...
Run Code Online (Sandbox Code Playgroud)

python python-unittest

5
推荐指数
1
解决办法
2544
查看次数

vscode 中的 Python 单元测试调试

我想在运行单元测试模块时附加一个调试器。我似乎无法通过谷歌找到任何有关此的信息。有人有允许调试 python 测试运行程序的配置吗?另一个是我使用 discovery arg 来匹配我的测试模式。我不介意必须调试单个文件,但只要用一个配置来启动调试器就好了,每当我需要更改为不同的文件时,我不需要胡闹。

python -m unittest discover -p "*_test.py"

我尝试添加此配置

    {
      "name": "Python: Unittest",
      "type": "python",
      "request": "launch",
      "module": "unittest",
      "args": ["discover", "-p", "'*_test.py'"]
    },
Run Code Online (Sandbox Code Playgroud)

但我收到no matches found: '*_test.py'错误...

有人有想法吗?另一种调试单元测试运行程序的方法?

python debugging python-unittest visual-studio-code

5
推荐指数
1
解决办法
1万
查看次数

使用 signal.CTRL_C_EVENT 杀死子进程而不杀死主进程

如何在不杀死main 的情况下杀死子进程?

我有一个只能用 杀死的子进程signal.CTRL_C_EVENT。执行标准os.kill(my_pid, signal.CTRL_C_EVENT)会杀死进程,但也会导致我的 main 死掉,尽管有不同的 pid。

我的最终目标是从单元测试中创建子流程,因此我需要单元测试sys.exit(0)在通过所有测试后返回。

孩子.py

from time

while True:
  print "I am alive"
  time.sleep(0.5)
Run Code Online (Sandbox Code Playgroud)

父级.py

import os
import signal
import subprocess
import time

p = subprocess.Popen(["child.py"], shell=True)
time.sleep(5)
os.kill(p.pid, signal.CTRL_C_EVENT)

print("This line doesn't print because the main thread dies")
Run Code Online (Sandbox Code Playgroud)

::: 更新 :::

我正在尝试在 Windows 中运行它。去掉shell=True没有明显效果。我在parent.py 中看到 KeyboardInterrupt 错误

Traceback (most recent call last)    
    File "parent.py", line 23, in <module>
KeyboardInterrupt
Run Code Online (Sandbox Code Playgroud)

以下所有方法都会导致相同的行为

  • os.kill
  • 发送信号psutil.Process(os.getpid()).children()
  • subprocess.call(['taskkill', …

python python-unittest

5
推荐指数
1
解决办法
1819
查看次数

在 Python 中测试类的正确方法是什么?

有一个名为State具有多个属性的类,我需要为其编写单元测试。测试需要执行某些更改State实例属性值的操作。预期参数位于字典内部。单元测试将比较实例的属性State与字典的值是否相等。

问题是保存比较逻辑的最佳位置是什么?我在考虑两个选择:

  1. __eq__将方法添加到State包含比较逻辑的类。
  2. 在包含比较逻辑的测试模块内部添加辅助函数。

哪一个选项更好,为什么?

python testing unit-testing python-3.x python-unittest

5
推荐指数
1
解决办法
566
查看次数

使用“-s”和“-t”的 Python 单元测试会抛出断言错误:路径必须在项目内

我想为我的项目执行单元测试。在项目根目录中,我使用一个src文件夹来存放我的代码和一个tests文件夹来存放我的单元测试。这是我的项目结构:

\n
project/\n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src/\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 func.py\n|\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tests/\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 __init__.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 test.py\n
Run Code Online (Sandbox Code Playgroud)\n

内容func.py

\n
def func():\n    return True\n
Run Code Online (Sandbox Code Playgroud)\n

内容test.py

\n
import unittest\n\ntarget = __import__("func.py")\nfunc = target.func\n\nclass TestFunc(unittest.TestCase):\n    def test_func(self):\n        self.assertTrue(func())\n\nif __name__ == \'__main__\':\n    unittest.main()\n
Run Code Online (Sandbox Code Playgroud)\n

目前,我不想将我的代码作为模块提供。这就是为什么没有__init__.py内部src,我导入我的代码来测试__import__()

\n

如果我通过执行我的单元测试python -m unittest discover -s tests -t src,我会收到以下错误消息:

\n
PS C:\\Users\\username\\Desktop\\project> python -m unittest discover -s tests -t src\nTraceback (most recent call last):\n  File "C:\\Users\\username\\AppData\\Local\\Programs\\Python\\Python39\\lib\\runpy.py", line …
Run Code Online (Sandbox Code Playgroud)

python-3.x python-unittest

5
推荐指数
2
解决办法
1717
查看次数

Django 应用程序的 VScode unittest 测试发现设置

我有一个带有一些单元测试的 django 应用程序。我想在 VScode v.1.59.1 中运行\调试它们。

我的 ./vscode/settings.json 看起来像这样:

{
    "python.testing.unittestArgs": [
        "-v",
        "-s",
        "./routes/tests",
        "-p",
        "test*.py"
    ],
    "python.testing.pytestEnabled": false,
    "python.testing.nosetestsEnabled": false,
    "python.testing.unittestEnabled": true,
}
Run Code Online (Sandbox Code Playgroud)

当我尝试运行\发现测试时,我有以下输出:

ImportError: Failed to import test module: test_utils
...
django.core.exceptions.ImproperlyConfigured: Requested setting REST_FRAMEWORK, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Run Code Online (Sandbox Code Playgroud)

当我尝试使用命令以常规 django 方式运行测试时:

python manage.py test
Run Code Online (Sandbox Code Playgroud)

测试工作正常。

请帮助我设置 VScode 来运行 django 单元测试。

PS:我无法安装 pytest,这应该在不安装任何新模块的情况下完成。

django django-rest-framework python-unittest visual-studio-code

5
推荐指数
1
解决办法
488
查看次数

如何正确导入测试类以继承,而不将其作为测试运行

语境

我有一个测试类,我的所有测试都继承自该类。它无法自行运行,因为它实际上不包含任何设置信息

我想添加一个由所有测试执行的测试(将其添加到基类似乎合乎逻辑)

但现在我注意到我导入的 basetestclass( => Foo) 被检测为测试本身并运行并在报告中可见

代码

base.py 中的基类

from unittest import TestCase

class Foo(TestCase):
    @classmethod
    def setUpClass(cls):
        # prepare the generic setup stuff based on what is defined in the child class
        print("setupclass Foo done")

    def test_run_in_all_inherited_tests(self):
        print("fooBar")
        assert True
Run Code Online (Sandbox Code Playgroud)

真正的测试在 test_something.py

from base import Foo # <= This is being detected as a testclass object and thus will be executed

class TestFoo(Foo):
    @classmethod
    def setUpClass(cls):
        # define specific test setup
        super().setUpClass()
        print("setup TestFoo done")

    def test_pass(self): …
Run Code Online (Sandbox Code Playgroud)

python inheritance nose pytest python-unittest

5
推荐指数
1
解决办法
963
查看次数

如何让 python unittest 仅在失败的测试中显示日志消息

问题

我一直在尝试使用unittest --buffer标志来抑制成功测试的日志并显示失败测试的日志。但无论如何它似乎都会显示日志输出。这是日志记录模块的怪癖吗?如何仅在失败的测试中获取日志输出?记录器上是否需要特殊配置?我发现的其他问题和答案采用了暴力方法来禁用测试期间的所有日志记录。

示例代码

import logging
import unittest
import sys

logger = logging.getLogger('abc')

logging.basicConfig(
    format = '%(asctime)s %(module)s %(levelname)s: %(message)s',
    level = logging.INFO,
    stream = sys.stdout)


class TestABC(unittest.TestCase):
    def test_abc_pass(self):
        logger.info('log abc in pass')
        print('print abc in pass')
        self.assertTrue(True)

    def test_abc_fail(self):
        logger.info('log abc in fail')
        print('print abc in fail')
        self.assertTrue(False)
Run Code Online (Sandbox Code Playgroud)
测试输出
$ python -m unittest --buffer
2021-09-15 17:38:48,462 test INFO: log abc in fail
F
Stdout:
print abc in fail
2021-09-15 17:38:48,463 test INFO: log abc in pass …
Run Code Online (Sandbox Code Playgroud)

python python-unittest python-logging

5
推荐指数
1
解决办法
3551
查看次数

如何模拟导入模块中引用的环境变量?

我创建了一个包含环境变量的文件,并且正在为此文件编写测试。文件 ( "my_variables.py") 如下所示:

import os

if os.getenv("VCAP_APPLICATION"):
    foo = os.getenv("foo")
else:
    foo = "bar"
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我嘲笑环境变量的定义"VCAP_APPLICATION"。然后我断言 ifmy_variables.foo等于"foo"。事实并非如此,因为它等于"bar"

我认为导入模块时我的模拟变量没有被正确模拟。这就是为什么我在模拟变量后尝试导入模块的原因。我的测试如下所示:

import unittest
import os
from unittest.mock import patch

class MyTestCase(unittest.TestCase):

    @patch.dict(
        os.environ,
        { 
            "VCAP_APPLICATION": "True",
            "foo": "foo"
        }
    )
    def test_env_var(self):
        print(os.getenv("VCAP_APPLICATION")) # Returns True, so env var is mocked!
        import my_variables
        self.assertEqual(my_variables.foo, "foo") # Results in AssertionError
Run Code Online (Sandbox Code Playgroud)

断言相等会导致 AssertionError:

AssertionError: 'Bar' =! 'Foo'
Run Code Online (Sandbox Code Playgroud)

我首先在文件顶部导入。我现在在嘲笑之后放置它。如何模拟环境变量以便我导入的模块使用该环境变量?

python unit-testing python-unittest

5
推荐指数
1
解决办法
7866
查看次数

如何为 @task 装饰的 Airflow 任务编写单元测试?

我正在尝试为使用Airflow TaskFlow API构建的一些任务编写单元测试。我尝试了多种方法,例如,通过创建 dagrun 或仅运行任务函数,但没有任何帮助。

这是我从 S3 下载文件的任务,还有更多内容,但我在本示例中删除了它。

@task()
def updates_process(files):
    context = get_current_context()
    try:
        updates_file_path = utils.download_file_from_s3_bucket(files.get("updates_file"))
    except FileNotFoundError as e:
        log.error(e)
        return

    # Do something else
Run Code Online (Sandbox Code Playgroud)

现在我试图编写一个测试用例,我可以在其中检查这个 except 子句。以下是我开始的例子

class TestAccountLinkUpdatesProcess(TestCase):
    @mock.patch("dags.delta_load.updates.log")
    @mock.patch("dags.delta_load.updates.get_current_context")
    @mock.patch("dags.delta_load.updates.utils.download_file_from_s3_bucket")
    def test_file_not_found_error(self, download_file_from_s3_bucket, get_current_context, log):
        download_file_from_s3_bucket.side_effect = FileNotFoundError
        task = account_link_updates_process({"updates_file": "path/to/file.csv"})
        get_current_context.assert_called_once()
        log.error.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

我还尝试创建一个 dagrun(如文档中的示例所示)并从 dagrun 获取任务,但这也没有帮助。

python-unittest airflow airflow-taskflow

5
推荐指数
1
解决办法
1773
查看次数