调用TKinter GUI的单元测试

时间:2018-12-05 21:35:57

标签: python python-2.7 unit-testing user-interface tkinter

假定一个脚本启动TKinter GUI(例如scripts/launch_GUI.py),并且是PyPI软件包的一部分(例如MyPackage)。

.
├── appveyor.yml
├── MyPackage
│   ├── TkOps.py
│   └── CoreFunctions.py
├── README.md
├── requirements.txt
├── scripts
│   ├── launch_CLI.py
│   └── launch_GUI.py
├── setup.py
└── tests
    └── MyPackage_test.py

启动脚本非常简单:

#!/usr/bin/env python2
if __name__ == '__main__':
    import sys, os
    sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'MyPackage'))
    import TkOps
    TkOps.start_GUI()

您建议使用什么 unittest 来评估TKinter GUI在启动launch_GUI.py后是否已正确启动?

注意:我只希望评估启动脚本是否能够完成其工作并启动GUI,而不是用户是否可以与GUI交互。

1 个答案:

答案 0 :(得分:3)

可以说,您需要一个功能测试而不是一个单元测试,但是无论如何,让我们尝试一下吧!

虽然可以通过exec()来测试启动脚本,但这被认为是不好的做法。让我们对其进行重构:

def main():
    import sys, os
    sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'MyPackage'))
    import TkOps
    TkOps.start_GUI()

if __name__ == '__main__':
    main()

然后让我们建立单元测试应该测试的内容,例如:

  • sys.path已更新为MyPackage的正确路径
  • start_GUI被称为

然后, mokist [1]单元测试可能如下所示:

@mock.patch("sys.path", copy.copy(sys.path))
@mock.patch.dict(sys.modules, TkOps=mock.MagicMock())
def test_main():
    main()
    # minimal validation of sys.path side effect
    # ideally this would check that path bit points to real directory
    assert any(p.endswith("/MyPackage") for p in sys.path)
    # validation of expected call
    assert sys.modules["TkOps"].start_GUI.called

经典单元测试将需要在GUI中使用转义填充,例如:

def start_GUI(dry_run=False):
    import tk
    ...
    if not dry_run: tk.foobar()

[1] https://agilewarrior.wordpress.com/2015/04/18/classical-vs-mockist-testing/