代码之家  ›  专栏  ›  技术社区  ›  Bob Aman

如何利用谷歌应用引擎建立TDD开发流程?

  •  15
  • Bob Aman  · 技术社区  · 15 年前

    我主要是一个红宝石人,但最近我已经研究了很多关于Python的东西,特别是应用程序引擎代码。在Ruby中,我将使用自动化的连续集成( autotest )代码覆盖工具( rcov )静态分析( reek )和突变测试( heckle )在我的开发过程中,但我不确定如何最好地为应用程序引擎环境设置类似的开发过程。我也会对类似的 RSpec Cucumber 对于可以在应用程序引擎中工作的python。

    4 回复  |  直到 13 年前
        1
  •  15
  •   JasonSmith    15 年前

    在我的GAE项目中,我使用:

    • NoseGAE -这是将所有其他部分联系在一起的关键部分
    • 嘲笑,就像约翰出色的回答一样。我主要将其用于AWS和其他Web服务
    • 固定装置(包装,不是创意)

    我还喜欢Rails的许多习惯用法。我将测试分解为单元,并使用Python包实现功能。您可以使用 --tests=unit --tests=functional . 这比Rails要手动的多,但至少我可以对硬件进行单元测试,并确保我从来没有进行过回归。

    我也做了一个简单的 FunctionalTest 类在Rails中执行许多非常常见的操作,例如 assert_response assert_xpath (类似于断言选择)。

    class FunctionalTest(Test):
      def get(self, *args, **kw):
        self.response = app.get(*args, **kw)
    
      def post(self, *args, **kw):
        self.response = app.post(*args, **kw)
    
      def assert_response(self, expected):
        pattern = str(expected) if re.search(r'^\d+$', expected) \
                                else (r'^\d+ %s' % expected)
        assert re.search(pattern, self.response.status, re.IGNORECASE), \
               'Response status was not "%s": %s' % (expected, self.response.status)
    
      def assert_xpath(self, path, expected):
        element = ElementTree.fromstring(self.response.body)
        found_nodes = element.findall('.' + path)
        if type(expected) is int:
          assert_equal(expected, len(found_nodes))
        elif type(expected) is str or type(expected) is unicode:
          assert (True in [(node.text == expected) for node in found_nodes])
        else:
          raise Exception, "Unknown expected value: %r" % type(expected)
    

    如果要进行大量的ListElement相等搜索,一定要了解 --tests=foo 语法,因为对列表中匹配元素的测试非常缓慢。

    有时,我喜欢将Rails控制台加载到夹具数据中,以查看测试环境(即 script/console test )要对GAE执行类似的操作,请使用参数运行dev_appserver.py --datastore_path="$TMPDIR/nosegae.datastore" (或可能的替代品) /tmp 对于 $TMPDIR .

        2
  •  26
  •   John Paulett    15 年前

    在Python中,您不会总是找到一对一等价的Ruby测试工具,但是在Python中有一些很棒的测试工具。我发现一些有用的工具包括:

    • unittest -包含在Python标准库中的XUnit工具。它包括单元测试的所有基础知识。
    • doctest -作为标准库的一个非常棒的部分,它允许您在函数、类、模块、方法的文档字符串中编写测试。它非常擅长传达预期的API用法。 Ian Bicking 建议对行为驱动的开发使用doctest。doctest非常适合 Sphinx 文档系统(您可以确保文档中的所有示例在每次构建文档时都能通过)。
    • nose py.test 被视为UnitTest的下一代版本。它们可以运行所有现有的单元测试用例,但允许进行更简单的、非基于类的单元测试。py.test还允许分布式执行。
    • mock 是一个很好的模仿行为库。
    • tdaemon 监视目录以更新代码,并将重新执行测试套件。(我的 personal branch 包含一些未合并的改进)。
    • Buildbot , Bitten 甚至 Hudson 所有这些都可以很好地为Python代码提供完整的持续集成服务器。
    • coverage.py 计算代码的代码覆盖率。
    • pylint 将对您的代码进行类似lint的分析,确保它遵循常见的编码约定,并且没有任何常见的错误。还有一个“更轻”的分析工具, PyFlakes .
    • 有许多HTTP/Browser测试工具可以在Python中很好地工作,包括 Twill , Selenium Windmill .

    如果您使用的是Django应用程序引擎,它包括 several extensions 到允许您模拟HTTP客户端和数据库持久性的UnitTest。

    还有很多其他工具我没有使用(例如 PySpec Behaviour )这也会有帮助。我还没有在Python中看到任何突变测试工具,但我敢打赌有一个(我很想知道它是什么)。

    快乐测试!

        3
  •  3
  •   yamad    15 年前

    还没有使用应用程序引擎,但我对最流行的Python测试工具的感觉是

    • unittest/doctest 测试包是否来自python标准? 图书馆。UnitTest是Python的XUnit。
    • nose 是测试运行程序/查找程序。它有很多选择,包括 --with-coverage ,它使用 coverage 为您提供代码覆盖 报告。
    • pylint 是蟒蛇最具特色的线头检查工具。有用的超越 一个语法检查程序,因为它会通知未使用的变量/函数,当 方法应该是函数等等。
    • pester (突变测试)
    • buildbot (持续集成)

    您可能需要参考以下(不完全)列表: Python Testing Tools .

    对于BDD,上次检查时字段很薄。许多真正的BDD工具 不能与nose一起使用和/或在所需的语法中限制过大。 你可能有点运气 spec 这是一个类似于bdd的鼻插件。 刚刚找到 pyccuracy 看起来很像黄瓜,但我没有 试过了。

    为了它的价值,我现在只使用 nosetests -v (机头滑槽 --verbose),它将使用测试运行程序中docstring的第一行 输出。也就是说,进行如下测试:

    class TestFoo(unittest.TestCase):
        def testAnyNameHere(self):
            """ Foo should be bar"""
            foo = "bar"
            self.assertEqual(foo, 'bar')
    

    鼻试验将得出:

    $ nosetests -v
    Foo should be bar... ok
    
    -----------------------------
    Ran 1 tests in 0.002s
    OK
    
        4
  •  0
  •   Bob Aman    13 年前

    另一个新的选择是 Agar ,这是基于 google.appengine.ext.testbed 是应用引擎SDK的一部分。见 this blog post 详情。