2008-12-07 25 views
6

Đây là lần theo dõi previous question của tôi.Làm cách nào để lấy mũi để khám phá các testcases được tạo động?

Trong câu hỏi trước, các phương pháp đã được khám phá để thực hiện những gì cơ bản là cùng một thử nghiệm đối với toàn bộ nhóm chức năng, đảm bảo kiểm tra không dừng lại ở hàm đầu tiên không thành công.

Giải pháp ưa thích của tôi đã sử dụng một metaclass để chèn động các bài kiểm tra vào một đoạn mã không áp dụng.TestCase. Thật không may, mũi không chọn này vì mũi tĩnh quét cho các trường hợp thử nghiệm.

Làm cách nào để tôi khám phá và chạy một TestCase như vậy? Vui lòng tham khảo here để biết ví dụ về TestCase được đề cập.

+0

Bạn đã thử giải pháp của mình chưa? Nó không dựa trên bất kỳ phép thuật nào, bộ kết quả sẽ được phát hiện. – muhuk

+0

Tôi có, xem nhận xét trong chuỗi gốc. Có lẽ có một tùy chọn cấu hình cho nó, hoặc một số cách để thiết lập một "mục tiêu giả" cho mũi? – saffsd

+1

BTW, tôi đã giải quyết vấn đề này mà không cần đến máy phát thử nghiệm của mũi (nó được giới hạn mà bạn không thể sử dụng nó cho các lớp con của 'unittest.TestCase'). Xem: http://stackoverflow.com/questions/5176396/nose-unittest-testcase-and-metaclass-auto-generated-test-methods-not-discover/5177625#5177625 – Santa

Trả lời

7

Mũi có tính năng "trình tạo thử nghiệm" cho các nội dung như thế này. Bạn viết một hàm máy phát điện để sinh ra mỗi hàm "test case" mà bạn muốn nó chạy, cùng với các arg của nó. Sau dụ trước đây của bạn, điều này có thể kiểm tra từng chức năng trong một thử nghiệm riêng biệt:

import unittest 
import numpy 

from somewhere import the_functions 

def test_matrix_functions(): 
    for function in the_functions: 
     yield check_matrix_function, function 

def check_matrix_function(function) 
    matrix1 = numpy.ones((5,10)) 
    matrix2 = numpy.identity(5) 
    output = function(matrix1, matrix2) 
    assert matrix1.shape == output.shape, \ 
      "%s produces output of the wrong shape" % str(function) 
0

Bạn có thể thử để tạo ra các lớp testcase với kiểu()

class UnderTest_MixIn(object): 

    def f1(self, i): 
     return i + 1 

    def f2(self, i): 
     return i + 2 

SomeDynamicTestcase = type(
    "SomeDynamicTestcase", 
    (UnderTest_MixIn, unittest.TestCase), 
    {"even_more_dynamic":"attributes .."} 
) 

# or even: 

name = 'SomeDynamicTestcase' 
globals()[name] = type(
    name, 
    (UnderTest_MixIn, unittest.TestCase), 
    {"even_more_dynamic":"attributes .."} 
) 

này nên được tạo ra khi mũi cố gắng nhập test_module của bạn để nó nên làm việc.

Ưu điểm của phương pháp này là bạn có thể tạo nhiều kết hợp kiểm tra động.

2

Nose không quét kiểm tra tĩnh, vì vậy bạn có thể sử dụng metaclass phép thuật để làm bài kiểm tra mà Nose tìm thấy.

Phần cứng là kỹ thuật metaclass tiêu chuẩn không đặt thuộc tính func_name chính xác, đó là những gì mũi tìm kiếm khi kiểm tra xem các phương pháp trên lớp của bạn là kiểm tra hay không.

Đây là một metaclass đơn giản. Nó xem xét thông qua fict dict và thêm một phương thức mới cho mọi phương thức mà nó tìm thấy, khẳng định rằng phương thức mà nó tìm thấy có một docstring. Những phương pháp tổng hợp mới này được đặt tên là "test_%d" %i.

import new 
from inspect import isfunction, getdoc 

class Meta(type): 
    def __new__(cls, name, bases, dct): 

     newdct = dct.copy() 
     for i, (k, v) in enumerate(filter(lambda e: isfunction(e[1]), dct.items())): 
      def m(self, func): 
       assert getdoc(func) is not None 

      fname = 'test_%d' % i 
      newdct[fname] = new.function(m.func_code, globals(), fname, 
       (v,), m.func_closure) 

     return super(Meta, cls).__new__(cls, 'Test_'+name, bases, newdct) 

Bây giờ, chúng ta hãy tạo ra một lớp mới sử dụng metaclass này

class Foo(object): 
    __metaclass__ = Meta 

    def greeter(self): 
     "sdf" 
     print 'Hello World' 

    def greeter_no_docstring(self): 
     pass 

Khi chạy, Foo thực sự sẽ được đặt tên Test_Foo và sẽ có greeter, greeter_no_docstring, test_1test_2 như các phương pháp của nó. Khi tôi chạy nosetests trong hồ sơ này, đây là kết quả:

$ nosetests -v test.py 
test.Test_Foo.test_0 ... FAIL 
test.Test_Foo.test_1 ... ok 

====================================================================== 
FAIL: test.Test_Foo.test_0 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/Library/Frameworks/EPD64.framework/Versions/7.3/lib/python2.7/site-packages/nose/case.py", line 197, in runTest 
    self.test(*self.arg) 
    File "/Users/rmcgibbo/Desktop/test.py", line 10, in m 
    assert getdoc(func) is not None 
AssertionError 

---------------------------------------------------------------------- 
Ran 2 tests in 0.002s 

FAILED (failures=1) 

metaclass này là không thực sự hữu ích như là, nhưng nếu bạn thay vì sử dụng Meta không phải là một metaclass thích hợp, nhưng như nhiều hơn một metaclass chức năng (tức là lấy một lớp làm đối số và trả về một lớp mới, một lớp được đổi tên để mũi sẽ tìm thấy nó), sau đó nó là hữu ích. Tôi đã sử dụng phương pháp này để tự động kiểm tra rằng các tài liệu tuân theo tiêu chuẩn Numpy như một phần của bộ kiểm tra mũi.

Ngoài ra, tôi đã gặp phải rất nhiều sự cố khi đóng cửa hợp lý với hoạt động mới.chức năng, đó là lý do tại sao mã này sử dụng m(self, func) trong đó func được tạo thành đối số mặc định. Sẽ tự nhiên hơn khi sử dụng một đóng cửa trên value, nhưng điều đó dường như không hoạt động.

Các vấn đề liên quan