如何使用unittest从测试或设置中停止所有测试?
我正在扩展 python 2.7 unittest
框架来进行一些功能测试。我想做的一件事是停止所有测试在测试内部和 setUpClass() 方法内部运行。有时,如果测试失败,则程序已损坏,不再有任何继续测试的用处,因此我想停止测试运行。
我注意到 TestResult 有一个 shouldStop
属性和一个 stop()
方法,但我不确定如何在测试内部访问它。
有人有什么想法吗?有更好的办法吗?
I'm extending the python 2.7 unittest
framework to do some function testing. One of the things I would like to do is to stop all the tests from running inside of a test, and inside of a setUpClass()
method. Sometimes if a test fails, the program is so broken it is no longer of any use to keep testing, so I want to stop the tests from running.
I noticed that a TestResult has a shouldStop
attribute, and a stop()
method, but I'm not sure how to get access to that inside of a test.
Does anyone have any ideas? Is there a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
如果您有兴趣,这里是一个简单的示例,您可以自己决定如何使用 py.test:
如果运行此命令,您会得到:
您还可以将 py.test.exit() 调用放入测试中或项目特定的插件中。
旁注:
py.test
原生支持py.test --maxfail=NUM
实现NUM次失败后停止。Sidenote2:
py.test
对以传统unittest.TestCase
样式运行测试的支持有限。In case you are interested, here is a simple example how you could make a decision yourself about exiting a test suite cleanly with py.test:
and if you run this you get:
You can also put the
py.test.exit()
call inside a test or into a project-specific plugin.Sidenote:
py.test
natively supportspy.test --maxfail=NUM
to implement stopping after NUM failures.Sidenote2:
py.test
has only limited support for running tests in the traditionalunittest.TestCase
style.这是我过了一段时间想出的另一个答案:
首先,我添加了一个新的异常:
然后我向我的子测试类添加了一个新的
assert
:最后我覆盖了
run
函数将其包含在testMethod()
调用的正下方:我更喜欢这个,因为现在任何测试都能够停止所有测试,并且没有特定于 cpython 的代码。
Here's another answer I came up with after a while:
First, I added a new exception:
then I added a new
assert
to my child test class:and last I overrode the
run
function to include this right below thetestMethod()
call:I like this better since any test now has the ability to stop all the tests, and there is no cpython-specific code.
目前,您只能停止套件级别的测试。一旦进入
TestCase
,迭代测试时就不会使用TestResult
的stop()
方法。与您的问题有些相关,如果您使用的是 python 2.7,则在使用
python -m unittest
调用测试时可以使用-f/--failfast
标志。这将在第一次失败时停止测试。请参阅25.3.2.1。 failfast、catch 和 buffer 命令行选项
您还可以考虑使用 Nose 运行测试并使用
-x, --stop
标志 提前停止测试。Currently, you can only stop the tests at the suite level. Once you are in a
TestCase
, thestop()
method for theTestResult
is not used when iterating through the tests.Somewhat related to your question, if you are using python 2.7, you can use the
-f/--failfast
flag when calling your test withpython -m unittest
. This will stop the test at the first failure.See 25.3.2.1. failfast, catch and buffer command line options
You can also consider using Nose to run your tests and use the
-x, --stop
flag to stop the test early.OP 是关于 python 2.7 的。向前跳过十年,对于 python 3.1 和上面,在 python unittest 中跳过测试的方法已经升级了,但是文档可以使用一些说明(恕我直言):文档
涵盖以下内容:
failfast (仅当您真的不想继续任何进一步的测试时有用,包括在其他不相关的 TestCase 类中)
@unittest.skip() 装饰类
等。@unittest.skip()
装饰方法,等等@unittest.skipIf() 装饰
或@unittest.skipUnless()
等。self.skipTest()
(这将跳过该方法,并且仅跳过该方法,而不是后续方法)该文档不涵盖以下内容(截至撰写本文时):
raise unittest.SkipTest("跳过所有在此类中进行测试”)
(可能还有另一种方法,但我不知道)该解决方案假设您在测试方法中间遇到“不良状态”,并且只能在测试方法中注意到(即,它不是可以的)无论出于何种原因,都已在 setUpClass 方法中确定)。事实上,setUpClass 方法是确定初始条件不正确时是否继续的最佳位置,但有时(正如我遇到的那样)直到运行某些测试方法时您才知道。此解决方案假设测试方法按字母顺序排列,并且您不想在遇到“不良”状态后运行的后续测试方法按字母顺序排列。
上述测试将产生以下输出:
The OP was about python 2.7. Skip ahead a decade, and for python 3.1 and above, the way to skip tests in python unittest has had an upgrade, but the documentation could use some clarification (IMHO):
The documentation covers the following:
failfast
(only useful if you really don't want to continue any further tests at all, including in other unrelated TestCase classes)@unittest.skip()
, etc.@unittest.skip()
, etc.@unittest.skipIf()
or@unittest.skipUnless()
etc.self.skipTest()
inside the method (this will skip that method, and ONLY that method, not subsequent methods)The documentation does not cover the following (as of this writing):
raise unittest.SkipTest("skip all tests in this class")
(there may be another way, but I'm unaware)This solution assumes that you encounter the "bad state" in the middle of a test method, and which could only be noticed in a test method ONLY (i.e., it is not something that could have been determined in the setUpClass method, for whatever reason). Indeed the setUpClass method is the best location for determining whether to proceed if the initial conditions aren't right, but sometimes (as I've encountered) you just don't know until you run some test method. This solution assumes that test methods are in alphabetical order and that subsequent tests methods that you don't want to run after encountering the "bad" state follow alphabetically.
The above test will yield the following output:
尽管您不会获得到目前为止运行的测试的常规测试报告,但从
TestCase
方法中停止测试运行的一个非常简单的方法就是引发KeyboardInterrupt
方法内部。通过查看 CPython 的代码,您可以了解如何仅允许
KeyboardInterrupt
在unittest
的测试运行程序中冒泡 此处在testPartExecutor()
内。Though you won't get the usual test reports of the tests run so far, a very easy way to stop the test run from within a
TestCase
method is simply to raiseKeyboardInterrupt
inside the method.You can see how only
KeyboardInterrupt
is allowed to bubble up insideunittest
's test runner by looking at CPython's code here insidetestPartExecutor()
.在
unittest.TestSuite
的测试循环中,开始时有一个break
条件:所以我使用像这样的自定义测试套件:
带有像这样的自定义测试结果类这:
我的测试类就像:
在某些条件下,我然后中止测试套件;例如,测试套件从登录开始,如果失败,我不必尝试其余的:
然后我按以下方式使用测试套件:
我不确定是否有更好的方法来做到这一点,但它对于我的测试表现正确。
In the test loop of
unittest.TestSuite
, there is abreak
condition at the start:So I am using a custom test suite like this:
with a custom test result class like this:
and my test classes are like:
Under certain conditions, I then abort the test suite; for example, the test suite starts with a login, and if that fails, I do not have to try the rest:
Then I use the test suite in the following way:
I'm not sure if there is a better way to do it, but it behaves correctly for my tests.
我查看了 TestCase 类并决定对其进行子类化。该类只是重写
run()
。我复制了该方法,并从原始类的第 318 行开始添加了以下内容:它有一些 CPython 特定代码,用于判断测试方法是否可以接受另一个参数,但由于我到处都使用 CPython,所以这不是问题为我。
I looked at the
TestCase
class and decided to subclass it. The class just overridesrun()
. I copied the method and starting at line 318 in the original class added this:It has some CPython specific code in there to tell if the test method can accept another parameter, but since I'm using CPython everywhere, this isn't an issue for me.
使用:
Use: