Sma*_*acL 11 c++ testing mfc multithreading
我有一块成熟的地理空间软件,最近重新编写了一些区域,以便更好地利用现代PC中的多处理器.具体来说,显示,GUI,空间搜索和主要处理都被分离出来以分离线程.该软件具有相当大的GUI自动化套件,用于功能回归,另一个较小的用于性能回归.虽然所有自动化测试都已通过,但我并不相信它们能够提供足够的覆盖范围来查找与多线程相关的竞争条件,死锁和其他恶意相关的错误.您将使用哪些技术来查看是否存在此类错误?假设有一些技术可以根除,那么你会提倡哪些技术可以根除它们?
我到目前为止所做的是在调试器下运行的应用程序上运行GUI功能自动化,这样我就可以摆脱死锁并捕获崩溃,并计划进行边界检查器构建并针对该版本重复测试.我还通过PC-Lint对源进行了静态分析,希望找到潜在的死锁,但没有任何有价值的结果.
该应用程序是C++,MFC,多文档/视图,每个文档有许多线程.我使用的锁定机构是基于一个对象,它包括一个指针指向一个CMutex,其被锁定在构造函数和在析构函数释放上.我使用此对象的局部变量来根据需要锁定各种代码,并且我的互斥锁有一个超时,如果达到超时,则会触发警告.尽可能使用资源副本,尽可能避免锁定.
您还会进行哪些其他测试?
编辑:我已经在许多不同的测试和编程论坛上发布了这个问题,因为我很想知道不同的思维方式和思想流派如何解决这个问题.如果你看到它在其他地方交叉发布,那么道歉.我会在一周左右后提供回复的摘要链接
oef*_*efe 10
一些建议:
虽然我同意@rstevens的答案,因为目前没有办法100%确定单元测试线程问题,但我发现有些东西是有用的.
首先,无论你做什么测试,都要确保在很多不同的规格盒上运行它们.我有几个构建机器,所有不同的,多核的,单核的,快速的,慢的等等.它们有多么多样化的好处是不同的机器会引发不同的线程问题.我经常惊讶地在我的农场添加一台新的构建机器并突然暴露出一个新的线程错误; 而我正在谈论在其他构建机器上运行10000次的代码中暴露出来的新bug,并且在新的机器上显示了10个中的1个...
其次,您对代码进行的大多数单元测试都不需要涉及线程.通常,线程是正交的.因此,第一步是将代码分开,以便您可以测试执行工作的实际代码,而不必过多担心线程性质.这通常意味着创建一个线程代码用来驱动实际代码的接口.然后,您可以单独测试实际代码.
通过Thridly,您可以测试线程代码与代码主体交互的位置.这意味着为您开发的接口编写模拟以分隔两个代码块.到目前为止,线程代码可能更简单,然后您可以经常将同步对象放在您已经创建的模拟中,以便您可以控制被测试的代码.因此,您可以启动线程并等待它通过调用模拟来设置事件,然后让它阻止您的测试代码控制的另一个事件.然后,测试代码可以将线程代码从接口中的一个点移动到下一个点.
最后(如果你已经解开了足够的东西,你可以做更早的事情然后这很容易)你可以运行测试中的应用程序的多线程部分的大部分,并确保你得到你期望的结果; 你可以使用线程的优先级,甚至可以添加几个测试线程,只需吃CPU就可以搞砸了.
现在,您可以在不同的硬件上多次运行所有这些测试......
我还发现在DevPartner BoundsChecker之类的东西下运行测试(或应用程序)可以帮助很多,因为它与线程调度混淆,因此它有时很难找到bug.我还写了一个死锁检测工具,它在程序执行期间检查锁定反转,但我很少使用它.
您可以在此处查看我如何测试多线程C++代码的示例:http: //www.lenholgate.com/blog/2004/05/practical-testing.html
首先,非常感谢您的回复。有关在不同论坛上发布的回复,请参阅;
http://www.sqaforums.com/showflat.php?Cat=0&Number=617621&an=0&page=0#Post617621
http://www.softwaretestingclub.com/forum/topics/testing-approach-for?xg_source=activity
以及以下邮件列表;软件测试@yahoogroups.com
测试花费的时间比预期要长得多,因此这个迟来的答复使我得出结论,即使编码非常简单,向现有应用程序添加多线程在测试方面可能会非常昂贵。这对于 SQA 社区来说可能很有趣,因为那里正在进行越来越多的多线程开发。
根据 Joe Strazzere 的建议,我发现解决错误的最有效方法是通过具有不同输入的自动化。我最终在三台电脑上完成了这项工作,这三台电脑在大约六周的时间里用不同的输入反复运行了一系列测试。最初,我发现每台电脑每天都会崩溃一两次。当我追踪这些问题时,最终发现三台电脑之间每周都会出现一到两个问题,并且在过去两周内我们没有遇到任何进一步的问题。在过去的两周里,我们还对用户进行了 beta 测试,并且正在内部使用该软件。
除了在自动化下改变输入之外,我还从以下方面获得了良好的结果;
添加一个测试选项,允许从配置文件读取互斥超时,而这又可以由我的自动化控制。
将互斥体超时延长到执行线程代码部分预期的典型时间之外,并在超时时引发调试异常。
与调试器 (VS2008) 结合运行自动化,以便在出现问题时有更好的机会进行跟踪。
在不使用调试器的情况下运行,以确保调试器不会隐藏其他与时序相关的错误。
针对正常发布、调试和完全优化的构建运行自动化。FWIW,优化的构建引发了其他构建中无法重现的错误。
发现的错误类型本质上往往很严重,例如取消引用无效指针,甚至在调试器下也需要进行大量跟踪。正如其他地方所讨论的,SuspendThread 和 ResumeThread 函数最终成为罪魁祸首,并且这些函数的所有使用都被互斥体所取代。同样,由于缺乏超时,所有关键部分都被删除。关闭文档和退出程序也是一个错误来源,在一个实例中,文档被破坏,而工作线程仍然处于活动状态。为了克服这个问题,每个线程添加了一个互斥体来控制线程的生命周期,并由文档析构函数获取以确保线程按预期终止。
再次非常感谢您提供的所有详细且多样的答复。下次我参加此类活动时,我会做好更好的准备。
| 归档时间: |
|
| 查看次数: |
6302 次 |
| 最近记录: |