2012-11-20 3 views
4

필자는 여전히 배우려는 피라미드 앱을 가지고 있습니다. 단위 테스트를 작성해야하지만 요청을 작성하는 방법을 모르겠습니다.단위 테스트시 실제 피라미드 요청을 얻는 방법

나는 피라미드가 DummyRequest이라는 테스트 모듈을 가지고있는 것을 보았습니다.하지만 이것은 공백입니다. 뷰에 전달하면 요청이 실행되는 동안 애트리뷰트가 채워지지 않아 실패 할 것입니다.

그래서 문제는 테스트하는 동안 런타임 요청과 같은 요청을 전달하는 것입니다.

답변

8

단위 테스트 (기능 테스트와 다름)가 발생할 때마다 실현해야 할 것은 작은 "단위"를 테스트한다는 것입니다. 이 유닛 (이 경우보기)에는 "실제"요청이 필요 없으며 완전히 작동하는 시스템이 필요하지 않습니다. 이 견해는 "요청"이라고 부르는 객체가 가질 수있는 기대에 대한 기대를 가지고 있지만, 그 점에 관해서는 실제 요청에서 사용 가능한 모든 것을 요구하지는 않습니다. 이것은 조롱 또는 더미 객체가 작동하는 곳입니다. 뷰를 테스트하고 싶다면 뷰를 수행 할 때 확인할 필요가있는 속성을 뷰에 전달할 수 있습니다.

def main(): 
    config = Configurator() 
    config.add_route('user', '/users/{uid}') 
    return config.make_wsgi_app() 

@view_config(route_name='user', renderer='user_template.mako') 
def user_view(request): 
    uid = request.matchdict['uid'] 
    user = find_user(request, uid) 
    if user is None: 
     raise HTTPNotFound 
    return {'user': user} 

def find_user(request, uid): 
    return request.db.query(User).filter_by(id=uid).first() 

가 큰, 그래서 이것은 진짜보기이며, 당신은 단지 2 속성, matchdictdb을 가지고 요청을해야합니다 것을 알 수 있습니다 :의는 다음과 같은 구성을 가지고 있다고 가정 해 봅시다.

class Test_user_view(unittest.TestCase): 
    def test_it(self): 
     req = DummyRequest() 
     req.db = DummyDB() 
     req.matchdict = {'uid': '3'} 
     result = user_view(req) 
     self.assertEqual(result['user'].id, 3) 

지금 우리가 여기서 해결하지 않는 한 가지 DummyDB의 구현이지만 더 나은 방법은 더미 값을 반환 밖으로 find_user 조롱 할 수 있습니다 : 그런데 우리는 그렇게 할 수 있습니다. 이것은 테스트를 간단하게 유지하고 데이터베이스와의 대화에 휩쓸 리지 않고 뷰 자체에 집중합니다. 그것은 별도의 테스트입니다.

여기에 대한 다른 대답은 기능 테스트를보다 철저하게 다루고 있으며 전체 테스트가 예상대로 작동하는지 확인하는 데 도움이되는 WebTest를 사용해야합니다. 그러나 이것은 단위 테스트의 영역이 아닙니다.

+0

는''request.db.query'' 방법을 구현하기위한 가장 좋은 방법은 어떤 것이 도움이? ''MagicMock()''? 돌이켜 보면, SQLAlchemy의 쿼리는 실제로''User''의 인스턴스를 리턴 할 것이므로,''DummyDB(). query()''메소드가 예상되는 User no를 리턴하도록 모의 할 수 있습니다. –

2

Pyramid unit vs integration vs functional testingPyramid testing guidelines을 아직 확인하지 않은 경우 확인하십시오. IMHO는 DummyRequest를 사용한 단위 테스트와 달리 기능 테스트부터 시작하여 많은 경우에 더 나은 결과를 제공하는 경향이 있습니다 (구현 및 유지 관리가 더 쉽습니다). Webtest (examples in pyramid docs) 또는 Selenium 라이브러리 (또는 둘의 조합) 중 하나를 사용하는 것이 좋습니다. webtest를 사용하면 기본 기능을 테스트 할 수 있으며 테스트는 일반적으로 Selenium보다 빠릅니다. Selenium은 실제로 브라우저를 시작할 수 있으며보다 세부적인 제어가 가능합니다. 브라우저를 실행하기 때문에 셀렌 테스트는 실행하는 데 시간이 오래 걸리는 경향이 있습니다. 엄지 손가락의 좋은 규칙은 기본 테스트 (예 : 특정 페이지가로드되는지 확인하는 것)가 필요한 경우 Webtest를 사용하는 것입니다. 테스트에 브라우저 (예 : 디버깅 자바 스크립트)를 더 많이 제어해야하는 경우 Selenium을 사용해보십시오. 이 라이브러리로 테스트하는 방법에 대한 예제는 위에 링크 된 문서를 확인하십시오.

1

나는 Brian의 답변이 좋다고 생각하지만, "가능한 한 많이 테스트하기 쉬운 코드로 작성하십시오"는 유용한 mantra라고 덧붙입니다. 기능 요구 사항에 익숙하지 않은 모듈 형 라이브러리를 사용하여 손쉽게 단위 테스트 할 수있는 모듈 라이브러리를 작성할 수 있습니다.

기능 테스트는 단위 테스트보다 속도가 더 빠르고 복잡합니다. Brian이 말했듯이 Webtest는 Pyramid를위한 곳입니다. 셀레늄은 아직 더 힘들어지고 복잡해지고 느리다. 조심해; 테스트가 실제 데이터에 의존하면 데이터가 변경 될 때마다 시간이 지날 것입니다. 조롱과 좋은 더미 데이터가 도움이 될 수 있습니다. 필요한 경우 더 높은 수준의보다 어려운 형태의 테스트를 사용하십시오. 재미를 위해서만 사용하면 안됩니다. 아키텍처를 어느 정도 사용하여 필요성을 줄일 수 있습니다.

실제 '어떻게 할 당신'질문에 대답 : 당신이 WebTest에 같은 것을 가지고있는 경우에, 당신은 단지 몇 가지 설정을 한 다음 모두에 편리한 응답 개체가

다음
response = app.get('/form.html') 

그런 짓을 당신이 원할 수있는 정보, 그리고 당신은 당신의 주장을 쓰십시오. tutorial in the docs은 I보다 잘 설명 할 것입니다.

1

당신은 설정 기능에서이 같은 '가짜'요청을 구축 할 수 있습니다 :

request = testing.DummyRequest() 
request.errors = errors.Errors([]) 
request.validated = {} 

그런 다음 테스트 중 하나는 당신이에 대해 테스트 할 매개 변수를 설정합니다. 이처럼 :

request.GET['app_id'] = 'xxxxxxxxx' 
valid_register(request) 
self.assertTrue('app_id' in request.validated) 

희망이

관련 문제