1

下面的代码失败,因为所需的基类 twisted.trial.unittest.TestCase 不是基类。

from twisted.trial import unittest
from unittest import TestCase
import myapp

class Feature(TestCase):

  def setUp(self):
    self.callbackCounter = 0

  def checkCbCalled(self, expected):
      self.assertEqual(self.callbackCounter, expected)

  def testTrialCallsDeferred(self):

      d = myapp.buildFeature()
      self.addCleanup(self.checkCbCalled, expected=1)
      def cb(res):
        self.callbackCounter += 1
      d.addCallback(cb).addErrback(self.fail)
      return d           # does not fire because of 'import rules'?

如果我说过

from twisted.trial import unittest as trialut
from trialut import TestCase 

或更好:

from twisted.trial.unittest import TestCase

然后测试将按预期运行,并且 trial.unittest.TestCase 会解雇我的延期。

这看起来好像本地最近导入的东西应该已经取代了 {lib/pythonX.X/unittest} 中可用的东西。我知道它必须是基于 sys.path 或其他隐式或显式的规则。这让我绊倒了太久,因为我没有调用 addCleanup 并且所有测试都通过了,因为返回的延迟实例没有被触发。

我违反了一些规则,请提供一些阅读或其他建议。

谢谢迈克

4

1 回答 1

2

非常不清楚您希望它如何工作,但听起来您至少对 Python 中的模块的行为方式有些困惑。

语句(有时)从import源文件加载模块,然后将本地范围内的名称绑定到该模块对象。

所以,当你这样做时:

from twisted.trial import unittest

您正在加载twisted.trial.unittest模块,然后绑定本地名称unittest

这与以下语句没有任何有趣的交互:

from unittest import TestCase

它加载unittest模块,然后将本地名称绑定TestCase到该模块TestCase属性所引用的对象。

当您稍后子类化时TestCase

class Feature(TestCase):
    ...

TestCase在本地范围内直接使用该名称 - 一个引用模块TestCase定义的类的名称。unittest请注意,它与 Twisted 的模块毫无关系twisted.trial.unittest,即使您也加载了该模块。您必须使用其属性之一才能使用其功能。

改进代码行为的一项更改是完全停止使用标准库unittest模块。删除这一行:

from unittest import TestCase

并将您的类定义替换为:

class Feature(unittest.TestCase):

不要对标准库unittest模块共享 Twisted 模块名称的一部分这一事实感到困惑twisted.trial.unittest。它们是具有不同(尽管相似,有时重叠)功能的不同模块。上面示例中的类定义是 using twisted.trial.unittest,因为它位于您的原始行之后:

from twisted.trial import unittest

一旦你真正使用了 Twisted 的TestCase(from twisted.trial.unittest) 而不是标准库的TestCase(from unittest),当测试方法返回一个Deferred. 这是因为提供此功能的是 Twisted,而不是标准库。

于 2012-01-06T19:12:09.533 回答