Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

3상 패턴으로 더 나은 테스트 작성

(이것은 Practicing Rails에서 발췌한 것입니다. 첫 번째 챕터를 무료로 받으려면 여기에서 가입하세요!)

따라서 새 앱을 개발 중이고 Rails에서 방금 테스트를 생성했습니다.

테스트/모델/bug_test.rb
require 'test_helper'

class BugTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end

주석을 제거하고 이름을 정하면 테스트를 작성할 준비가 된 것입니다. 하지만 그럼? 무엇을 먼저 쓰나요? 테스트 코드는 어떻게 생겼습니까?

간단한 패턴을 따른다면 쪼개진 코드 라인을 명확하고 구조화된 테스트 케이스로 바꿀 수 있습니다.

3단계 테스트 패턴

테스트 사례는 세 단계로 작동해야 합니다.

  1. 먼저 몇 가지 항목을 설정합니다("정렬")
  2. 그런 다음, 당신은 무언가를 합니다("행동")
  3. 그러면 예상했던 일이 실제로 일어났는지 확인합니다. ("주장")

예를 들어 Ruby의 배열에서 메서드를 테스트한다고 상상해보십시오. 이 패턴에 따라 테스트는 다음과 같을 수 있습니다.

test "Array#sort will sort an array of numbers" do
  # arrange
  unsorted_array = [7, 4, 2, 3]
  
  # act
  sorted_array = unsorted_array.sort

  # assert
  assert_equal [2, 3, 4, 7], sorted_array
end

충분히 간단합니다. 그러나 테스트의 모든 부분에는 갈 곳이 있으며 테스트의 각 단계는 거의 작성 방법을 알려줍니다.

때로는 Arrange 단계가 필요하지 않거나 Act 및 Assert 단계가 결합됩니다. 하지만 테스트를 작성할 때 세 단계 모두에 대해 생각하는 것이 여전히 도움이 됩니다.

어설션 단계가 있습니다

Assert 단계에는 트릭이 있습니다. Act 단계에서 Assert 단계에서 사용한 것과 동일한 논리를 사용하면 안 됩니다. 당신은 항상 같은 답을 얻기 위해 두 가지 길을 택해야 합니다. 그렇지 않으면 Assert 단계에서 다시 호출되기 때문에 호출하는 코드의 버그를 눈치채지 못할 것입니다.

예를 들어, 수학을 한다면:

test "average returns the average of a set of numbers" do
  # arrange
  numbers = [1, 2, 3, 4]
  
  # act
  average = numbers.average

  # assert
  
  # this is bad
  assert_equal [1, 2, 3, 4].average, average

  # this is better
  assert_equal 2.5, average
end

[1, 2, 3, 4].average 호출 다시 Assert 단계에서 average 거의 무엇이든 반환할 수 있음 그리고 그 주장은 여전히 ​​통과할 것입니다.

여기, 아주 명확합니다. 그러나 상황이 더 복잡해지더라도 동일한 코드를 두 번 실행하지 않도록 하십시오. 그렇지 않으면 메소드가 호출되었는지만 확인하는 것입니다. , 예상대로 작동하지 않았습니다.

일반적으로 답에 대한 두 번째 경로를 선택하는 가장 쉬운 방법은 직접 답을 찾아 하드코딩하는 것입니다. 부서지기 쉬울 수 있지만 자신도 모르게 테스트가 깨지는 것보다는 낫습니다.

3단계가 필요한 이유

테스트를 세 단계로 나누면 더 간단한 질문에 답할 수 있습니다. "이 테스트를 어떻게 작성해야 하나요?" 대신 "이 테스트를 어떻게 설정해야 하나요?", "테스트 중인 항목은 무엇인가요?", "대답은 어떤 모양이어야 하나요?"와 같은 각 단계에 집중할 수 있습니다.

이 질문들은 여전히 ​​쉬운 답이 아닐 수 있지만, 답은 전체 시험을 한 번에 생각하는 것보다 훨씬 쉬울 것입니다. 운이 좋다면 관련 테스트 간에 단계를 공유할 수도 있으므로 다음 테스트를 작성하는 데 훨씬 덜 수고롭습니다.