2016-10-05 2 views
3

학생들이 unittest를 실행하는 가져온 모듈에서 함수를 호출하여 Jupyter Notebook에 코드를 작성할 때 코드를 확인할 수 있기를 바랍니다. 노트북의 전역 범위에서 선택해야하는 개체에 대해 함수를 검사해야하는 경우가 아니면 제대로 작동합니다. 노트북 인 경우Unit 테스트를 통해 Jupyter에서 학생 코드 테스트하기

import unittest 
from IPython.display import Markdown, display 

def printmd(string): 
    display(Markdown(string)) 

class Tests(unittest.TestCase): 

    def check_add_2(self, add_2): 
     val = 5 
     self.assertAlmostEqual(add_2(val), 7) 

    def check_add_n(self, add_n): 
     n = 6 
     val = 5 
     self.assertAlmostEqual(add_n(val), 11) 


check = Tests() 
def run_check(check_name, func, hint=False): 
    try: 
     getattr(check, check_name)(func) 
    except check.failureException as e: 
     printmd('**<span style="color: red;">FAILED</span>**') 
     if hint: 
      print('Hint:', e) 
     return 
    printmd('**<span style="color: green;">PASSED</span>**') 

:

여기 내 check_test 모듈의

In [1]: def add_2(val): 
      return val + 2 

In [2]: def add_n(val): 
      return val + n 

In [3]: import test_checks 

In [4]: test_checks.run_check('check_add_2', add_2) 
     PASSED 

In [5]: test_checks.run_check('check_add_n', add_n) 
     !!! ERROR !!! 

여기에 오류가 놀라운 일되지 않습니다 add_n 내가 check_add_n에 정의 된 n에 대해 알고하지 않습니다. 노트북에

In [6]: def add_n(val, default_n=None): 
      if default_n: 
       n = default_n 
      return val + n 

다음 시험에 n을 통과 :

그래서 나는 내가 좋아하는 일을 할 수있는 생각에 도착

def check_add_n(self, add_n): 
     val = 5 
     self.assertAlmostEqual(add_n(val, 6), 11) 

하지만이 아래로 나에게 UnboundLocalError 두통의 원인 심지어 if 절 내에서도 n이라는 할당으로 인해 노트북이 필요합니다. 이는 노트북이 필요할 때 전체 범위에서 n을 픽업하는 것을 분명히 막고 있습니다.

의심의 여지가 없으므로 add_n에 이 전달되었다고 주장하고 싶지 않습니다. 사용되는 많은 개체가 있지만 테스트 할 함수에 의해 변경되지는 않을 수 있으며 바깥 범위에서 해결되기를 원합니다. .

아이디어가 있습니까?

+0

나는 당신의 질문에 답하는 동안 나는'add_n' 함수가 꽤 못 생기는 것을 발견했다. 차라리 학생들이'def make_adder (n) : return lambda val : val + n'과'add_n = make_adder (n)'같은 함수를 작성하고'n' ​​로컬을 유지하도록 할 것입니다. – Bakuriu

+0

대답 - 이것은 큰 도움이됩니다. 그러나 당신이 제안하는보다 고급 코드가 초보자로서 이해하기 쉽다고 확신 할 수는 없습니다. – xnx

답변

2

당신은 import __main__ 노트북 범위에 액세스 할 수 있습니다

import unittest 
from IPython.display import Markdown, display 

import __main__ 


def printmd(string): 
    display(Markdown(string)) 

class Tests(unittest.TestCase): 

    def check_add_2(self, add_2): 
     val = 5 
     self.assertAlmostEqual(add_2(val), 7) 

    def check_add_n(self, add_n): 
     __main__.n = 6 
     val = 5 
     self.assertAlmostEqual(add_n(val), 11) 


check = Tests() 
def run_check(check_name, func, hint=False): 
    try: 
     getattr(check, check_name)(func) 
    except check.failureException as e: 
     printmd('**<span style="color: red;">FAILED</span>**') 
     if hint: 
      print('Hint:', e) 
     return 
    printmd('**<span style="color: green;">PASSED</span>**') 

이 나에게 PASSED 출력을 제공합니다.


작동하기 때문에 당신이 파일이 __main__ 모듈로 sys.modules에 저장되어있는 파이썬 파일을 실행할 때. 이것은 정확하게 if __name__ == '__main__':이라는 관용구가 사용 된 이유입니다. 이러한 모듈을 가져올 수 있으며 모듈 캐시에 이미 있기 때문에 다시 실행하지 않습니다.

관련 문제