Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用典型的测试目录结构运行unittest_Python_Unit Testing - Fatal编程技术网

Python 使用典型的测试目录结构运行unittest

Python 使用典型的测试目录结构运行unittest,python,unit-testing,Python,Unit Testing,对于一个简单的Python模块来说,最常见的目录结构似乎是将单元测试分离到它们自己的test目录中: new_project/ antigravity/ antigravity.py test/ test_antigravity.py setup.py etc. import sys, os testdir = os.path.dirname(__file__) srcdir = '../antigravity' sys.path

对于一个简单的Python模块来说,最常见的目录结构似乎是将单元测试分离到它们自己的
test
目录中:

new_project/
    antigravity/
        antigravity.py
    test/
        test_antigravity.py
    setup.py
    etc.
import sys, os
testdir = os.path.dirname(__file__)
srcdir = '../antigravity'
sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir)))

import antigravity
import unittest
new_project/
    src/
        antigravity.py
    test/
        test_antigravity.py
例如,请看这个

我的问题很简单,实际运行测试的通常方式是什么?我怀疑这对除我之外的所有人来说都是显而易见的,但是您不能从测试目录运行
python test\u antigravity.py
,因为它的
导入antigravity
将失败,因为模块不在路径上

我知道我可以修改PYTHONPATH和其他与搜索路径相关的技巧,但我不相信这是最简单的方法——如果你是开发人员,这很好,但如果你的用户只是想检查测试是否通过,那么期望他们使用它是不现实的

另一种选择是只将测试文件复制到另一个目录中,但这似乎有点愚蠢,并且忽略了将它们放在一个单独目录中的意义


那么,如果您刚刚将源代码下载到我的新项目中,您将如何运行单元测试?我希望有一个答案能让我告诉我的用户:“要运行单元测试,请执行X.”

使用
setup.py develope
使您的工作目录成为已安装Python环境的一部分,然后运行测试。

来自您链接到的文章:

创建一个test_modulename.py文件并 把你的单元测试放进去。自从 测试模块位于一个单独的模块中 目录,您可能需要 添加模块的父目录的步骤 到你的PYTHONPATH跑 他们:

最后,还有一个更受欢迎的例子 Python单元测试框架 (有那么重要!),鼻子。鼻子 有助于简化和扩展内置的 unittest框架(例如,它可以 例如,自动查找您的测试 编码并设置PYTHONPATH以用于 您),但它不包括在 标准Python发行版


也许您应该像它所建议的那样查看?

如果您运行“python setup.py develope”,那么包将位于路径中。但您可能不想这样做,因为您可能会感染系统python安装,这就是为什么像和这样的工具存在的原因

对于用户来说,最简单的解决方案是提供一个可执行脚本(
runtests.py
或类似的脚本),该脚本引导必要的测试环境,包括在需要时临时将根项目目录添加到
sys.path
。这不需要用户设置环境变量,类似这样的方法在引导脚本中可以很好地工作:

import sys, os

sys.path.insert(0, os.path.dirname(__file__))
然后,您对用户的说明可以简单到“
python runtests.py

当然,如果您真正需要的路径是
os.path.dirname(\uuu file\uuu)
,那么您根本不需要将它添加到
sys.path
;Python总是将当前运行脚本的目录放在
sys.path
的开头,因此根据目录结构的不同,只需将
runtests.py
定位在正确的位置即可


另外,(与Python2.6和更早版本一样进行后端口)现在已经内置了,因此如果您想要自动测试发现,就不再需要nose:您的用户指令可以简单到
Python-m unittest discover

我通常在项目目录中创建一个“运行测试”脚本(源目录和
test
)加载我的“所有测试”套件。这通常是样板代码,因此我可以在项目之间重用它

运行_tests.py:

import unittest
import test.all_tests
testSuite = test.all_tests.create_test_suite()
text_runner = unittest.TextTestRunner().run(testSuite)
测试/所有_tests.py(来自)


使用此设置,您确实可以在测试模块中包含反重力。缺点是您需要更多的支持代码来执行特定的测试…我每次都运行它们。

我遇到了相同的问题,有一个单独的单元测试文件夹。根据上述建议,我添加了绝对源代码路径
sys.path

以下解决方案的好处是,可以运行文件
test/test\u yourmodule.py
,而无需首先更改为test目录:

new_project/
    antigravity/
        antigravity.py
    test/
        test_antigravity.py
    setup.py
    etc.
import sys, os
testdir = os.path.dirname(__file__)
srcdir = '../antigravity'
sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir)))

import antigravity
import unittest
new_project/
    src/
        antigravity.py
    test/
        test_antigravity.py

您应该真正使用pip工具


使用
pip install-e.
在开发模式下安装软件包。这是pytest推荐的一种非常好的做法(请参阅他们的,您还可以在其中找到两种要遵循的项目布局).

我认为最好的解决方案是使用
unittest
,它将目录添加到
sys.path
,这样您就不必(在
TestLoader
类中完成)

例如,对于这样的目录结构:

new_project
├── antigravity.py
└── test_antigravity.py
new_project
├── antigravity
│   ├── __init__.py         # make it a package
│   └── antigravity.py
└── test
    ├── __init__.py         # also make test a package
    └── test_antigravity.py
您只需运行:

$ cd new_project
$ python -m unittest test_antigravity
对于类似您的目录结构:

