Rspec-core: 디버깅 μ‹€νŒ¨λ₯Ό μœ„ν•œ μΆ”κ°€ μ»¨ν…μŠ€νŠΈλ‘œ λ³€μˆ˜ 값을 μΆ”κ°€ν•˜κΈ° μœ„ν•œ κΈ°λŠ₯ μš”μ²­

에 λ§Œλ“  2019λ…„ 04μ›” 09일  Β·  5μ½”λ©˜νŠΈ  Β·  좜처: rspec/rspec-core

문제의 주제

ν…ŒμŠ€νŠΈ μ„€μ • 방법에 따라 일뢀 ν…ŒμŠ€νŠΈλŠ” λ¬΄μž‘μœ„ μ„€μ • 데이터, μ‹€ν–‰ μ‹œκ°„ λ˜λŠ” ν…ŒμŠ€νŠΈ μ»¨ν…μŠ€νŠΈλ₯Ό κ΅¬μ„±ν•˜λŠ” 기타 λ³€μˆ˜μ™€ 같은 νŠΉμ • μ»¨ν…μŠ€νŠΈμ—μ„œλ§Œ μ‹€νŒ¨ν•©λ‹ˆλ‹€. ν…ŒμŠ€νŠΈκ°€ μ‹€νŒ¨ν•œ νŠΉμ • μ»¨ν…μŠ€νŠΈλ₯Ό λ¦¬λ²„μŠ€ μ—”μ§€λ‹ˆμ–΄λ§ν•˜λŠ” 것은 μ–΄λ €μšΈ 수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ μƒν™©μ—μ„œλŠ” 디버깅 λͺ©μ μœΌλ‘œ 도움이 될 κ²ƒμž…λ‹ˆλ‹€. μ»¨ν…μŠ€νŠΈ λ³€μˆ˜μ˜ 값을 ν‘œμ‹œν•˜λŠ” λ¬Έμžμ—΄λ‘œ μ‹€νŒ¨ λ©”μ‹œμ§€λ₯Ό μΆ”κ°€ν•˜λŠ” κΉ”λ”ν•œ 방법 이 μžˆλ‹€λ©΄.

이것을 μ²˜λ¦¬ν•˜λŠ” ν•œ 가지 방법은 μ‚¬μš©μž μ •μ˜λœ μ‹€νŒ¨ λ©”μ‹œμ§€κ°€ μžˆλŠ” μ‚¬μš©μž μ •μ˜ 맀처λ₯Ό λ§Œλ“œλŠ” 것이라고 μƒκ°ν•˜μ§€λ§Œ μ‹€νŒ¨ λ©”μ‹œμ§€μ— μΆ”κ°€ν•  수 μžˆλŠ” 것이 훨씬 더 λ©‹μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€. μ‚¬μš©μž μ •μ˜ λ©”μ‹œμ§€ 와 μœ μ‚¬ν•˜μ§€λ§Œ κΈ°μ‘΄ μ‹€νŒ¨ λ©”μ‹œμ§€ λ₯Ό

이것은 λΉ„μŠ·ν•œ μ‹œλ„μ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€: https://til.hashrocket.com/posts/a50b3d9313-append-an-rspec-failure-message

λ‹Ήμ‹ μ˜ ν™˜κ²½

ν˜„μž¬ 행동

1) Colors::awesome_color starts with g
     Failure/Error: expect(subject.awesome_color).to start_with 'g'
       expected "red" to start with "g"
     # ./spec/lib/colors.rb:22:in `block (5 levels) in <top (required)>'

미래 행동

