如何确定 Python 调试器停止的位置以及应该归咎于哪一行?

How to decide where Python debugger stops and which line is to be blamed?

背景: 我在 Python 中编写 Squish GUI 测试。我尝试尽可能将测试代码设为 Pythonic 和 DRY,因此我将所有重复代码移至单独的 类 / 模块。

问题定义: test.verify 或 assert 语句告诉调试器在语句所在的那一行停止,在大多数情况下,这是包含单个测试步骤详细信息的模块。此行在手动 运行 期间显示在 eclipse 中,并在 Jenkins 中由自动测试输出。

要实际查看测试失败的原因,最好在程序的调用点停止调试器,其中包含断言。然后测试人员/GUI 开发人员可以发现 GUI 上的哪些操作导致了问题以及检查了什么。

示例:

test_abstract.py

class App():
    def open_file(self, filename):
        pass # example

    def test_file_content(content):
        # squish magic to get file content from textbox etc.
        # ...
        test.verify(content in textBoxText)

test_file_opening.py

def main():
   app = App()
   app.open_file('filename.txt')
   app.test_file_content('lorem')

由于 test.verify() 调用测试失败,调试器停止并定向到 test_abstract.py 文件。它实际上没有说明导致此测试失败的测试步骤。

有没有办法告诉调试器忽略测试失败的直接位置,并让它显示调用测试过程的位置。我正在寻找在通用测试文件本身中不需要太多代码的优雅方式。

不是理想的有效解决方案: 现在我没有在抽象模块内部使用 test.verify 并在特定的测试用例代码中调用它。广义测试函数 return 元组(test_result,test_descriptive_message_with 错误)用 *:

解包
def test_file_content(content):
    # test code
    return (result, 'Test failed because...')

测试用例代码包含:

test.verify(*test_file_content('lorem'))

效果很好,但是每个测试用例代码都必须包含很多 test.verify(*... 并且测试开发人员必须记住这一点。更不用说它看起来很潮湿。 ..(不干)。

是的!如果您可以访问 Squish 6,则有一些新功能可以做到这一点。 fixateResultContext() 函数将导致所有结果被重写,使它们看起来像是起源于祖先框架。 See Documentation.

如果您使用的是 python 这可以包装成 handy context manager

def resultsReportedAtCallsite(ancestorLevel = 1):
    class Ctx:
        def __enter__(self):
            test.fixateResultContext(ancestorLevel + 1)
        def __exit__(self, exc_type, exc_value, traceback):
            test.restoreResultContext()
    return Ctx()

def libraryFunction():
    with resultsReportedAtCallsite():
        test.compare("Apples", "Oranges")

以后对 libraryFunction() 的任何失败调用都将指向包含 libraryFunction() 的代码行,而不是其中的 test.compare()