2013-05-23 59 views
5

Tôi hiện đang viết một số bài kiểm tra chức năng bằng cách sử dụng mũi. Thư viện tôi đang thử nghiệm thao tác một cấu trúc thư mục.Nhận tên bài kiểm tra hiện tại trong quá trình thiết lập bằng cách sử dụng mũi

Để có được kết quả có thể lặp lại, tôi lưu trữ mẫu cấu trúc thư mục thử nghiệm và tạo bản sao của cấu trúc đó trước khi thực hiện kiểm tra (tôi làm điều đó bên trong các chức năng kiểm tra setup). Điều này đảm bảo rằng tôi luôn luôn có một trạng thái được xác định rõ ở đầu bài kiểm tra.

Bây giờ tôi có hai yêu cầu thêm:

  1. Nếu một thử nghiệm thất bại, tôi muốn cấu trúc thư mục nó hoạt động trên để không được ghi đè hoặc bị xóa, vì vậy mà tôi có thể phân tích vấn đề.
  2. Tôi muốn có thể chạy nhiều thử nghiệm song song.

Cả hai yêu cầu này đều có thể được giải quyết bằng cách tạo một bản sao mới có tên khác cho mỗi thử nghiệm được thực hiện. Vì lý do này, tôi muốn có quyền truy cập vào tên của thử nghiệm hiện đang được thực thi trong hàm setup, để tôi có thể đặt tên cho bản sao một cách thích hợp. Có bất kì cách nào để đạt được điều này không?

Một minh họa mã ví dụ:

def setup_func(test_name): 
    print "Setup of " + test_name 

def teardown_func(test_name): 
    print "Teardown of " + test_name 

@with_setup(setup_func, teardown_func) 
def test_one(): 
    pass 

@with_setup(setup_func, teardown_func) 
def test_two(): 
    pass 

Dự kiến ​​sản lượng:

Setup of test_one 
Teardown of test_one 
Setup of test_two 
Teardown of test_two 

Tiêm tên như một tham số sẽ là giải pháp đẹp nhất, nhưng tôi mở để gợi ý khác là tốt.

Trả lời

1

tôi có một giải pháp mà làm việc cho các chức năng kiểm tra, sử dụng một trang trí tùy chỉnh:

def with_named_setup(setup=None, teardown=None): 
    def wrap(f): 
     return with_setup(
      lambda: setup(f.__name__) if (setup is not None) else None, 
      lambda: teardown(f.__name__) if (teardown is not None) else None)(f) 
    return wrap 

@with_named_setup(setup_func, teardown_func) 
def test_one(): 
    pass 

@with_named_setup(setup_func, teardown_func) 
def test_two(): 
    pass 

này reuses with_setup trang trí hiện có, nhưng liên kết với tên của hàm được trang trí với setupteardown chức năng thông qua như là thông số .

6

Âm thanh như self._testMethodName hoặc self.id() sẽ phù hợp với bạn. Đây là tài sản và phương pháp trên lớp unittest.TestCase. Ví dụ .:

from django.test import TestCase 


class MyTestCase(TestCase): 
    def setUp(self): 
     print self._testMethodName 
     print self.id() 

    def test_one(self): 
     self.assertIsNone(1) 

    def test_two(self): 
     self.assertIsNone(2) 

in:

... 
AssertionError: 1 is not None 
-------------------- >> begin captured stdout << --------------------- 
test_one 
path.MyTestCase.test_one 

--------------------- >> end captured stdout << ---------------------- 
... 
AssertionError: 2 is not None 
-------------------- >> begin captured stdout << --------------------- 
test_two 
path.MyTestCase.test_two 

--------------------- >> end captured stdout << ---------------------- 

Xem thêm:

Hy vọng rằng sẽ giúp.

+0

Hm, nhờ gợi ý này , nhưng tôi thích một giải pháp không yêu cầu xuất phát từ 'unittest.TestCase'. –

+0

Chắc chắn rồi. Tôi nghĩ rằng giải pháp của bạn bằng cách sử dụng '__name__' bên trong một trang trí trông khá tốt. – alecxe

+0

Điều này đã giúp ... cảm ơn ... –

0

Trong trường hợp bạn không muốn phân lớp unittest.TestCase hoặc sử dụng một trang trí tùy chỉnh (như được giải thích trong các câu trả lời khác), bạn có thể nhận được thông tin bằng cách đào bới các cuộc gọi stack:

import inspect 

def get_current_case(): 
    ''' 
    Get information about the currently running test case. 

    Returns the fully qualified name of the current test function 
    when called from within a test method, test function, setup or 
    teardown. 

    Raises ``RuntimeError`` if the current test case could not be 
    determined. 

    Tested on Python 2.7 and 3.3 - 3.6 with nose 1.3.7. 
    ''' 
    for frame_info in inspect.stack(): 
     if frame_info[1].endswith('unittest/case.py'): 
      return frame_info[0].f_locals['self'].id() 
    raise RuntimeError('Could not determine test case')