问题标签 [pytest-qt]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
332 浏览

python - “这个插件不支持propagateSizeHints()”/在QDialog子类上调用`exec`

NB 操作系统是W10

这里的上下文是 pytest-qt。我找到了这个答案并尝试使用它(见下文)。

当测试方法调用创建 aQFileDialog然后调用exec它的应用程序方法时,我收到此错误。然后控制台发出此消息并且控制台挂起。我别无选择,只能手动关闭控制台。

这里涉及的一个因素是此设置(在运行测试之前的测试期间设置):

... 如果没有此行,则QFileDialog显示 OK exec,测试结束,并且控制台不会挂起。

我当然不知道哪个插件是罪魁祸首......在“propagateSizeHints”上搜索了一下,没有任何结果。pip freeze输出如下:

在搜索问题后,exec我找到了 eyllanesc 的上述答案。所以我尝试了这个:

(这些断言注定要失败)

应用程序代码尽可能简单:

...但我再次收到相同的“此插件不...”消息,控制台再次挂起。只有“A3”和“A4”被打印出来。

一种解决方案可能只是exec普遍模拟。但是 eyllanesc 知道他的洋葱,如果是这样的话,大概会这么说。如果是这种情况,我看不出如何进行任何由qtbot.

到目前为止,我对“屏幕外”设置没有任何问题。但也许有限制......这篇文章似乎表明这可能是问题的根源。

MRE:

on_timeout在我的机器上,如果 QT_QPA_PLATFORM 行被注释掉,这会在函数行中产生(如预期的那样)FAIL 。

如果后者没有被注释掉,我会收到插件错误消息并且控制台挂起。

即使MainWinshow()在其构造函数中进行,即使QFileDialog是使用创建QtWidgets.QFileDialog(self.main_win),错误仍然会发生。

我也尝试过class Project(object),甚至 (longshot) class Project(QtCore.QObject)。没有喜悦。

注意,我还在我的虚拟环境中的所有文件以及我的核心 Python 安装(v. 3.9.4)中的所有文件中搜索了字符串“propagatesize”。没有什么!

0 投票
0 回答
26 浏览

python - 单击 QFileDialog 中的项目

使用 pytest-qt 的qtbot夹具,我希望测试代码单击QFileDialog. 但是我实际上很难以编程方式获取这些项目。这是一个MRE:

我的操作系统是 W10。

当我运行上面的文件时,据说文件列表中有两行 4 列:“C:”和“D:”。这不仅与我在我面前看到的不相符(CWD 中有很多文件和目录),而且,如果我QFileDialog尽可能地向上导航,实际上有 4 个驱动器,而不仅仅是2. 不仅如此,更令人费解的是,C: 和 D: 的“最后修改”日期(第 3 列)与此处打印的不匹配。

我不太确定如何QStyledItemDelegate呈现用户看到的内容:这可能与它有关:这些可能只是文件和目录的“图像”,而不是适当的项目。在那种情况下,我想我需要找出这些图像占用的屏幕空间,然后qtbot在其中单击。

0 投票
1 回答
53 浏览

python - 如何检查对信号的响应

在 的子类中QFileDialog有一个方法 ,on_dir_entered应该在QFileDialog' 的信号directoryEntered触发时调用它,因此:

问题是信号需要很长时间才能生效。最初,我受到著名 PyQt5 专家 eyllanesc 的回答的启发。通过一个孤立的测试,这种技术QTimer.singleShot()可以使用,尽管我从一开始就对它有模糊的怀疑。事实上,在我的机器上,我发现这种事情“测试泄漏”,特别是当有不止一种这样的测试方法时:奇怪的错误显然发生在测试本身之外:

...所以我回到 pytest-qt 文档,发现有各种可用的方法开始wait...似乎可以解决信号或其他事件需要花费不可忽略的时间才能生效的问题。所以我做了一些尝试来测试信号directoryEntered

接着

接着

全部失败:该方法被调用 0 次。

我也试过:

