4

每个版本似乎我们的客户都会发现我们的软件存在一些老问题。它使每个版本看起来都有多个错误,而实际上我们的新代码通常是可靠的。

我们已经尝试实施一些额外的测试,我们让测试人员每月对单个应用程序进行数小时的每月回归测试,以保持领先于小问题。我们将此过程称为我们的软件强化过程,但似乎我们没有捕捉到足够多的错误,而且感觉就像一个非常落后的过程,因为总是有新的代码要编写。

这种测试有诀窍吗?我是否需要一次针对一项特定功能?

4

6 回答 6

4

当你开发你的测试程序时,你可能想要实现这些类型的测试:

  • 单元测试(测试项目的各个组件以测试其功能),这些测试很重要,因为它们允许您查明错误可能来自软件的哪个位置。基本上在这些测试中,您将测试单个功能并使用模拟对象来模拟行为,返回其他对象/实体的值。

  • 你提到的回归测试

  • 特性测试,一个示例可以在自动生成的输入(模拟用户输入)上自动运行程序,存储结果并将每个版本的结果与这些结果进行比较。

一开始这将非常繁重,但是随着更多版本和更多错误修复被添加到自动非回归测试中,您应该开始节省时间。

不要陷入设计大量愚蠢测试的陷阱,这一点非常重要。测试应该让您的生活更轻松,如果您花太多时间了解测试在哪里出错,您应该重新设计测试,例如它们可以为您提供更好的信息/对问题的理解,以便您可以快速定位问题。

根据您的环境,这些测试可以链接到开发过程。

在我的环境中,我们使用 SVN 进行版本控制,机器人针对每个修订版运行测试,并返回失败的测试和消息,其中包含破坏它的修订版名称和贡献者(他的登录名)。

编辑:

在我的环境中,我们使用 C++ 和 C# 的组合来提供金融中使用的分析,代码是 C++ 并且相当陈旧,而我们正试图将接口迁移到 C# 并保留 C++ 中的分析核心(主要是因为速度要求)

大多数 C++ 测试都是手写的单元测试和回归测试。

在 C# 方面,我们使用 NUnit 进行单元测试。我们有几个一般测试。

我们有一个 0 警告政策,我们明确禁止人们提交生成警告的代码,除非他们能够证明为什么绕过这部分代码的警告是有用的。我们也有关于异常安全、设计模式的使用和许多其他方面的约定。

明确设置约定和最佳实践是提高代码质量的另一种方法。

于 2009-12-03T17:37:09.930 回答
3

这种测试有诀窍吗?

你说:“我们让测试人员每个月对一个应用程序进行数小时的月度回归测试,以保持领先于小问题。”

我猜“回归测试”是指“手动行使旧功能”。

你应该决定你是否正在寻找以前从未发现过的旧错误(这意味着,运行你以前从未运行过的测试);或者,您是否正在重复先前运行的测试以验证先前测试的功能是否未更改。这是两个相反的东西。

“回归测试”对我来说意味着你正在做后者。

如果问题是“客户发现我们的软件存在一些旧问题”,那么您的客户正在运行您以前从未运行过的测试(在这种情况下,要找到这些问题,您需要运行旧软件的测试),或者他们正在寻找您之前测试并发现的错误但您在找到它们之后显然从未修复过。

我是否需要一次针对一项特定功能?

你到底想做什么:

  • 在客户发现之前发现错误?
  • 让客户相信开发没有什么问题?
  • 在测试上花费尽可能少的时间?

非常普遍的建议是虫子生活在家庭中:所以当你发现虫子时,寻找它的父母、兄弟姐妹和表亲,例如:

  • 您可能在其他模块中也有同样的错误
  • 这个模块可能比其他模块有更多错误(也许是某个休息日的某个人写的),所以在这个模块中寻找所有其他类型的错误
  • 也许这是一类问题(性能问题或内存不足问题)中的一个,它表明需要更好的测试覆盖率的整个区域(或整个类型的需求)

其他建议是与管理客户期望有关:您说,“它使每个版本看起来都有多个错误,而实际上我们的新代码通常是可靠的”,好像真正的问题是错误地认为错误是新写的。

这感觉像是一个非常次要的过程,因为总是有新的代码要写

软件开发不会在后台或刻录​​机上发生:要么有人在开发它,要么他们没有。管理层必须决定是否分配任何人来完成这项任务(即寻找现有的以前未发现的错误,或修复以前发现但尚未报告的错误),或者他们是否更愿意专注于新的开发并让客户进行错误检测。


编辑:值得一提的是,测试并不是发现错误的唯一方法。还有:

  • 非正式设计评审 (35%)
  • 正式设计检查 (55%)
  • 非正式代码审查 (25%)
  • 正式的代码检查 (60%)
  • 个人桌面检查代码 (40%)
  • 单元测试 (30%)
  • 组件测试 (30%)
  • 集成测试 (35%)
  • 回归测试 (25%)
  • 系统测试 (40%)
  • 低容量 Beta 测试(<10 个站点)(35%)
  • 大容量 Beta 测试(>1000 个站点)(70%)

我放在每个旁边的百分比是每种技术的缺陷消除率的度量(取自 McConnel 的Software Estimation书的第 243 页)。两种最有效的技术似乎是正式的代码检查和大量的 beta 测试。

所以引入正式的代码审查可能是一个好主意:这可能比黑盒测试更能检测缺陷。

于 2009-12-08T04:50:40.413 回答
1

编码结束后,首先应该进行单元测试。在这里你会得到一些应该修复的错误,你应该执行另一轮单元测试来确定是否有新的错误出现。完成单元测试后,您应该进行功能测试。

您在这里提到您的测试人员每月执行一次回归测试,但仍然有旧的错误出现。所以最好和测试人员坐在一起,审查测试用例,因为我觉得它们需要定期更新。在审查过程中,还要强调错误出现在哪个模块或功能上。强调这些区域并在这些区域中添加更多测试用例,并将它们添加到您的回归测试用例中,以便一旦新构建到来,这些测试用例就应该运行。

如果您的项目是长期项目,您可以再尝试一件事,那么您应该与测试人员交谈以自动化回归测试用例。它将帮助您在晚上等下班时间运行测试用例,并在第二天获得结果。此外,回归测试用例应该更新,因为当回归测试用例没有定期更新时出现主要问题,并且通过运行旧的回归测试用例和新的进展测试用例,您会丢失一些未测试的模块。

于 2009-12-08T04:22:13.947 回答
1

这里有很多关于单元测试的讨论,我完全同意。我希望 Josh 明白单元测试是一个机械化的过程。我不同意 PJ 的观点,因为应该在编写应用程序之前而不是之后编写单元测试。这称为 TDD 或测试驱动开发。

有些人编写单元测试来执行中间层代码,但忽略了测试 GUI 代码。那是不谨慎的。您应该为应用程序中的所有层编写单元测试。

由于单元测试也是代码,因此您的测试套件存在 QA 问题。代码覆盖率好吗?单元测试中是否存在误报/否定错误?你在测试正确的东西吗?您如何确保质量保证过程的质量?基本上,这个问题的答案归结为同行评议和文化价值观。团队中的每个人都必须致力于良好的测试卫生。

越早将错误引入您的系统,它在系统中停留的时间越长,移除它的难度和成本就越高。这就是为什么您应该研究所谓的持续集成。如果设置正确,持续集成意味着在您签入当天的更改后不久,项目就会被编译并使用全套单元测试运行。

如果构建或单元测试失败,那么违规的编码器和构建大师会收到通知。他们与团队负责人一起确定最合适的路线修正应该是什么。有时它就像修复问题并签入一样简单。构建大师和团队负责人需要参与以确定需要额外干预的任何总体模式。例如,家庭危机可能导致开发人员的编码质量触底。如果没有 CI 和一些管理监督,您可能需要六个月的时间才能意识到发生了什么并采取纠正措施。

你没有提到你的开发环境是什么。如果您是 J2EE 商店,那么我建议您查看以下内容。

  • 用于持续集成的 CruiseControl
  • 源代码版本控制的 Subversion,因为它与 CruiseControl 很好地集成
  • Spring,因为 DI 使单元测试更容易机械化以实现持续集成
  • 用于单元测试中间层的 JUnit
  • 用于对 GUI 进行单元测试的 HttpUnit
  • 用于压力测试的 Apache JMeter
于 2009-12-08T05:33:41.123 回答
1

回过头来为(所有)现有的东西实施测试策略是一件痛苦的事。时间长,难度大,没人愿意做。但是,我强烈建议在出现新错误时,围绕该错误开发测试。如果您没有收到关于它的错误报告,那么要么是(a)有效,要么(b)用户不在乎它不起作用。无论哪种方式,测试都是在浪费您的时间。

一旦确定,就编写一个变红的测试。现在。然后修复错误。确认它已修复。确认测试现在是绿色的。当新的错误出现时重复。

于 2009-12-11T14:04:33.883 回答
0

很抱歉这么说,但也许你只是测试不够,或者太晚了,或者两者兼而有之。

于 2009-12-07T20:32:14.413 回答