ทดสอบค่าขอบเขตล่างและบนใน Python

Sep 19 2020

ฟังก์ชันรหัส

รหัสต่อไปนี้จะทดสอบว่าค่าที่ผู้ใช้ระบุสำหรับขอบเขตล่างและขอบเขตบนของคุณสมบัติสองคุณสมบัติ:

  1. ขอบเขตล่างมีขนาดเล็กกว่าขอบเขตบน
  2. ค่ามากกว่า 0 (บวก)

เนื่องจากขั้นแรกจะตรวจสอบว่าขอบเขตล่างมีขนาดเล็กกว่าขอบเขตบนหรือไม่จึงตรวจสอบโดยปริยายว่าขอบเขตบนมีขนาดใหญ่กว่า 0 หรือไม่หากทดสอบว่าขอบเขตล่างมีขนาดใหญ่กว่า 0 หรือไม่ดังนั้นสิ่งที่ฉันต้องพิจารณาคือ: ฉันสามารถทำให้โค้ดมากกว่านี้ได้ กระชับโดยไม่ใส่เครื่องหมายถูกสำหรับ "คือขอบเขตบนที่ใหญ่กว่า 0"

รหัส

# Object getting labels
class Get_labels:
    def __init__(self,lower_bound,upper_bound,configuration_name):
        self.lower_bound = lower_bound
        self.upper_bound = upper_bound
        self.configuration_name = configuration_name
        self.check_threshold_validity()
          
                            
    # Verifies if the chosen thresholds are valid values.
    def check_threshold_validity(self):
        if self.lower_bound>=self.upper_bound:
            raise Exception(f'Sorry, the lower threshold={self.lower_bound} should be smaller than the upper bound={self.upper_bound} for configuration={self.configuration_name}')
        
        # checks if lower bound (and implicitly upper bound) are above zero
        if self.lower_bound<=0:
            raise Exception(f'Sorry, the lower threshold={self.lower_bound} should be larger than 0 for configuration={self.configuration_name}')
        
if __name__ == '__main__':
    get_labels = Get_labels(-1,25,"first")

ทางเลือกในการออกแบบ

อย่างไรก็ตามหากมีการแก้ไขโค้ดอาจไม่ชัดเจนจำเป็นต้องตรวจสอบขอบเขตด้านบนด้วยเนื่องจากทำโดยปริยาย นั่นอาจส่งผลให้ขอบเคสที่มีขอบเขตด้านบนต่ำกว่าศูนย์ไม่ถูกจับหลังจากแก้ไข ดังนั้นเพื่อป้องกันสถานการณ์นี้ฉันสามารถใช้การทดสอบสองหน่วยเพื่อตรวจสอบว่าเกิดข้อผิดพลาดสำหรับ:

  1. ค่าลบขอบเขตล่างลบขอบเขตบน
  2. ค่าศูนย์ขอบเขตล่างลบขอบเขตบน
  3. ขอบเขตล่างบวกลบขอบเขตบน

คำถาม

ขอแนะนำให้รวมการตรวจสอบอย่างชัดเจนไว้ในรหัสหลักหรือไม่แม้ว่าจะมีการทดสอบในการทดสอบหน่วย

คำตอบ

9 FMc Sep 19 2020 at 00:38

ยกเว้นภายใต้สถานการณ์ที่ผิดปกติคลาสคือสิ่งของหรือเอนทิตีดังนั้นคำว่าอ็อบเจกต์ - ในขณะที่ฟังก์ชันหรือวิธีการคือการกระทำหรือการดำเนินการ คุณต้องการตั้งชื่อตามนั้น ด้วยเหตุนั้นGet_labelsฉันจึงเรียกฉันว่าเป็นคลาสที่มีชื่อแปลก ๆ จากสิ่งที่คุณแสดงให้เราเห็นฉันอาจแนะนำชื่อนี้Boundsเป็นทางเลือก ข้อดีของชื่อนั้นคือช่วยให้คุณสามารถย่อชื่อแอตทริบิวต์โดยไม่สูญเสียความหมาย

วิธีการแยกต่างหากสำหรับการตรวจสอบความถูกต้องพื้นฐานของขอบเขตดูเหมือนว่าจะเกินวิศวกรรมสำหรับฉัน - เว้นแต่ตรรกะการตรวจสอบจะซับซ้อนขึ้นมากหรือเว้นแต่จะใช้ที่อื่นในโค้ด ดังนั้นฉันจะทำการตรวจสอบความถูกต้องอย่างง่าย__init__()ในกรณีนี้