1) Colors::awesome_color starts with g
     Failure/Error: expect(subject.awesome_color).to start_with 'g'
       expected "red" to start with "g"
     Context: 
       Variable <strong i="23">@colors</strong> was 'red'. Date was '2019-04-10'
     # ./spec/lib/colors.rb:22:in `block (5 levels) in <top (required)>'

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ„€, μ‚΄νŽ΄λ΄μ•Ό ν•  곳은 (μΆ”κ°€ 좜λ ₯을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄) 우리의 ν¬λ§·ν„°μž…λ‹ˆλ‹€. #2616μ—μ„œ μ œμ•ˆν•œ "μ»¨ν…μŠ€νŠΈ"λ₯Ό μΆ”μ ν•˜λŠ” 방법을 κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ©”λͺ¨ν™”λ˜μ–΄ ν•΄λ‹Ή 값을 μ‚¬μš©)

λͺ¨λ“  5 λŒ“κΈ€

:wave: μ‚¬μš©μž 지정 μ‹€νŒ¨ λ©”μ‹œμ§€λ₯Ό μΆ”κ°€ν•˜λŠ” κΈ°λŠ₯이 이미 μ‘΄μž¬ν•©λ‹ˆλ‹€.

예

expect(subject.awesome_color).to(
  start_with('g'),
  "Expected colour to start with 'g' was #{subject.awesome_color}\n" \
  "Context: <strong i="7">@colours</strong> #{@colours}, Date #{@date}"
)

νŠΉμ • 데이터가 무엇인지 μ˜ˆμ œμ— μ„€μ •ν•  수 μžˆλŠ” PR을 지원할 것이라고 μƒκ°ν•©λ‹ˆλ‹€. κ²°κ΅­ μ»¨ν…μŠ€νŠΈλ₯Ό 포함할 수 μžˆλŠ” 예제 메타데이터가 μžˆμŠ΅λ‹ˆλ‹€... 그런 λ‹€μŒ 이λ₯Ό μ§€μ›ν•˜λ„λ‘ 포맷터λ₯Ό μˆ˜μ •ν•˜λŠ” λ¬Έμ œκ°€ 될 κ²ƒμž…λ‹ˆλ‹€. ..

@JonRowe λ₯Ό λ‹€μ‹œ

예, μ§€κΈˆμ€ κ·Έ μŠ€νƒ€μΌμ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€! μ—¬λŸ¬ ν…ŒμŠ€νŠΈλ₯Ό μœ„ν•΄ κ·Έλ ‡κ²Œν•΄μ•Όν•©λ‹ˆλ‹€. 당신이 μ œμ•ˆν•œ λŒ€λ‘œ context / describe μ—μ„œ 이것을 μ§€μ›ν•˜μ—¬ λͺ¨λ“  것을 κ±΄μ‘°μ‹œν‚€κ³  κΈ°μ‘΄ μ‹€νŒ¨ λ©”μ‹œμ§€λ₯Ό μž¬μ‚¬μš©ν•˜λŠ” 것이 쒋을 κ²ƒμž…λ‹ˆλ‹€. :-)

PR μ œμΆœμ„ κ³ λ €ν•˜λŠ” 것을 염두에 λ‘κ² μŠ΅λ‹ˆλ‹€. μ €λŠ” rspec μ½”λ“œλ² μ΄μŠ€μ— λŒ€ν•΄ 잘 μ•Œμ§€ λͺ»ν•˜μ§€λ§Œ PR μ œμΆœμ„ μ‹œλ„ν•œλ‹€λ©΄ κ·€ν•˜ λ˜λŠ” λ‹€λ₯Έ λˆ„κ΅°κ°€κ°€ μ €λ₯Ό λŒ€λž΅μ μœΌλ‘œ μ˜¬λ°”λ₯Έ λ°©ν–₯으둜 μ•ˆλ‚΄ν•˜κ³  μŠ€νƒ€μΌμ— λŒ€ν•΄ λ…Όμ˜ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? κ³Όκ±°μ—λŠ” λ‹€λ₯Έ μ½”λ“œ κΈ°λ°˜μ—μ„œ 길을 μžƒμ—ˆμ§€λ§Œ rspec이 훨씬 κΉ¨λ—ν•˜κ³  μΆ”λ‘ ν•˜κΈ° μ‰¬μšΈ 것이라고 μƒκ°ν•©λ‹ˆλ‹€.

λ‹€μ‹œ ν•œλ²ˆ κ°μ‚¬ν•©λ‹ˆλ‹€!

λ„€, μ‚΄νŽ΄λ΄μ•Ό ν•  곳은 (μΆ”κ°€ 좜λ ₯을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄) 우리의 ν¬λ§·ν„°μž…λ‹ˆλ‹€. #2616μ—μ„œ μ œμ•ˆν•œ "μ»¨ν…μŠ€νŠΈ"λ₯Ό μΆ”μ ν•˜λŠ” 방법을 κ³ λ €ν•΄μ•Ό ν•©λ‹ˆλ‹€. λ©”λͺ¨ν™”λ˜μ–΄ ν•΄λ‹Ή 값을 μ‚¬μš©)

@gaganawhad μ—κ²Œ 이 정도면 μΆ©λΆ„

  after do |example|
    instance_variables.reject { |v| v =~ /@__/ }.each { |v| puts "#{v}: #{instance_variable_get(v)}" }
  end

메타데이터λ₯Ό μ‚¬μš©ν•˜μ—¬ ν¬ν•¨ν•˜λŠ” 것이 κ°€λŠ₯ν•©λ‹ˆλ‹€. 예:

  after(:dump_ivars) do |example|
    instance_variables.reject { |v| v =~ /@__/ }.each { |v| puts "#{v}: #{instance_variable_get(v)}" }
  end

  describe 'something', :dump_ivars do
  ...
  end

λΆˆν–‰νžˆλ„ after ν›„ν¬μ—μ„œ κΈ°λŒ€μΉ˜λ₯Ό μ„€μ •ν•  수 있고 λ³€κ²½ν•  수 있기 λ•Œλ¬Έμ— ν•΄λ‹Ή λ‹¨κ³„μ—μ„œ μ˜ˆμ œκ°€ 아직 μ‹€νŒ¨ν–ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό 아직 이해할 수 μ—†μŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 단지 aggregate_failures λ₯Ό μ›ν•˜μ§€λ§Œ 단 ν•œ 번의 μ‹€νŒ¨κ°€ μžˆλ”λΌλ„ ν™œμ„± μƒνƒœμž…λ‹ˆλ‹€.

it "parses all entries correctly" do
  result = Parser.call(bar_owner)
  result.each do |entry|
    aggregate_failures("Entry #{entry.id}") do
      expect(entry.name).to match(/\A[A-z][a-z]+\z/)
      expect(entry.owner).to eq(bar_owner)
      expect(entry.tags).to be_present
    end
  end
end

거기에 두 개의 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ 멋진 μ»¨ν…μŠ€νŠΈ( Entry 76: … )λ₯Ό 얻을 수 μžˆμ§€λ§Œ κ·Έ 쀑 ν•˜λ‚˜λ₯Ό μˆ˜μ •ν•˜λ©΄ μ»¨ν…μŠ€νŠΈκ°€ λ‹€μ‹œ 사라지고 μΆ”κ°€ 인쇄λ₯Ό μΆ”κ°€ν•˜μ§€ μ•Šκ³ λŠ” μ΄ν•΄ν•˜κΈ° 맀우 μ–΄λ €μš΄ 였λ₯˜λ‘œ λŒμ•„κ°‘λ‹ˆλ‹€. λ£¨ν”„μ—μ„œ λͺ…령문을 μ‹€ν–‰ν•˜κ³  λ‹€μ‹œ μ‹€ν–‰ν•©λ‹ˆλ‹€.

aggregate_failures 와 μœ μ‚¬ν•˜κ²Œ μž‘λ™ν•˜κ³  μž‘λ™ν•˜λŠ” with_failure_context(extra_message) { … } λ©”μ†Œλ“œλŠ” μ–΄λ–»μŠ΅λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