2008-09-29 2 views
61

저는 Ruby에서 Kent Beck의 xUnit을 코딩하여 루비에 대한 이해를 넓히고 있습니다. 파이썬 (켄트가 쓴)은 광범위하게 사용되는 언어로 된 assert() 메소드를 가지고있다. 루비는 그렇지 않습니다. 나는 이것을 추가하는 것이 쉬워야한다고 생각하지만, 커널은 그것을 놓기에 적당한 장소인가?루비의 커널 클래스에 assert() 메소드를 추가하는 관용적 인 루비인가?

BTW, 루비에서 다양한 단위 프레임 워크가 있다는 것을 알고 있습니다 - 이것은 "무언가 완료"하기보다는 루비 관용어를 배우는 연습입니다.

+3

나는 모두를 가르치는 문제가 있습니다. 가르쳐 주시고, 뭔가 끝내십시오. :) –

답변

77

아니요. 모범 사례는 아닙니다. 가장 좋은 비유 루비) (주장하는 단지

raise "This is wrong" unless expr 

을 제기하고 당신이

+22

원한다면'오류 if [expr]'을 사용하여 런타임 오류를 발생시킬 수도 있습니다. –

+6

'fail'은'raise'의 별명입니다, 안 그래요? 둘 다'RuntimeError'를 제공합니다. (아마 하나는 더 관용적입니까?) –

+0

여기에서 "실패"참조 : http://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html –

14

커널 모듈에 assert 메서드를 추가하는 이유는 무엇입니까? 그냥 Assertions 또는 다른 모듈을 사용하지 않는 것이 어떻습니까? 이처럼

:

class Object 
    include Assertions 
end 

면책 조항 : 나는 코드 만 원칙적으로 테스트하지 않았다 당신이 정말로 당신의 주장을해야하는 경우

module Assertions 
    def assert(param) 
    # do something with param 
    end 

    # define more assertions here 
end 

사방이 같은 일을 사용할 수 나는 이렇게 할 것입니다.

+1

이 원숭이가 패치하지 않았습니까? 'Object' 클래스를 변경하고 있습니다. – tsikov

+0

그래, 그게 고전적인 원숭이 패치 야. 이것이 당신이 정말로 assert 메쏘드를 전역 적으로 사용할 수있게해야한다면, 그렇게 할 수있는 방법입니다. 그러나 나는 비 장난감 프로젝트에서 이런 식으로 원숭이 패치를 사용하도록 권하지 않습니다. –

4

내 이해는 당신이 Ruby에 익숙해지기 위해 자신의 테스트 스위트를 작성하고 있다는 것입니다. 따라서 Test :: Unit은 지침으로 유용 할 수 있지만, 이미 찾고있는 것이 아니기 때문일 수 있습니다.

즉 파이썬의 주장은 C의 assert(3)과 더 유사합니다. "이것은 결코 일어나지 않아야"하는 경우를 잡기 위해 단위 테스트를 위해 특별히 설계된 것은 아닙니다.

Ruby의 기본 단위 테스트에서 문제를 보는 경향이있는 경우 각 개별 테스트 케이스 클래스는 TestCase의 하위 클래스이며 전달 된 항목의 유효성을 검사하는 "assert"문을 포함합니다 보고를 위해 기록합니다.

6

그것은이다 특히 관용적하지 처리보다 구체적인 예외 제공하려는 경우 당신은 당신의 자신의 예외를 구현할 수 있지만, 나는 그것이 생각 좋은 생각. 다음과 같이 수행 특히 경우 :

def assert(msg=nil) 
    if DEBUG 
     raise msg || "Assertion failed!" unless yield 
    end 
end 

디버깅 실행하지 않기로 결정한 경우에는 아무런 영향이 없다 그런 식 세트 (또는 다른 편리한 스위치, 나는 과거에 Kernel.do_assert을 사용했습니다).

25

Ruby에서 어설 션을 사용하는 것이 완전히 유효하다고 생각합니다. 그러나 당신은 두 가지 다른 것을 언급하고 있습니다 :

  • xUnit 프레임 워크는 시험 기대치를 확인하는 방법을 assert 사용합니다. 이 코드는 응용 프로그램 코드가 아닌 테스트 코드에서 사용하기위한 것입니다.
  • C, Java 또는 Python과 같은 일부 언어에는 프로그램의 코드 내에서 사용하기 위해 assert 구조가 포함되어있어 무결성에 대한 가정을 검사합니다. 이러한 검사는 코드 자체 내에 구축됩니다. 그것들은 테스트 타임 유틸리티가 아니라 개발 시간 유틸리티입니다.

    assert some_string != "some value" 
    assert clients.empty?, "Isn't the clients list empty?" 
    
    invariant "Lists with different sizes?" do 
        one_variable = calculate_some_value 
        other_variable = calculate_some_other_value 
        one_variable > other_variable 
    end  
    

    을 그리고 그들은 assertinvariant가 비어있는 문으로 평가받을 때문에 비활성화 할 수 있습니다 :

나는 최근에 그것은 당신이 형태로 표현을 쓸 수 .. 또한 a post in my blog explaining its motivationsolid_assert: a little Ruby library implementing a Ruby assertion utility 등을 썼다. 이렇게하면 프로덕션 환경에서 성능 문제를 피할 수 있습니다. 그러나 The Pragmatic Programmers은 비활성화하는 것이 좋습니다. 성능에 실제로 영향을주는 경우에만 비활성화해야합니다.

관용적 인 Ruby 방식이 정상적인 raise 문장을 사용하고 있다고 대답하는 것에 대해서는 표현력이 부족하다고 생각합니다. 독단적 프로그래밍의 황금률 중 하나는 정상적인 예외 처리를위한 어설 션을 사용하지 않는 것입니다. 그들은 완전히 다른 두 가지입니다. 두 구문에 동일한 구문을 사용하면 코드가 더 모호해질 것이라고 생각합니다. 그리고 물론 당신은 그것들을 비활성화시키는 능력을 잃어 버리게됩니다.

The Pragmatic Programmer From Journeyman to MasterCode Complete과 같이 반드시 읽어야하는 두 권의 고전 서적이 전체 섹션을 전용으로 사용하도록 권장하므로 어설 션을 사용하는 것이 좋습니다. 또한 무엇이 독단적 인 프로그래밍이고 언제 사용하는지 (자바를 기반로하지만 개념은 모든 언어에 적용됨) 매우 잘 설명하는 멋진 문서 인 Programming with assertions이 있습니다.

+0

나는 또한 매우 C 지향적 인 Steve Maguire의 "Writing Solid Code"를 제안하지만, assert, testing 전략 및 메소드 구축에도 적용되는 함수를 구성하는 아이디어에 대해 이야기합니다. –

+0

멋진 작은 보석 - 감사합니다. – Yarin

관련 문제