new_project
├── antigravity
│   ├── __init__.py         # make it a package
│   └── antigravity.py
└── test
    ├── __init__.py         # also make test a package
    └── test_antigravity.py
测试
包内的测试模块中,您可以像往常一样导入
反重力
包及其模块:

# import the package
import antigravity

# import the antigravity module
from antigravity import antigravity

# or an object inside the antigravity module
from antigravity.antigravity import my_object
运行单个测试模块:

要运行单个测试模块,在本例中为
test\u antigravity.py

$ cd new_project
$ python -m unittest test.test_antigravity
$ cd new_project
$ python -m unittest test.test_antigravity
只需以导入测试模块的相同方式引用它

运行单个测试用例或测试方法:

您还可以运行单个
TestCase
或单个测试方法:

$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method
运行所有测试:

您还可以使用它来发现并运行所有测试,它们必须是名为
test*.py
的模块或包(可以使用
-p,--pattern
标志进行更改):


这将运行
测试
包中的所有
测试*.py
模块。

可以使用运行选定测试或所有测试的包装器

例如:

./run_tests antigravity/*.py
或者使用(
tests/***.py
)递归运行所有测试(通过
shopt-s globstar启用)

包装器基本上可以使用
argparse
解析参数,如:

parser = argparse.ArgumentParser()
parser.add_argument('files', nargs='*')
然后加载所有测试:

for filename in args.files:
    exec(open(filename).read())
然后将它们添加到测试套件中(使用
inspect
):

然后运行
"envFile": "${workspaceRoot}/.env",
ProjectName
 ├── project_name
 |    ├── models
 |    |    └── thing_1.py
 |    └── __main__.py
 └── test
      ├── models
      |    └── test_thing_1.py
      └── __main__.py
# ProjectName/test/models/__init__.py

from .test_thing_1 import Thing1TestCase        
# ProjectName/test/__main__.py

import sys
import unittest

sys.path.append('../project_name')

loader = unittest.TestLoader()
testSuite = loader.discover('test')
testRunner = unittest.TextTestRunner(verbosity=2)
testRunner.run(testSuite)
# ProjectName/test/models/test_thing_1.py    

import unittest
from project_name.models import Thing1  # this doesn't work without 'sys.path.append' per step 2 above

class Thing1TestCase(unittest.TestCase):

    def test_thing_1_init(self):
        thing_id = 'ABC'
        thing1 = Thing1(thing_id)
        self.assertEqual(thing_id, thing.id)
ProjectFolder:
 - project:
     - __init__.py
     - item.py
 - tests:
     - test_item.py
import unittest
import sys    

class ItemTest(unittest.TestCase):

    def setUp(self):
        sys.path.insert(0, "../project")
        from project import item
        # further setup using this import

    def test_item_props(self):
        # do my assertions

if __name__ == "__main__":
    unittest.main()
cd new_project

pytest test/test_antigravity.py
import antigravity

class TestAntigravity(unittest.TestCase):

    def test_something(self):

        # ... test stuff here


# if __name__ == '__main__':
# 
#     if __package__ is None:
# 
#         import something
#         sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
#         from .. import antigravity
# 
#     else:
# 
#         from .. import antigravity
# 
#     unittest.main()
python -m unittest discover -s ../test
setlocal & cd src & python -m unittest discover -s ../test
#!/bin/bash

this_program="$0"
dirname="`dirname $this_program`"
readlink="`readlink -e $dirname`"

python -m unittest discover -s "$readlink"/test -v
new_project
├── antigravity
│   ├── __init__.py         # make it a package
│   └── antigravity.py
└── test
    ├── __init__.py         # also make test a package
    └── test_antigravity.py
$ cd new_project
$ python -m unittest test.test_antigravity
$ python -m unittest test.test_antigravity.GravityTestCase
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
import unittest
try:
    import context
except ModuleNotFoundError:
    import test.context    
import antigravity
$ pwd
/projects/new_project
$ python -m unittest
$ cd test
$ python test_antigravity
/home/johndoe/snakeoil
└── test
    ├── __init__.py        
    └── frontend
        └── __init__.py
        └── test_foo.py
    └── backend
        └── __init__.py
        └── test_bar.py
python -m unittest discover -s /home/johndoe/snakeoil/test -t /home/johndoe/snakeoil
  -s START, --start-directory START
                        Directory to start discovery ('.' default)
  -t TOP, --top-level-directory TOP
                        Top level directory of project (defaults to start
                        directory)
new_project/
    src/
        antigravity.py
    test/
        test_antigravity.py
$ set PYTHONPATH=%PYTHONPATH%;%cd%\src
$ python -m unittest discover -s test
$ export PYTHONPATH=$PYTHONPATH:$(pwd)/src  [I think - please edit this answer if you are a Linux user and you know this]
$ python -m unittest discover -s test
import sys, os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
project_path
├── Makefile
├── src
│   ├── script_1.py
│   ├── script_2.py
│   └── script_3.py
└── tests
    ├── __init__.py
    ├── test_script_1.py
    ├── test_script_2.py
    └── test_script_3.py
import os
import sys
PROJECT_PATH = os.getcwd()
SOURCE_PATH = os.path.join(
    PROJECT_PATH,"src"
)
sys.path.append(SOURCE_PATH)
run_tests:
    python -m unittest discover .
python3 setup.py build
python3 setup.py develop --user