... 这超时(默认 5000 毫秒)。我已经反复检查并检查了connect在此信号上设置的代码是否已执行。

之后

print通过在被调用的 slot ( ) 中添加一条语句,on_dir_entered我现在看到了问题所在:尽管有这with mock.patch...条线,但该方法并没有被嘲笑!

在我对嘲笑等知识的低水平上,我倾向于认为这是因为使用信号emit()来触发事件的事实:我想不出另一种解释。

注意这个信号是由 a 中的一个或两个事件“自然地”触发的QFileDialog(例如单击“转到父目录” QToolButton)。也许你必须这样做......所以我尝试了这个:

暂停。0 次通话。我再次能够确定正在调用真正的方法,并且补丁不起作用。

我做错了什么,有没有办法用 pytest-qt 的东西来测试它?

0 投票
0 回答
56 浏览

python - 为什么这些与信号相关的测试会失败?

我正在尝试在 PyQt5 中实现长时间运行的任务。我的灵感是这个页面

使用该页面,我已经设法让事情在预测试阶段运行无错误(到目前为止)。现在我想使用测试来构建它。

在之前的一些测试中,我设法QFileDialog通过调用emit并查看连接的插槽是否触发来测试信号(因为它会发生来自类的预先存在的信号)。

但是,当我尝试根据 Maya Posch 的公式为“任务管理器”类设计测试时,我失败了。这是一个 MRE:(取消注释sys.exit以作为应用程序运行的行,或者运行pytest- 必须安装 NB pytest-qt):

之后

...发现qtbot.waitSignal,并取得了一些成功,并带有一些信号...所以我稍微修改了一下:

TaskManager现在给出了两种新方法,目的是查看我是否可以检查是否正确运行QtCore.QTimer.singleShot

...不幸的是,在合并后waitSignal,以下所有测试都失败了,各不相同,如下所述:

0 投票
0 回答
42 浏览

python - 如何使用 qtbot 和 pytest 单击菜单项

使用 pycharm,我用 pyqt5 创建了一个小 gui,并想用 pytest 和 qtbot 进行测试。

我在单击菜单中的 menu_entry 时遇到问题,我可能需要提示。

我看了这篇很有帮助的帖子: `pytestqt.mouseMove` to menubar menu widget move to wrong place in the comments他们谈到了在菜单栏中单击一个条目的问题。(gist.github.com/eyllanesc/ded349044bf43dd79f8c43acb049b263)但是解决方案代码不再可用。

目前测试代码如下所示:

为最小的、可重现的示例添加了代码:

主文件

用户界面/主窗口.py

test_main.py

0 投票
1 回答
32 浏览

python-requests - requests 模块是否在 pytest 或 pytest-qt 中起作用?

这在一些测试过程中出现了。我试图在 MRE 中重现该问题以隔离问题但没有成功。

我有一个这样的测试(简化了,但是这个简化的版本也出现了同样的问题):

...添加这两行并运行 pytest 会导致一系列意外的失败和错误。我正在使用 pytest-random-order,所以它们会有所不同。错误是可怕的

RuntimeError: QTextEdit 类型的包装 C/C++ 对象已被删除

...但是如果我注释掉该requests.delete行,则没有任何反应:所有测试都通过多次随机顺序运行。

索引是否存在应该不是问题(或者实际上 Elasticsearch 是否正在运行)。我有点困惑。

AQTextEdit存在于我的 GUI 中,并且使用信号来更新它。来自 pytest 的跟踪信息如下所示:

这表明当这些测试失败时会触发更新此 GUI 元素的信号。作为回应,我删除了应用程序和测试代码中的信号和所有对它的引用。在此之后,测试都通过了。

为什么调用命令requests.delete会导致看似虚假的信号触发(显然在拆卸期间)?pytest-qt 是否requests可能在其内部使用?

PS删除qtbot上面的夹具并不能解决问题。

编辑

如果我放入traceback.print_stack()被解雇的插槽,我会得到:

从上面可以看出,触发信号的东西是pytestqt内部的东西:

该方法如下所示: