常见的测试错误

92 阅读6分钟

0号错误

你可能犯的最大错误之一是错过了我的完整测试JS课程。(看到我做了什么了吗?)

错误1:测试实施细节

我经常强调这一点(阅读更多)。这是因为这是测试中的一个巨大问题,导致测试不能给人以足够的信心。这里有一个非常简单的测试例子,是测试实现细节的:

// counter.js
import * as React from 'react'

export class Counter extends React.Component {
  state = {count: 0}
  increment = () => this.setState(({count}) => ({count: count + 1}))
  render() {
    const {count} = this.state
    return <button onClick={this.increment}>{count}</button>
  }
}

// __tests__/counter.js
import * as React from 'react'
// (it's hard to test implementation details with React Testing Library,
//  so we'll use enzyme in this example 😅)
import {mount} from 'enzyme'
import {Counter} from '../counter'

test('the increment method increments count', () => {
  const wrapper = mount(<Counter />)
  // don't ever do this:
  expect(wrapper.instance().state.count).toBe(0)
  wrapper.instance().increment()
  expect(wrapper.instance().state.count).toBe(1)
})

那么,为什么是测试实现细节?为什么测试实现细节会如此糟糕?这里有两个关于关注实现细节的测试的真相,比如上面的测试:

  1. 我可以破坏代码,而不是测试(例如:我可以在按钮的onClick分配中打错字)。
  2. 我可以重构代码并破坏测试(例如:我可以将增量重命名为 updateCount)。

这些类型的测试是最难维护的,因为你要不断地更新它们(由于第2点),而且它们甚至不能给你带来可靠的信心(由于第1点)。

我的课程中,我将向你展示编写测试的正确方法,避免这种常见的错误。

错误二:100%的代码覆盖率

试图对一个应用程序进行100%的代码覆盖是一个完全的错误,我经常看到这种情况。有趣的是,我通常认为这是来自管理层的授权,但无论它来自哪里,它都是出于对代码覆盖率报告可以和不能告诉你对你的代码库的信心的误解。

代码覆盖率告诉你什么。

  • 这段代码在你的测试中被运行了。

代码覆盖率不能告诉你什么。

  • 这段代码将根据业务需求工作。
  • 这段代码与应用程序中的所有其他代码一起工作。
  • 应用程序不可能进入一个坏的状态

代码覆盖率报告的另一个问题是,每一行被覆盖的代码在整个覆盖率报告中的作用与其他任何一行一样大。这意味着你可以通过在 "关于我们 "的页面上添加测试来增加你的代码覆盖率,就像你在 "结账 "页面上添加测试一样多。其中一件事比另一件事更重要,而代码覆盖率并不能让你对你的代码库有任何了解......

对于一个好的代码覆盖率数字,没有一个放之四海而皆准的解决方案。每个应用程序的需求都是不同的。我不太关心代码覆盖率,而更关心我对我的应用程序的重要部分的覆盖率有多大信心。我已经确定了我的应用程序代码中哪些部分是关键的之后,我使用代码覆盖率报告来帮助我。它可以帮助我知道我是否遗漏了一些代码覆盖的边缘情况,但我的测试却没有。

我应该注意到,对于开源模块来说,100%的代码覆盖率是完全合适的,因为它们通常更容易保持100%的覆盖率(因为它们更小,更独立),而且由于它们在多个项目中共享,它们是真正重要的代码。

我在前几天的直播中谈到了这个问题,请看吧

错误三:重复测试

人们对端到端(E2E)测试最大的抱怨之一是,与集成或单元测试相比,它们是多么缓慢和脆弱。你不可能让一个E2E测试和一个单元测试一样快,一样可靠,这是不可能的。也就是说,单一的E2E测试会比单一的单元测试给你带来更多的信心。事实上,有一些信心的角落是不可能从单元测试中得到的,而E2E测试是很好的,所以绝对值得拥有它们

但这并不意味着我们不能使我们的E2E测试比你过去可能经历的更快、更可靠。重复测试是人们在编写E2E测试时常犯的一个错误,它导致了性能和可靠性的下降。

测试应该总是孤立地工作。所以这意味着每个测试都应该作为不同的用户来执行。因此,每个测试都需要作为一个全新的用户来注册和登录,对吗?对的。所以你需要为注册和登录页面准备一些页面对象,因为你将在每个测试中运行这些页面,对吗?错了!这是个错误!

让我们退一步。你为什么要写测试?这样你就可以有信心地发送你的应用程序,因为事情不会被破坏比方说,你有100个需要认证用户的测试。你需要运行多少次 "快乐之路 "的注册流程才能确信该流程是有效的?100次还是1次?我认为可以这么说,如果它工作过一次,那么它应该每次都工作。所以那些额外的99次运行并没有给你带来任何额外的信心。这是在浪费精力。

那么,你是怎么做的呢?我的意思是,我们已经确定了你的测试应该是孤立工作的,所以你不应该在它们之间共享一个用户。你可以这样做:在你的测试中进行同样的HTTP调用,当你注册和登录一个新的用户时,你的应用程序也会这样做。这些请求将比在页面上点击和打字快得多,而且假阴性失败的机会也少。只要你保留一个真正测试注册/登录流程的测试,你就不会失去对这个流程工作的信心。

总结

永远记住你测试的原因是关于信心。如果你的测试所做的事情没有给你带来更多的信心,那么考虑你是否可以停止做它

祝您好运!