Unittest setUp / tearDown สำหรับการทดสอบหลายครั้ง


119

มีฟังก์ชันที่เริ่มต้น / สิ้นสุดของสถานการณ์การทดสอบหรือไม่? ฟังก์ชัน setUp และ tearDown จะเริ่มทำงานก่อน / หลังการทดสอบทุกครั้ง

ฉันมักจะต้องการสิ่งนี้:

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

สำหรับตอนนี้ setUp และ tearDown เหล่านี้เป็นการทดสอบหน่วยและแพร่กระจายในทุกสถานการณ์ของฉัน (มีการทดสอบจำนวนมาก) รายการหนึ่งเป็นการทดสอบครั้งแรกอีกรายการหนึ่งเป็นการทดสอบครั้งสุดท้าย


6
เวอร์ชั่นไหน โมดูล unittest ได้รับการขยายเพื่อรวม module_setup และ module_teardown ใน Python 2.7
ล็อต

3
2.7 ยังแนะนำวิธีการเรียน setUpClass () และ tearDownClass () ซึ่งจะช่วยให้คุณมีหลายคลาสในไฟล์เดียวกันโดยมีการตั้งค่าและการแยกต่อชุดของตนเอง
ต่อ Fagrell

คำตอบ:


132

ณ 2.7 (ตามเอกสารประกอบ ) คุณจะได้รับsetUpClassและtearDownClassรันก่อนและหลังการทดสอบในคลาสที่กำหนดตามลำดับ หรือหากคุณมีกลุ่มในไฟล์เดียวคุณสามารถใช้setUpModuleและtearDownModule( เอกสารประกอบ )

มิฉะนั้นทางออกที่ดีที่สุดของคุณอาจจะเป็นในการสร้างของคุณเองได้มาTestSuiterun()และแทนที่ การโทรอื่น ๆ ทั้งหมดจะได้รับการจัดการโดยผู้ปกครองและการเรียกใช้จะเรียกการตั้งค่าและรหัสการฉีกขาดของคุณโดยrunใช้วิธีการของผู้ปกครอง


72

ฉันมีสถานการณ์เดียวกันสำหรับฉันวิธี setUpClass และ tearDownClass ทำงานได้อย่างสมบูรณ์แบบ

import unittest

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

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

6
สิ่งนี้ควรได้รับการอัปเดตให้เป็นคำตอบที่ยอมรับเนื่องจากแสดงตัวอย่างที่ถูกต้องและฟังก์ชันเหล่านี้ต้องเป็นวิธีการเรียนเพื่อให้ทำงานได้ซึ่งไม่ได้กล่าวถึงในคำตอบที่ยอมรับ
NuclearPeon

1

สำหรับ python 2.5 และเมื่อทำงานร่วมกับ pydev มันค่อนข้างยาก ดูเหมือนว่า pydev ไม่ได้ใช้ชุดทดสอบ แต่พบกรณีทดสอบแต่ละกรณีและเรียกใช้ทั้งหมดแยกกัน

วิธีแก้ปัญหาของฉันคือการใช้ตัวแปรคลาสเช่นนี้:

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

ด้วยเคล็ดลับนี้เมื่อคุณได้รับมรดกจากสิ่งนี้TestCase(แทนที่จะเป็นจากต้นฉบับunittest.TestCase) คุณจะได้รับค่าrunCountของ 0 ด้วยจากนั้นในวิธีการเรียกใช้กล่องrunCountทดสอบลูกจะถูกตรวจสอบและเพิ่มขึ้น สิ่งนี้ทำให้runCountตัวแปรสำหรับคลาสนี้เป็น 0

ซึ่งหมายความว่าsetUpClassจะรันเพียงครั้งเดียวต่อคลาสและไม่ใช่ครั้งเดียวต่ออินสแตนซ์

ฉันยังไม่มีtearDownClassวิธีการ แต่ฉันคิดว่าอาจมีบางอย่างเกิดขึ้นจากการใช้ตัวนับนั้น


0

นี่คือตัวอย่าง: วิธีทดสอบ 3 วิธีเข้าถึงทรัพยากรที่ใช้ร่วมกันซึ่งสร้างขึ้นครั้งเดียวไม่ใช่ต่อการทดสอบ

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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.