หลีกเลี่ยงสิ่งล่อใจที่จะใช้ข้อความที่พูดเก่งหรือแบบละเอียดในรหัสของคุณ มันจะไม่ช่วยคุณหรือผู้ใช้ของคุณในระยะยาว - อย่างน้อยนั่นก็เป็นประสบการณ์ของฉัน ทำให้สิ่งต่างๆตรงประเด็นและรัดกุมอย่างจริงจัง ในความเป็นจริงมักจะเป็นประโยชน์ในการเก็บรักษาข้อความในเชิงเทคนิคมากกว่าที่จะเป็นธรรมชาติในแนวโวหาร สิ่งที่ฉันหมายถึงคือแทนที่จะอธิบายปัญหาด้วยวิธีที่คนเราอาจพูดกับมนุษย์ด้วยวาจา ("ขอบเขตล่างซึ่งเป็น 1,000 ต้องน้อยกว่าขอบเขตบนซึ่งเท่ากับ 125") คุณมักจะอธิบายได้ดีกว่า ปัญหาในลักษณะที่เป็นสูตรแผนผังเหมือนคอมพิวเตอร์ เหนือสิ่งอื่นใดวิธีการดังกล่าวช่วยให้คุณสามารถใช้รูปแบบทั่วไปสำหรับข้อความแสดงข้อผิดพลาดทั้งหมดในแอปพลิเคชัน รูปแบบข้อความแสดงข้อผิดพลาดที่แสดงในการเขียนPROBLEM: SELFซ้ำด้านล่างสามารถอธิบายได้โดยทั่วไปว่า แนวทางที่สอดคล้องกันช่วยให้เขียนรหัสตรวจสอบความถูกต้องได้ง่ายขึ้นตั้งแต่แรกและรักษาไว้เมื่อเวลาผ่านไป ความสม่ำเสมอยังบ่งบอกถึงความเป็นมืออาชีพแก่ผู้ใช้

ตามบรรทัดเหล่านี้คุณมักจะทำให้การสร้างข้อความตรวจสอบความถูกต้องนั้นง่ายขึ้นได้โดยการกำหนด__repr__()สำหรับชั้นเรียนของคุณก่อน

สำหรับการตรวจสอบที่คุณมีเพื่อให้ห่างไกลที่เป็นแบบที่ใกล้ชิดกว่าการระดมทั่วไปValueError Exceptionนอกจากนี้คุณอาจพิจารณาตรวจสอบข้อผิดพลาดประเภทอื่น ๆ เช่นขอบเขต จำกัด เฉพาะจำนวนเต็มเท่านั้นหรือไม่

หากคุณตรวจสอบแล้วให้เพิ่มไฟล์TypeError.

ในที่สุดก็เป็นประเด็นที่ดีในเชิงโวหารและเป็นที่ยอมรับ ด้านล่างนี้เป็นสแต็กเทรซจากโค้ดของคุณตามที่เขียนไว้ เราเห็นข้อความ verbose สองครั้งครั้งแรกเป็น f-string แล้วตามด้วยพารามิเตอร์มีอะไรผิดปกติ? ไม่มีอะไรร้ายแรง แต่มันหนักน่าเบื่อแม้ขาดความสง่างาม อย่างน้อยที่สุดเราสามารถพูดได้ว่าการทำซ้ำของข้อความ verbose นั้นทำให้ผู้ใช้เสียสมาธิเล็กน้อยทำให้ผู้ใช้เพิ่มภาระทางสายตาหรือความรู้ความเข้าใจเพื่อให้ทราบว่าเกิดอะไรขึ้น เปรียบเทียบสิ่งนั้นกับการติดตามสแต็กจากโค้ดที่แก้ไข

# ORIGINAL.

Traceback (most recent call last):
  File "bounds.py", line 19, in <module>
    get_labels = Get_labels(-1,25,"first")
  File "bounds.py", line 7, in __init__
    self.check_threshold_validity()
  File "bounds.py", line 17, in check_threshold_validity
    raise Exception(f'Sorry, the lower threshold={self.lower_bound} should be larger than 0 for configuration={self.configuration_name}')
Exception: Sorry, the lower threshold=-1 should be larger than 0 for configuration=first

# REVISED.

Traceback (most recent call last):
  File "bounds.py", line 72, in <module>
    b1 = Bounds(1000, 125, 'first')
  File "bounds.py", line 67, in __init__
    raise Exception(msg)
Exception: Upper bound must be greater than lower: Bounds(1000, 125, first)

โค้ดที่มีการแก้ไขที่เป็นไปได้เพื่อให้คุณพิจารณา:

class Bounds:

    def __init__(self, lower, upper, name):
        self.lower = lower
        self.upper = upper
        self.name = name

        if lower <= 0 or upper <= 0:
            msg = f'Bounds must be positive: {self}'
            raise ValueError(msg)

        if upper <= lower:
            msg = f'Upper bound must be greater than lower: {self}'
            raise ValueError(msg)

    def __repr__(self):
        return f'Bounds({self.lower}, {self.upper}, {self.name!r})'