小编Sil*_*cer的帖子

过时的UI自动化树

我正在尝试使用新的本机Microsoft UI Automation接口3.0(在VC++ 2010,Win7中)编写自动化测试器应用程序.被测应用程序(AUT)是一个WPF应用程序.

几乎一切正常......我可以安装事件处理程序,在树中导航,使用各种条件搜索元素并使用它们的模式控制找到的元素.

但是昨天我发现了一种令我绝望的行为:我的AUT的UIA树在通过点击其主菜单按钮切换其GUI主面板后根本没有更新.

单击主菜单按钮后,我可以在AUT的GUI中看到新的小部件,但是UIA树仍然包含单击主菜单按钮之前已经存在的控件.(过时的)UIA树仍然可以使用搜索功能或使用walker完全读取,但当然由于小部件不再存在而无法写入.

这看起来好像会有一个过时的缓存...但是我根本不使用任何缓存UIA功能.没有.决不.无处.

我无法以编程方式更新UIA树...既不能通过调用任何UIA函数,也不能通过重新启动测试器应用程序,也不能来回切换AUT的GUI.这不会每次都发生.有时单击主按钮后,树似乎是最新的,一切正常.但是大多数运行都失败了.只有一种(神秘的)方式可靠地更新UIA树:使用inspect.exe.当使用inspect.exe工具简要查看AUT的UIA子树时,问题突然消失,我的测试人员应用程序可以立即访问实际更新的树!当然重启AUT后问题会重新出现.

inspect.exe做什么来使UIA树(另一个应用程序!!!)更新?如何在不使用任何缓存的情况下访问已删除的元素?我错过了什么?

我真的需要帮助.


好的,还有一些发现:

  1. UISpy.exe能够以与inspect.exe相同的神秘方式刷新UIA树(这尤其奇怪,因为inspect.exe使用与我相同的本机接口,但UISpy.exe使用.NET接口AFAIK).这意味着这是一种系统范围内持久的UIA问题,而不是纯粹的原生UIA问题.

  2. 如果我切换视图之前不访问树,则不会发生此问题.即如果我的测试者应用程序在通过单击主菜单按钮切换视图之前没有访问AUT'S视图,它会看到新的小部件没有问题.这强烈表明了本机UIA API的一些缓存问题 - 即使我不知道如何发生这种情况,因为我根本不缓存.有人知道是否有一些内部缓存发生?

