一段时间以来,我的单元测试时间比预期的要长.我试图调试它几次没有太大的成功,因为延迟是在我的测试开始运行之前.这影响了我做任何远程接近测试驱动开发的能力(也许我的期望太高),所以我想看看我是否可以一劳永逸地解决这个问题.
运行测试时,测试开始和实际开始之间有70到80秒的延迟.例如,如果我为一个小模块运行测试(使用time python manage.py test myapp),我会得到
<... bunch of unimportant print messages I print from my settings>
Creating test database for alias 'default'...
......
----------------------------------------------------------------
Ran 6 tests in 2.161s
OK
Destroying test database for alias 'default'...
real 1m21.612s
user 1m17.170s
sys 0m1.400s
Run Code Online (Sandbox Code Playgroud)
大约1m18的1m:21之间
Creating test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)
和
.......
Run Code Online (Sandbox Code Playgroud)
线.换句话说,测试需要不到3秒,但数据库初始化似乎需要1:18分钟
我有大约30个应用程序,大多数有1到3个数据库模型,所以这应该给出项目大小的概念.我使用SQLite进行单元测试,并实现了一些建议的改进.我无法发布我的整个设置文件,但很高兴添加所需的任何信息.
我确实使用跑步者
from django.test.runner import DiscoverRunner
from django.conf import settings
class ExcludeAppsTestSuiteRunner(DiscoverRunner):
"""Override the default django 'test' command, exclude from testing
apps which we know …Run Code Online (Sandbox Code Playgroud) 使用Django的普通测试运行器,您可以深入研究在特定应用程序,TestCase的特定子类或TestCase的特定子类中的特定测试中运行测试.
例如:
./manage.py test myapp.MyTestCase.test_something
Run Code Online (Sandbox Code Playgroud)
但是,除了测试特定应用程序之外,django-nose似乎不支持任何其他内容.我如何复制最后两个行为?
我已经成功地安装和配置django-nose与coverage
问题是如果我只是运行覆盖./manage.py shell并退出该shell - 它显示我37%的代码覆盖率.我完全理解执行代码并不意味着测试代码.我唯一的问题是 - 现在怎么样?
我想象的是能够导入所有python模块并在执行任何测试之前"安顿下来",并直接与coverage"Ok,在这里开始计算到达代码"进行通信.
理想情况下,这可以通过nose在执行每个测试套件之前基本上重置"触摸"代码行来完成.
我不知道从哪里开始寻找/发展.我在网上搜索过,没有发现任何有成效的东西.任何帮助/指导将不胜感激.
PS
我尝试执行这样的事情:
DJANGO_SETTINGS_MODULE=app.settings_dev coverage run app/tests/gme_test.py
Run Code Online (Sandbox Code Playgroud)
它工作(显示1%的覆盖率)但我无法弄清楚如何为整个应用程序执行此操作
编辑:这是我的覆盖配置:
[run]
source = .
branch = False
timid = True
[report]
show_missing = False
include = *.py
omit =
tests.py
*_test.py
*_tests.py
*/site-packages/*
*/migrations/*
[html]
title = Code Coverage
directory = local_coverage_report
Run Code Online (Sandbox Code Playgroud) 我在测试目录中测试了Django应用程序:
my_project/apps/my_app/
??? __init__.py
??? tests
? ??? __init__.py
? ??? field_tests.py
? ??? storage_tests.py
??? urls.py
??? utils.py
??? views.py
Run Code Online (Sandbox Code Playgroud)
Django测试运行器要求我将一个suite()函数放在__init__.py我的应用程序的tests目录的文件中.该函数返回当我执行$ python manage.py test时将运行的测试用例
我安装了django-nose.当我尝试使用django-nose运行测试时,运行0测试:
$ python manage.py test <app_name>
Run Code Online (Sandbox Code Playgroud)
如果我直接指向测试模块,则运行测试:
$ python manage.py test my_project.apps.my_app.tests.storage_tests
Run Code Online (Sandbox Code Playgroud)
为什么django-nose的测试跑者没有找到我的测试?我必须做什么?
目前有一个项目配置为通过Django的管理命令运行覆盖,如下所示:
./manage.py test --with-coverage --cover-package=notify --cover-branches --cover-inclusive --cover-erase
Run Code Online (Sandbox Code Playgroud)
这会产生如下报告:
Name Stmts Miss Branch BrMiss Cover Missing
--------------------------------------------------------------------------
notify.decorators 4 1 0 0 75% 4
notify.handlers 6 1 2 0 88% 11
notify.notification_types 46 39 2 0 19% 8-55, 59, 62, 66
notify.notifications 51 51 0 0 0% 11-141
--------------------------------------------------------------------------
TOTAL 107 92 4 0 17%
Run Code Online (Sandbox Code Playgroud)
但是,这份报告存在问题.这是不对的.覆盖范围是标记线丢失,尽管它们确实被测试覆盖.例如,如果我通过nosetests而不是django的manage命令运行测试,我会得到以下正确的报告:
Name Stmts Miss Branch BrMiss Cover Missing
-----------------------------------------------------------------------------
notify.decorators 4 0 0 0 100%
notify.handlers 6 0 2 0 100%
notify.notification_types 46 …Run Code Online (Sandbox Code Playgroud) 我试图使用Django的鼻子在我目前的项目,但我无法弄清楚如何让鼻子跑我的测试.所以我开始了一个简单的Django 1.4.1项目来了解鼻子.但即使在这个简单的测试项目中,我也无法运行它.
在继续之前:我知道Stackoverflow上有很多类似的问题,比如这个问题:
但谷歌搜索后,阅读博客文章和StackOverflow答案我仍然无法运行.
pip install django django-nose nose.django-admin.py startproject djangonosetest.创建项目.manage.py startapp testapp编辑settings.py:
ENGINE为django.db.backends.sqlite3django_nose,testapp以INSTALLED_APPSTEST_RUNNER = 'django_nose.NoseTestSuiteRunner'.跑 manage.py test
但我得到的只是这个输出:
nosetests --verbosity 1
Creating test database for alias 'default'...
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)
但至少应该运行默认的测试用例.
当我运行python manage.py test djangonosetest.testapp.tests:SimpleTest它时,将运行测试.但是,如果我必须为每个测试文件执行此操作,那似乎有点矫枉过正.但它证明了测试可以运行.
当我跑manage.py test -v 3(高级别级别)时,这出现了:
nose.selector: INFO: /Users/Jens/Projects/Django/djangonosetest/djangonosetest/settings.py …Run Code Online (Sandbox Code Playgroud) 我试图在Djangos model.Manager()类上模拟一个链式调用.现在我想嘲笑values()和filter()方法.
为了测试我创建了一个小测试项目:
pip install django mock mock-django nose django-nosedjango-admin.py startproject mocktestmanage.py startapp mockmedjango_nose和mocktest.mockme以INSTALLED_APPS(settings.py)TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'到settings.py为了确保所有设置都正确,我跑了manage.py test.运行一个测试,Django在您创建应用程序时创建的标准测试.
我做的下一件事是创建一个非常简单的模型.
mockme/models.py
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=50)
Run Code Online (Sandbox Code Playgroud)
我做的下一件事是创建一个使用的简单函数MyModel.这是我想要稍后测试的功能.
mockme/functions.py
from models import MyModel
def chained_query():
return MyModel.objects.values('name').filter(name='Frank')
Run Code Online (Sandbox Code Playgroud)
这里没有什么特别的事情发生.该函数正在过滤MyModel对象以查找其中的所有实例name='Frank'.对values()的调用将返回一个ValuesQuerySet只包含所有找到的MyModel实例的name字段的内容.
mockme/tests.py
import mock
from django.test import TestCase
from mocktest.mockme.models import MyModel …Run Code Online (Sandbox Code Playgroud) 我有一个使用django-nose的django项目.我想在项目中添加django-celery.我使用单元测试.django-nose和django-celery都需要在settings.py文件中设置TEST_RUNNER.特别:
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
Run Code Online (Sandbox Code Playgroud)
对于django-nose和:
TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner'
Run Code Online (Sandbox Code Playgroud)
对于django-celery.
我应该如何处理这个以便我可以使用这两个包?
我的python应用程序测试是在远程服务器上使用命令执行的nosetests.我无法修改测试的启动方式,也无法为其添加选项.我有测试的Django应用程序,但测试不正常.
我的项目结构:
project
??? README.md
??? setup.py
??? mysite
? ??? blog
? ? ??? __init__.py
? ? ??? models.py
? ? ??? tests.py
| | ??? ...
? ??? db.sqlite3
? ??? manage.py
? ??? mysite
? ? ??? __init__.py
? ? ??? settings.py
| | ??? ...
Run Code Online (Sandbox Code Playgroud)
命令nosetests在project目录中执行.我想要正确运行tests.py哪个有2个Django测试用例.我尝试tests在项目根目录中创建目录并使用以下方法调用测试DiscoverRunner:
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
test_dir = os.path.dirname(os.path.dirname(__file__)) # one level up
sys.path.insert(0, os.path.join(test_dir, 'mysite'))
class ServerTest(unittest.TestCase):
def test_runtests(self):
django.setup() …Run Code Online (Sandbox Code Playgroud) 我遇到了一个奇怪的问题,似乎是由python单元测试如何管理它们的导入以及它与mock包的关系.这是一个django项目,使用django-nose/nose进行单元测试运行,并使用mock进行模拟.
我有一个使用mock的单元测试,单独运行时效果非常好(python manage.py test tests/test_code.py)
在test_code.py中:
from my.app.models.bookstore import create_from_proxy
class MockTestCase( TestCase ):
def setUp( self ):
self.patcher = patch( 'my.app.models.bookstore.BookProxy', autospec=True )
self.mock_proxy = self.patcher.start()
self.proxy_instance = self.mock_proxy.return_value
self.proxy_instance.json = json.loads(BOOK_JSON)
def tearDown( self ):
self.patcher.stop()
def test_mock_works( self ):
book_id = 55
v = create_from_proxy( book_id )
self.assertTrue( self.mock_proxy.called )
... more tests ...
Run Code Online (Sandbox Code Playgroud)
在bookstore.py里面:
from my.app.proxies import BookProxy
def create_from_proxy( self, id ):
proxy = BookProxy(id)
...
Run Code Online (Sandbox Code Playgroud)
但是,当我将此测试作为整个测试套件(python manage.py test)的一部分运行时,测试失败,因为bookstore.py代码没有得到注入的mock类,而是回退到BookProxy的实际代码.
因此,当所有测试一起运行时,似乎有一些有状态的事情发生,但我无法弄清楚是什么导致模拟注入失败.其他使用mock的单元测试似乎都是在他们自己之后进行清理(使用装饰器,上下文或我在这里展示的显式补丁对象方法).
之前有过类似的东西吗?
django ×10
django-nose ×10
python ×7
nose ×4
unit-testing ×3
celery ×1
django-orm ×1
mocking ×1
nosetests ×1
python-mock ×1
testing ×1