python - Django 分析测试
问题描述
所以我发现这篇2016 年的文章详细介绍了如何创建一个自定义测试运行器来捕获在 Django 中运行测试所需的时间:
亚军.py:
from unittest.runner import TextTestResult
from django.test.runner import DiscoverRunner
import time
class TimeLoggingTestRunner(DiscoverRunner):
def __init__(self, slow_test_threshold=0.0, *args, **kwargs):
self.slow_test_threshold = slow_test_threshold
return super().__init__(
resultclass=TimeLoggingTestResult,
*args,
**kwargs,
)
def run(self, test):
result = super().run(test)
self.stream.writeln(
"\nSlow Tests (>{:.03}s):".format(
self.slow_test_threshold))
for name, elapsed in result.getTestTimings():
if elapsed > self.slow_test_threshold:
self.stream.writeln(
"({:.03}s) {}".format(
elapsed, name))
return result
def get_resultclass(self):
return TimeLoggingTestResult
class TimeLoggingTestResult(TextTestResult):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.test_timings = []
def startTest(self, test):
self._test_started_at = time.time()
super().startTest(test)
def addSuccess(self, test):
elapsed = time.time() - self._test_started_at
name = self.getDescription(test)
self.test_timings.append((name, elapsed))
super().addSuccess(test)
def getTestTimings(self):
return self.test_timings
设置.py:
TEST_RUNNER = 'core.utils.test_runner.runner.TimeLoggingTestRunner'
但是,最后没有打印任何内容。我知道代码会运行,因为调试语句在两个类中都会触发 - 但实际的最终结果 ( run
) 似乎没有被调用。
我设法做的是获得打印时间(通过在里面添加打印语句TimeLoggingTestResult
),但我似乎无法让它们在最后全部打印出来。
有没有人有做这样的事情的经验?该run
方法似乎根本无法访问。
使用 Django 1.11。
解决方案
我知道这是一个老问题,但我发现它是为了寻找一种方法来分析我的测试并尝试自己实现它。我在 Django 3.0.8 上,但遇到了与提问者相同的问题。
经过研究,我发现DiscoverRunner
它不是从 TextTestRunner 继承的,它使用组合。而不是调用self.run()
它调用runner.run()
. 请参阅下面的代码。
class DiscoverRunner:
...
test_runner = unittest.TextTestRunner
...
def run_suite(self, suite, **kwargs):
kwargs = self.get_test_runner_kwargs()
runner = self.test_runner(**kwargs)
return runner.run(suite)
我所做的是TimeLoggingTestRunner
继承 DiscoverRunner 和 TextTestRunner 并覆盖run_suite()
.
class TimeLoggingTestRunner(DiscoverRunner, TextTestRunner):
def __init__(self, *args, slow_test_threshold=0.0, **kwargs):
self.slow_test_threshold = slow_test_threshold
DiscoverRunner.__init__(self, *args, **kwargs)
TextTestRunner.__init__(self, *args, **self.get_test_runner_kwargs())
[...]
def run_suite(self, suite, **kwargs):
return self.run(suite)
可能有更好的方法来处理继承,但它正在工作。
另一种选择可能是创建两个 TestRunner,分别继承 DiscoverRunner 和 TextTestRunner,然后以与 DiscoverRunner 相同的方式组合它们。
推荐阅读
- javascript - 如何禁用不同大小的 Html 代码?
- php - 无法使用 MYSQL 搜索串行监视器 VB.NET 2017 发送的值
- r - 在R中将两行合并为一行
- python - 声明派生类的对象初始化基类的属性
- android - 如何在 TextView 中显示 Toast 消息?
- python - 是否可以将 base_estimator 设置为 Adaboost 的 OneVsRestClassifier(DecisionTreeClassifier())?
- python - 列在 tfidf 矩阵中代表什么?
- jquery - 将summernote中的语法检查与截止日期后集成
- git - 如何确保我拥有最新版本的开发分支?
- docker - 为什么没有记录来自 Red Hat Container Catalog 的 Docker 映像?