我最近开始尝试将一个令人尊敬的大型(> 100万行)程序进行测试.目前没有单元测试.此外,程序链接为每个单独的文件链接在一起 - 没有组件库.此外,对象是高度相互依赖的,并且很难(不可能?)链接到任何目标文件而不链接到它们中的至少一半.
是的,我知道,我的生活很糟糕.
我想做一些重构(显然),但我想在开始移动之前进行一些测试.我目前的想法是编译一个单独的"测试程序",它运行我创建的所有测试.这将大大简化我的链接问题,让我专注于真正的问题.所以我有两个问题:
如何跳过BOOST单元测试?我想以编程方式跳过我的一些单元测试,具体取决于(例如)我执行它们的平台.我目前的解决方案是:
#define REQUIRE_LINUX char * os_cpu = getenv("OS_CPU"); if ( os_cpu != "Linux-x86_64" ) return;
BOOST_AUTO_TEST_CASE(onlylinux) {
REQUIRE_LINUX
...
the rest of the test code.
}
Run Code Online (Sandbox Code Playgroud)
(请注意,我们的构建环境设置变量OS_CPU).这看起来很丑陋且容易出错,而且无声跳过也可能导致用户在不知情的情况下跳过测试.
如何基于任意逻辑干净地跳过升压单元测试?
我有一些Python单元测试,我发现并运行鼻子.我观察到setUpModule(),tearDownModule()和测试模块导入的奇怪排序.我有这个(示例)目录结构:
test1.py
test_dir/test2.py
Run Code Online (Sandbox Code Playgroud)
test1.py和test2.py都是这样的:
import sys
import unittest
def flushwrite(text):
sys.stdout.write(text + '\n')
sys.stdout.flush()
flushwrite("import %s" % __name__)
def setUpModule():
flushwrite("setUp %s" % __name__)
def tearDownModule():
flushwrite("tearDown %s" % __name__)
class Test(unittest.TestCase):
def test1(self):
flushwrite("running %s.test1" % __name__)
Run Code Online (Sandbox Code Playgroud)
当我跑步时nosetests -s test1.py test_dir/test2.py
,我看到了这个序列:
这是我期望/渴望的.当我运行nosetests -s test1.py test_dir
(使用测试发现来查找test2.py)时,我看到了这个序列:
请注意,test1的tearDown在test2的测试后执行.这意味着当test2运行时系统不处于干净状态!显然,在从大型目录树发现的数千个测试的生产环境中,这可能是一个问题.
这是怎么回事?我误会了什么吗?有没有办法确保在每个测试模块之后运行tearDownModule?
我正在尝试更改Python执行过程的环境。似乎正确的方法应该是与os.environ交互。但是,我以下断言失败:
import os, subprocess
os.environ['ATESTVARIABLE'] = 'value'
value = subprocess.check_output(['echo', '$ATESTVARIABLE'], shell=True)
assert 'value' in value
Run Code Online (Sandbox Code Playgroud)
我还应该做些其他事情来改变当前环境吗?上面的代码揭示了我对Python的理解有何缺陷:)?
(请注意,在当前的Python解释器中,它os.environ['ATESTVARIABLE']
包含期望值。我正在设置为运行一些需要特定环境变量的代码,并且可能会启动外部进程。显然,如果我想控制特定子进程的环境,我会使用env关键字。)
我觉得几乎每次我用Python读取文件时,我想要的就是:
with open("filename") as file_handle:
for line in file_handle:
#do something
Run Code Online (Sandbox Code Playgroud)
这真的是首选的成语吗?双重缩进所有文件读取逻辑使我有些恼火。有没有办法将此逻辑分解为一行或一层?
当我玩django-revisions时,我正在创建一些初始测试.我希望能够测试我的一些api和查看代码是否正确保存了修订版.但是,我甚至无法获得保存已删除版本的基本测试.
import reversion
from django.db import transaction
from django import test
from myapp import models
class TestRevisioning(test.TestCase):
fixtures = ['MyModel']
def testDelete(self):
object1 = models.MyModel.objects.first()
with transaction.atomic():
with reversion.create_revision():
object1.delete()
self.assertEquals(reversion.get_deleted(models.MyModel).count(), 1)
Run Code Online (Sandbox Code Playgroud)
使用以下命令检查已删除的QuerySet的长度时,此操作失败:
AssertionError: 0 != 1
Run Code Online (Sandbox Code Playgroud)
我的假设是我需要创建我的模型的初始修订版(相当于./manage.py createinitialrevisions
).如果这是问题,我如何在测试中创建初始修订?如果那不是问题,我还能尝试什么?
通常,我可以随意修补和模拟方法:
from UserDict import DictMixin
class py2fake_dict(DictMixin):
def __setitem__(self, name, value):
raise AssertionError("Don't talk to me!")
def __delitem__(self, name):
pass
def __getitem__(self, name):
pass
def __iter__(self):
yield None
def __len__(self):
return 0
c = py2fake_dict()
c.__setitem__ = lambda name, value: 'All clear.'
# This is OK:
c[1] = 2
Run Code Online (Sandbox Code Playgroud)
但是,如果有问题的方法位于 MutableMapping 子类上,我不能:
from collections import MutableMapping
class py3fake_dict(MutableMapping):
def __setitem__(self, name, value):
raise AssertionError("Don't talk to me!")
def __delitem__(self, name):
pass
def __getitem__(self, name):
pass
def __iter__(self):
yield None
def …
Run Code Online (Sandbox Code Playgroud) 在我的 Django 支持的站点上,我有一个包含多个可选字段的搜索页面。搜索页面是django形式,我的view函数是典型的:
def search(request):
form = SearchForm(request.GET or None)
if form.is_valid():
return form.display_results(request)
return render(request, 'search.html', {'form': form})
Run Code Online (Sandbox Code Playgroud)
Form.display_results() 使用提供的字段来查询数据库并呈现响应。我的 search.html 包括:
<form action="/search/" method="get">{% csrf_token %}
<!-- Render the form fields -->
<input type="submit" value="Search" />
<input type="reset" value="Reset form" />
</form>
Run Code Online (Sandbox Code Playgroud)
由于大多数搜索都会有几个空白字段,我不想将它们包含在 search.html 上的提交按钮发出的 GET 请求中。当前搜索类似于:
http://mysite/search/?csrfmiddlewaretoken=blah&optional_field1=&optional_field2=&optional_field3=oohIWantThisOne
Run Code Online (Sandbox Code Playgroud)
我希望它们看起来像:
http://mysite/search/?csrfmiddlewaretoken=blah&optional_field3=oohIWantThisOne
Run Code Online (Sandbox Code Playgroud)
当然,我还有几个领域。这会很好,因为它会使搜索 URL 更容易被人类解析和共享。
我正在使用Twitter Bootstrap折叠功能来隐藏表格行.我还在跨度中的文本中有一个链接,触发崩溃/展开.不幸的是,当我点击链接时,首先展开折叠的文本,然后跟踪链接.
我希望能够在点击链接时跳过触发折叠切换.这里有一些代码可以演示这个问题(这里有jsfiddle示例):
<table class="table">
<tr data-toggle="collapse" data-target="#collapseRow1" style="cursor: pointer;">
<td>Click me to show more!</td>
<td><a href="http://getbootstrap.com/css/">but don't expand after clicking this link</a></td>
</tr>
<tr class="collapse" id="collapseRow1">
<td>hidden content1</td>
<td />
</tr>
</table>
Run Code Online (Sandbox Code Playgroud) 我有一个Python程序,有几个慢进口.我想延迟导入它们直到需要它们为止.例如,如果用户只是试图打印帮助消息,那么导入慢速模块就很愚蠢.最恐怖的方法是什么?
我将添加一个我正在玩的解决方案作为答案.但我知道你们都可以做得更好.
python ×6
unit-testing ×4
boost ×2
c++ ×2
django ×2
css ×1
django-forms ×1
file-io ×1
html ×1
idioms ×1
javascript ×1
jquery ×1
nose ×1
nosetests ×1
testing ×1