2011-02-07 6 views
15

질문에 관심이 있으시면 먼저 설명을 입력하십시오.python에서 py.test 테스트를 생성합니다.

py.test의 컨텍스트에서, 작은 테스트 함수 템플릿 집합에서 많은 수의 테스트 함수를 생성하려면 어떻게해야합니까? 같은

뭔가 :

models = [model1,model2,model3] 
data_sets = [data1,data2,data3] 

def generate_test_learn_parameter_function(model,data): 
    def this_test(model,data): 
     param = model.learn_parameters(data) 
     assert((param - model.param) < 0.1) 
    return this_test 

for model,data in zip(models,data_sets): 
    # how can py.test can see the results of this function? 
    generate_test_learn_parameter_function(model,data) 

설명 :

내가 단위 테스트에 들어갈 열심히 노력하고있어. 나는 '과학'을위한 코드를 작성하는데, 수학적으로 복잡하다고 생각하는 코드를 작성하지만 프로그래밍의 관점에서 보면 그렇게 나쁜 것은 아닙니다. 즉, 테스트 할 함수가 다섯 개 정도 있습니다. 내가 '과학'에서 온 것은 내가 단원 테스트에 처음 온 것을 의미하지만 내 CS 친구들에게 이것이해야할 일이라는 것을 확신시켜 주었다.

필자가 작성한 코드는 모델 구조, 일부 데이터를 취하여 모델의 매개 변수를 학습합니다. 따라서 단위 테스트는 일련의 모델 구조와 미리 생성 된 데이터 집합으로 구성되며, 각 구조 + 데이터를 완성하는 약 5 회의 기계 학습 작업 세트로 구성됩니다.

그래서 코드를 작성하면 작업 당 모델 당 하나의 테스트가 필요합니다. 새로운 모델이 생길 때마다 필자는 5 개의 작업을 복사하여 붙여 넣어야하며, 필자가 가리키는 피클 링 된 구조 + 데이터를 변경해야합니다. 이것은 나에게 나쁜 습관 인 것 같은 느낌이 든다. 이상적으로는 5 가지 템플릿 함수가 각각 5 가지 태스크를 정의한 다음 지정하는 구조 목록에 대한 테스트 함수를 추출하는 것입니다.

Google 검색은 두 가지 모두 내 뇌를 자극하고 나에게 쉬운 방법이 있어야한다고 제안합니다.이 문제는 적절한 프로그래머가 정기적으로 직면해야하기 때문입니다. 거기 있습니까?


편집 : 여기이 문제를 해결하는 방법이 있습니다.

def pytest_generate_tests(metafunc): 
    if "model" in metafunc.funcargnames: 
     models = [model1,model2,model3] 
     for model in models: 
      metafunc.addcall(funcargs=dict(model=model)) 

def test_awesome(model): 
    assert model == "awesome" 

이렇게하면 내 모델 목록의 각 모델에 test_awesome 테스트가 적용됩니다. 감사합니다 @dfichter!

(참고 : 항상 BTW, 통과 주장)

+0

는 일반적으로 동적으로 같은 테스트 코드를 생성하는 나쁜 생각입니다. 왜냐하면 테스트 코드 등을위한 테스트를 작성해야하기 때문입니다.'5 개의 태스크를 복사하여 붙여 넣기 '새로운 코드 나 복사 붙여 넣기 대신에 함수가 정확히 무엇을 모르고 테스트 할 수있는 공통점을 찾을 수 있다고 생각합니다. 다시 테스트 해. – Falmarri

+2

현재 나는 test_learn과 같은 모양의 테스트를 작성 중이다 : 모델의 모델에 대해 : assert (error

+1

@Falmarri : http://en.wikipedia.org/wiki/Copy_and_paste_programming 거의 모든 비용으로 피해주십시오. – lpapp

답변

15

좋은 본능. py.testpytest_generate_tests() 후크로 정확히 무엇을 말하고 있는지 지원합니다. 그들은 그것을 here으로 설명합니다.

+0

이것은 굉장합니다. 나는 내 질문을 편집하여 내가 마지막으로 한 것을 추가한다. 누군가 비슷한 일을 찾기 위해 여기에 온다. –

+0

dfichter, OP에 인라인 예를 들어 줄 수 있니? – lpapp

+0

이것은 이제 부서진 링크입니다. –

4

parametrized fixtures을 사용하여이를 수행 할 수도 있습니다. hook은 Py.test 용 플러그인을 빌드하는 API이지만, 매개 변수화 된 fixtures는 여러 값을 출력하고 추가 테스트 케이스를 생성하는 픽스처를 만드는 일반적인 방법입니다.

플러그인은 프로젝트 전체 (또는 패키지 전체) 기능을위한 것이지 테스트 케이스 특정 기능이 아니며 매개 변수화 된 픽스쳐는 테스트 사례를 위해 일부 리소스를 매개 변수화하는 데 정확히 필요합니다.

그래서 솔루션은으로 다시 작성할 수 있습니다 :

@pytest.fixture(params=[model1, model2, model3]) 
def model(request): 
    return request.param 

def test_awesome(model): 
    assert model == "awesome"