SetUp / tearDown Unittest untuk beberapa pengujian


119

Apakah ada fungsi yang diaktifkan di awal / akhir skenario pengujian? Pengaturan fungsi dan tearDown diaktifkan sebelum / setelah setiap pengujian.

Saya biasanya ingin memiliki ini:

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

Untuk saat ini, setUp dan tearDown ini adalah tes unit dan tersebar di semua skenario saya (berisi banyak tes), satu adalah tes pertama, yang lainnya adalah tes terakhir.


6
Versi yang mana Modul unittest telah diperluas untuk menyertakan module_setup dan module_teardown dengan Python 2.7.
S. Lott

3
2.7 juga memperkenalkan metode kelas setUpClass () dan tearDownClass (), yang memungkinkan Anda memiliki beberapa kelas dalam file yang sama dengan penyiapan dan pembongkaran per suite mereka sendiri.
Per Fagrell

Jawaban:


132

Mulai 2,7 (sesuai dokumentasi ) yang Anda dapatkan setUpClassdan tearDownClassyang dijalankan sebelum dan sesudah pengujian di kelas tertentu dijalankan. Alternatifnya, jika Anda memiliki grup dari mereka dalam satu file, Anda dapat menggunakan setUpModuledan tearDownModule( dokumentasi ).

Jika tidak, taruhan terbaik Anda mungkin akan membuat TestSuite turunan Anda sendiri dan menimpa run(). Semua panggilan lain akan ditangani oleh induk, dan run akan memanggil penyiapan dan kode pembongkaran Anda di sekitar panggilan ke metode induk run.


72

Saya memiliki skenario yang sama, bagi saya metode setUpClass dan tearDownClass bekerja dengan sempurna

import unittest

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

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

6
Ini harus diperbarui menjadi jawaban yang diterima karena ini menunjukkan contoh yang benar dan fungsi ini HARUS menjadi metode kelas agar berfungsi, yang tidak disebutkan dalam jawaban yang diterima.
NuclearPeon

1

Untuk python 2.5, dan saat bekerja dengan pydev, ini agak sulit. Tampaknya pydev tidak menggunakan rangkaian pengujian, tetapi menemukan semua kasus pengujian individual dan menjalankan semuanya secara terpisah.

Solusi saya untuk ini menggunakan variabel kelas seperti ini:

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

Dengan trik ini, ketika Anda mewarisi dari ini TestCase(bukan dari aslinya unittest.TestCase), Anda juga akan mewarisi runCountdari 0. Kemudian dalam metode run,runCount testcase anak diperiksa dan dinaikkan. Ini meninggalkan runCountvariabel untuk kelas ini di 0.

Artinya setUpClass hanya akan dijalankan sekali per kelas dan bukan sekali per instance.

Saya belum memiliki tearDownClassmetode, tapi saya rasa sesuatu bisa dibuat dengan menggunakan penghitung itu.


0

Berikut ini contohnya: 3 metode pengujian mengakses resource bersama, yang dibuat sekali, bukan per pengujian.

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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.