如何确定 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()
。
背景: 我在 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()
。