如何使用“discover”在我的“tests”目录中运行测试?

问题描述 投票:1回答:4

使用DJango / Python 3.7。我在这里阅读 - How do I run all Python unit tests in a directory?我可以使用“discover”命令在指定目录中查找测试。我想要一个“测试”文件夹,所以我创建了一个,然后运行

(venv) localhost:myproject davea$ python -m unittest discover tests
Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/__main__.py", line 18, in <module>
    main(module=None)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 100, in __init__
    self.parseArgs(argv)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 124, in parseArgs
    self._do_discovery(argv[2:])
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 244, in _do_discovery
    self.createTests(from_discovery=True, Loader=Loader)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/main.py", line 154, in createTests
    self.test = loader.discover(self.start, self.pattern, self.top)
  File "/usr/local/Cellar/python/3.7.2_2/Frameworks/Python.framework/Versions/3.7/lib/python3.7/unittest/loader.py", line 344, in discover
    raise ImportError('Start directory is not importable: %r' % start_dir)
ImportError: Start directory is not importable: 'tests'

这对我来说很奇怪,因为我有一个(空的)初始化文件...

(venv) localhost:myproject davea$ ls web/tests/
__init__.py  model_tests.py

我还需要做些什么才能识别我的测试目录?

编辑:以下是model_tests.py的内容......

from django.conf import settings
from django.test import TestCase
from django.core import management


def setup():
    print("setup")
    management.call_command('loaddata', 'test_data.yaml', verbosity=0)


def teardown():
    management.call_command('flush', verbosity=0, interactive=False)


class ModelTest(TestCase):

    # Verify we can correctly calculate the amount of taxes when we are working
    # with a state whose tax rates are defined in our test data
    def test_calculate_tax_rate_for_defined_state(self):
        state = "MN"
        income = 30000
        taxes = IndividualTaxBracket.objects.get_taxes_owed(state, income)
        print(taxes)
        self.assertTrue(taxes > 0, "Failed to calucate taxes owed properly.")
django python-3.x unit-testing testing
4个回答
0
投票

我认为你对discover命令有些困惑。根据文件。

Unittest支持简单的测试发现。为了与测试发现兼容,所有测试文件必须是可从项目的顶级目录导入的模块或包(包括命名空间包)(这意味着它们的文件名必须是有效的标识符)。

这意味着所有测试文件都必须可以从运行命令的目录(包含web目录的目录)导入。确保这一点,所有测试文件必须在有效的python包中(包含__init__.py的目录)。

其次,你运行命令python -m unittest discover tests这是错误的。您最后不必添加tests。 unittests with discover命令支持4个选项。你可以阅读更多关于它here

我有以下目录结构。

 web
    ├── __init__.py
    └── tests
        ├── __init__.py
        └── test_models.py

我正在按照命令运行。

python3 -m unittest discover

有以下结果。

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

0
投票

第一件事:拥有__init__.py并不罕见,因为__init__.py告诉python该目录是一个模块;它通常有一个空的__init__.py文件。我有同样的错误,并通过重命名我的目录.修复它。


0
投票

如果一个名为tests.py的文件作为tests模块的兄弟存在,那可能会导致提到的ImportError,并且删除test.py应该修复它。

如果仍未发现单元测试,则需要提出几个问题:

1)测试模块是否至少包含一个派生自django.test.TestCase的类?

2)在这种情况下,该类是否包含至少一个名称以“test_”开头的方法

请注意,包含单元测试的任何文件的名称都应以“test”开头。

所以model_test.py不起作用; is通常用于设置一些假模型,但单元测试应该驻留在其他地方。

您可以使用此管理命令发现并运行测试:

python manage.py test

要么

python manage.py test appname

使用python -m unittest discover有什么特别的原因吗?我认为这也可以,但是你必须手动引导django环境


0
投票

完成......

你已经知道形式here

您的测试和文件的名称必须与特定模式匹配才能被discover()发现。

但是你得到了这个错误:

“django.core.exceptions.ImproperlyConfigured:请求的设置,但未配置设置”

这意味着Django在运行测试时无法找到其设置。您可以使用环境变量告知在何处查找设置:

DJANGO_SETTINGS_MODULE='myproyect.settings' python3 -m unittest discover

参考:https://docs.djangoproject.com/en/2.2/topics/settings/#designating-the-settings

另一方面 ...

您应该运行Django测试

./manage.py tests

这将是search tests automatically using the same mechanism than discover(),因为你将运行Django命令,你将有一些好处直接运行Django测试。


@Nafees Anwar问:设置环境变量如何配置设置?

model_tests.py文件的最开头有from django.conf import settings行,在创建设置LazyObject实例时,Django将搜索该环境变量。阅读代码以获取更多详细信息。

我将在此处发布该代码的片段以供说明。

# django.conf module.
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"


class LazySettings(LazyObject):
    """
    A lazy proxy for either global Django settings or a custom settings object.
    The user can manually configure settings prior to using them. Otherwise,
    Django uses the settings module pointed to by DJANGO_SETTINGS_MODULE.
    """
    def _setup(self, name=None):
        """
        Load the settings module pointed to by the environment variable. This
        is used the first time we need any settings at all, if the user has not
        previously configured the settings manually.
        """
        settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
        if not settings_module:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
                % (desc, ENVIRONMENT_VARIABLE))

        self._wrapped = Settings(settings_module)

所以,如果你这样做:

from django.conf import settings

这个环境变量已经解决了,声明

settings.configure()

将与RuntimeError('Settings already configured.')失败

© www.soinside.com 2019 - 2024. All rights reserved.