我认为这可能是一个API错误.但是考虑到我目前使用Microsoft Connect的经历,我有点迷失于那个showstopper :-(

有人有什么想法吗?


我还测试了Snoop工具.使用Snoop不会像Inspect和UISpy那样暂时修复问题.关于Inspect.exe,还有另一个细节......它足以折叠和扩展AUT的子树以暂时解决问题.

wpf user-interface visual-studio-2010 ui-automation visual-c++

6
推荐指数
1
解决办法
1866
查看次数

QByteArray与reserve()的内部重新分配行为

我只是试图优化一些通信堆栈.我使用的是Qt 5.3.2/VS2013.

堆栈使用QByteArray作为数据缓冲区.我打算在数据大小增加时使用capacity()reserve()方法来减少不必要的内部缓冲区重新分配.然而,QByteArray的行为结果是不一致的.保留的空间有时似乎被隐含地挤压了.

我可以提取以下演示,应用字符串追加,字符串赋值和附加到三个缓冲区的字符.这些单个操作似乎保留了内部缓冲区大小(使用获得capacity()).但是,当将这三个操作中的每一个应用于同一QByteArray时,保留的大小会发生变化.这种行为对我来说是随机的:

QByteArray x1; x1.reserve(1000);
x1.append("test");
qDebug() << "x1" << x1.capacity() << x1;

QByteArray x2; x2.reserve(1000);
x2 = "test";
qDebug() << "x2" << x2.capacity() << x2;

QByteArray x3; x3.reserve(1000);
x3.append('t');
qDebug() << "x3" << x3.capacity() << x3;

QByteArray x4; x4.reserve(1000);
x4.append("test");
x4.append('t');
x4 = "test";
qDebug() << "x4" << x4.capacity() << x4;
Run Code Online (Sandbox Code Playgroud)

预期的产出是:

x1 1000 "test"
x2 1000 "test"
x3 1000 "t"
x4 1000 "test"
Run Code Online (Sandbox Code Playgroud)

但实际输出是:

x1 1000 "test"
x2 1000 "test" …
Run Code Online (Sandbox Code Playgroud)

c++ qt memory-management qbytearray

6
推荐指数
1
解决办法
936
查看次数

QSignalSpy 不能与线程一起使用

我写了一个执行工作对象的线程。一切正常。结果信号也按应有的方式发出。当然,我处理了有关线程/对象关联性的常见错误。

今天我为这些工作线程/线程编写了一个自动化模块测试。我创建了一个 QSignalSpy 来等待工作对象(已移动到线程)发出的信号,如下所示:

QSignalSpy spy(worker, SIGNAL(Success()));
thread.ExecuteWorker();
QVERIFY(spy.wait()); // Error in this line
Run Code Online (Sandbox Code Playgroud)

我在标记行中收到一个众所周知的错误:

QObject::killTimer: timers cannot be stopped from another thread
Run Code Online (Sandbox Code Playgroud)

首先,我预计会出现错误,因为 wait() 中的某些代码在错误的线程中执行。然后我在QSignalSpy的实现中发现了如下代码:

if (!QMetaObject::connect(obj, sigIndex, this, memberOffset, Qt::DirectConnection, 0))
{
   qWarning("QSignalSpy: QMetaObject::connect returned false. Unable to connect.");
   return;
}
Run Code Online (Sandbox Code Playgroud)

这显然意味着 QSignalSpy 一直使用 DirectConnection 并且不能用于监视生活在不同线程中的对象的信号。

为什么他们在 Qt5.3 中这样编程?这是一个错误还是有意的行为?我该如何解决这个限制?

c++ qt qthread qtestlib qsignalspy

6
推荐指数
1
解决办法
1893
查看次数

GPU 中每个操作的时钟周期数

有没有办法找到使用 CUDA 在 GPU 中执行除法、减法和加法等不同操作所需的时钟周期数?

cuda gpu gpgpu

6
推荐指数
1
解决办法
4713
查看次数

库部署与未使用的直接依赖关系

我试图找出Qt Assistant需要部署的库.我ldd在Linux上用过这个.

我发现它ldd提供了-u"打印未使用的依赖项" 的选项.这听起来像是某种依赖(部署)不需要(总是).所以我再运行了两个ldd命令:

~$ ldd -u ~/Qt/5.10.0/gcc_64/bin/assistant 
Unused direct dependencies:
        /lib/x86_64-linux-gnu/libQt5Network.so.5
        /lib/x86_64-linux-gnu/libQt5Sql.so.5
        /lib/x86_64-linux-gnu/mesa/libGL.so.1
        /lib/x86_64-linux-gnu/libpthread.so.0
        /lib/x86_64-linux-gnu/libm.so.6
        /lib/x86_64-linux-gnu/libgcc_s.so.1

~$ ldd -r -u ~/Qt/5.10.0/gcc_64/bin/assistant 
Unused direct dependencies:
        /lib/x86_64-linux-gnu/libQt5Network.so.5
        /lib/x86_64-linux-gnu/mesa/libGL.so.1
        /lib/x86_64-linux-gnu/libpthread.so.0
        /lib/x86_64-linux-gnu/libm.so.6
        /lib/x86_64-linux-gnu/libgcc_s.so.1
Run Code Online (Sandbox Code Playgroud)

我试图找出发生了什么,但我并没有完全理解它.

我的问题是:

  • 什么是未使用的直接依赖(这听起来与我相矛盾)?
  • 是否有可能找出Qt Assistant实际上是否需要一个未使用的直接依赖(除了启动它并等待错误)?
  • 上述命令行之间究竟有什么区别?为什么
    第一个列表libQt5Sql却没有第二个列表?

linux qt dependencies shared-libraries ldd

6
推荐指数
1
解决办法
291
查看次数

Qt 与 constexpr 字符串文字

有没有办法在 Qt 中定义静态 constexpr 字符串文字成员?即类似以下内容:

class X
{
   static constexpr QString tag = "mytag";
};
Run Code Online (Sandbox Code Playgroud)

c++ qt string-literals constexpr

6
推荐指数
1
解决办法
6990
查看次数

C++20 协程、标准返回类型和状态持久性

这个问题其实是两个问题。我会马上问他们,因为他们可能有关系。

我刚刚第一次看到 C++20 协程。如果看过各种例子,他们中的大多数都非常基础。像下面这样:

generator<int> ints(int x)
{
   for (int i = 0; i < x; ++i)
   {
      co_yield i;
   }
}
Run Code Online (Sandbox Code Playgroud)

所有的例子都使用一个特殊的返回类型,显然包含计算结果和协程上下文。但是没有示例使用标准返回类型。他们要么偷偷地忽略该类型,要么定义一个难以理解的自定义嵌套类(对我来说,目前)。

1. 这是否意味着 C++20 标准库不提供可用于例如生成器的协程返回类型?

我能找到的最好的std::coroutine_handle方法是提到的自定义类在内部使用。

在文档中,据说协程是一种很好的工具,可以实现需要逐块数据处理的算法,并且通常需要将其拆分为片段,例如使用(可能非常复杂)状态引擎。我也是这么理解的。我什至记得一些项目是协程的一个很好的用例,即使用流接口加载一个大的、复杂的 XML 文件。

似乎仍然有很大的不同:在实现状态引擎时,将状态存储到磁盘或从磁盘加载状态非常容易,因为所有状态数据都可以作为标准变量使用(一些错误检查和文件处理就足够了)。我想到了类似用户界面的东西来取消/恢复长时间运行的计算。

2. 是否有(简单的)方法来存储/加载协程上下文到/从永久存储?C++20 标准中是否有任何内容有助于这样做?

c++ c++-standard-library c++20 c++-coroutine

6
推荐指数
1
解决办法
235
查看次数

为每个C++类模板实例执行一次代码

好的,这是一个复杂的问题.

我有一个多次实例化的C++类模板.对于这些实例中的每一个,我都需要执行一个注册一些运算符的函数.这需要该模板实例中使用的第一目标(这并不意味着它必须在执行前每个模板实例只需进行一次 instanciation这在编译时有发生).

最新的我手动完成了这个.但这是一种痛苦.所以我想自动执行注册功能.

我目前的想法是在构造函数中调用一个受保护的注册方法.然而,每当构造一个类的实例时,这需要(小的)开销.由于这种情况经常发生,我想避免这种开销.

我还尝试使用静态RAII帮助程序成员,但如果没有主动访问静态模板类成员,则不会构造静态模板类成员,因此尝试失败.

有没有办法在类模板instanciation上执行代码(通过函数或可能由RAII帮助程序类)而没有运行时开销?

c++ templates class-template c++11

5
推荐指数
1
解决办法
1236
查看次数

QMap 和 QMultiMap 中的项目顺序

我想使用QMultiMap(源自QMap)来存储键/值对。由于我可以多次使用密钥,因此我更愿意使用QMultiMap.

假设我会按给定的顺序插入以下对:

"C" -> 5
"A" -> 10
"B" -> 77
"B" -> 1
"X" -> 314159
Run Code Online (Sandbox Code Playgroud)

在迭代地图时(最好使用 java 风格的迭代器),我需要保留相等键对的顺序。即,"B" -> 77并且"B" -> 1在迭代时应该完全按照插入顺序出现。不同的键之间的顺序无关紧要。

不幸的是,文档并没有说明这个细节。它说

使用 QMap,项目总是按键排序

但它没有说明是否/如何对相等的键进行排序。

是否QMap保留对的插入顺序同键或可以以某种方式保存?

qt qmap qmultimap

5
推荐指数
1
解决办法
8958
查看次数

将C或C99中的结构数组初始化为所有相同的值

让我们在C或C99中假设以下内容:

typedef struct
{
   int x;
   double y;
} MY_S;

MY_S a[666] = {333, 666.6};
Run Code Online (Sandbox Code Playgroud)

这是否仅初始化数组的第一个对象?如果是,是否有一种方法可以使用该语法将数组的所有元素初始化为所有相同的值(无需调用函数/循环,而无需重复初始化程序)?

c arrays struct initialization c99

5
推荐指数
2
解决办法
2719
查看次数