Unittest setUp / ráchDown cho một số thử nghiệm


118

Có một chức năng nào được kích hoạt khi bắt đầu / kết thúc một kịch bản kiểm tra không? Các chức năng setUp và drawDown được kích hoạt trước / sau mỗi lần kiểm tra.

Tôi thường muốn có cái này:

class TestSequenceFunctions(unittest.TestCase):

    def setUpScenario(self):
        start() #launched at the beginning, once

    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)

    def test_sample(self):
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)

    def tearDownScenario(self):
        end() #launched at the end, once

Hiện tại, những setUp và drawDown này là các bài kiểm tra đơn vị và trải rộng trong tất cả các kịch bản của tôi (chứa nhiều bài kiểm tra), một là bài kiểm tra đầu tiên, bài còn lại là bài kiểm tra cuối cùng.


6
Phiên bản nào? Mô-đun mới nhất đã được mở rộng để bao gồm module_setup và module_teardown trong Python 2.7.
S.Lott

3
2.7 cũng giới thiệu các phương thức phân lớp setUpClass () và ráchDownClass (), cho phép bạn có nhiều lớp trong cùng một tệp với thiết lập và chia nhỏ riêng cho từng bộ của chúng.
Theo Fagrell,

Câu trả lời:


132

Kể từ 2,7 (theo tài liệu ) bạn nhận được setUpClasstearDownClassthực thi trước và sau khi các bài kiểm tra trong một lớp nhất định được chạy, tương ứng. Ngoài ra, nếu bạn có một nhóm chúng trong một tệp, bạn có thể sử dụng setUpModuletearDownModule( tài liệu ).

Nếu không, đặt cược tốt nhất của bạn có thể là tạo TestSuite dẫn xuất của riêng bạn và ghi đè run(). Tất cả các cuộc gọi khác sẽ được xử lý bởi cha mẹ và run sẽ gọi mã thiết lập và chia nhỏ của bạn xung quanh một cuộc gọi tới runphương thức của cha mẹ .


71

Tôi có cùng một kịch bản, đối với tôi các phương thức setUpClass và ráchDownClass hoạt động hoàn hảo

import unittest

class Test(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls._connection = createExpensiveConnectionObject()

    @classmethod
    def tearDownClass(cls):
        cls._connection.destroy()

6
Đây phải được cập nhật để trở thành câu trả lời được chấp nhận vì nó hiển thị một ví dụ chính xác và các hàm này PHẢI là các phương thức phân lớp để hoạt động, điều này không được đề cập trong câu trả lời được chấp nhận.
NuclearPeon

1

Đối với python 2.5 và khi làm việc với pydev thì hơi khó. Có vẻ như pydev không sử dụng bộ thử nghiệm, nhưng tìm tất cả các trường hợp thử nghiệm riêng lẻ và chạy tất cả chúng một cách riêng biệt.

Giải pháp của tôi cho điều này là sử dụng một biến lớp như thế này:

class TestCase(unittest.TestCase):
    runCount = 0

    def setUpClass(self):
        pass # overridden in actual testcases

    def run(self, result=None):
        if type(self).runCount == 0:
            self.setUpClass()

        super(TestCase, self).run(result)
        type(self).runCount += 1

Với thủ thuật này, khi bạn kế thừa từ cái này TestCase(thay vì từ cái gốc unittest.TestCase), bạn cũng sẽ kế thừa runCountbằng 0. Sau đó, trong phương thức run, giá runCounttrị của testcase con được kiểm tra và tăng dần. Điều này để lại runCountbiến cho lớp này là 0.

Điều này có nghĩa là di setUpClasschúc chỉ được chạy một lần cho mỗi lớp chứ không phải một lần cho mỗi trường hợp.

Tôi chưa có tearDownClassphương pháp, nhưng tôi đoán có thể tạo ra điều gì đó bằng cách sử dụng bộ đếm đó.


0

Đây là một ví dụ: 3 phương pháp kiểm tra truy cập tài nguyên được chia sẻ, được tạo một lần, không phải cho mỗi lần kiểm tra.

import unittest
import random

class TestSimulateLogistics(unittest.TestCase):

    shared_resource = None

    @classmethod
    def setUpClass(cls):
        cls.shared_resource = random.randint(1, 100)

    @classmethod
    def tearDownClass(cls):
        cls.shared_resource = None

    def test_1(self):
        print('test 1:', self.shared_resource)

    def test_2(self):
        print('test 2:', self.shared_resource)

    def test_3(self):
        print('test 3:', self.shared_resource)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.