Làm thế nào để xử lý đúng các tham số toàn cầu để kiểm tra đơn vị trong python?


11

Chúng tôi đang thực hiện nhiều thuật toán thường có nhiều tham số được chia sẻ, được biết đến công khai và liên quan đến bảo mật.

Hiện tại, chúng ta chỉ cần sử dụng một lớp chứa tất cả các tham số và hai đối tượng toàn cục được xác định trước:

class PublicParams(object):
    p = q = 0

    def __init__(self, p, q):
        self.p = p
        self.q = q

# used for tests
publicParams_test = PublicParams(15,7)               

# Some 2048 bit numbers for example
publicParams_secure = PublicParams(128378947298374928374,128378947298374928374)  

Các thuật toán sau đó lấy một PublicParamsđối tượng làm đối số mặc định cho năng suấtpublicParams_secure

def AlgoOne(n, publicParams = publicParams_secure):
    # do stuff with publicParams.p
    # ...
    AlgoTwo(x, publicParams)

def AlgoTwo(x, publicParams= publicParams_secure):
    # do stuff with publicParams.q

Bằng cách này, chúng tôi vẫn có thể tiêm các tham số công khai khác nhau để kiểm tra đơn vị dễ dàng hơn:

class AlgoOneTest(unittest.TestCase):
    def test(self):
        # compare with manually computed result
        self.assertTrue(AlgoOne(1, publicParams_test) == 10) 

Những gì tôi không thích về cách tiếp cận này:

  • Đưa ra publicParamsmột giá trị mặc định làm cho nó tùy chọn khi gọi một số thuật toán. Tuy nhiên, thật dễ dàng để quên việc chuyển nó khi gọi AlgoTwotừ bên trong AlgoOne, điều này sẽ dẫn đến hai đối tượng khác nhau được sử dụng nếu đối tượng thử nghiệm được chuyển đếnAlgoOne

Có cách nào tốt hơn mà ít bị nhưng vẫn mang lại sự linh hoạt cho thử nghiệm đơn vị không? Đây thực sự là thực hành tốt nhất?

Câu trả lời:


1

Tạo tập tin cấu hình test_config.pyproduction_config.py. Chọn một trong số chúng bằng cách sử dụng biến môi trường hoặc đối số dòng lệnh. Nhập nó (hoặc đọc / phân tích, nếu bạn chọn .json/ .txtthay vì .py) và cung cấp kết quả cho toàn bộ chương trình thông qua một đối tượng toàn cầu trong một mô-đun mà bạn có thể nhập ở bất cứ đâu.

Điều này rất giống với những gì bạn đã làm, ngoại trừ việc nó tiến thêm một bước, từ phạm vi toàn cầu đến lớp vỏ mà bạn gọi con trăn. Ưu điểm là không còn có nguy cơ vô tình trộn lẫn cấu hình kiểm tra và sản xuất: bạn không thể đọc cả hai tệp trong cùng một phiên python, vì chỉ có một biến môi trường / dòng lệnh.


0

Có một số điều bạn có thể làm.

  • Ngừng sử dụng toàn cầu
  • Ngừng sử dụng mặc định
  • Luôn kiểm tra các phương thức trợ giúp riêng không cho phép sử dụng mặc định

    def _AlgoOne(n, publicParams):
        return AlgoOne(n, publicParams)

Chắc chắn rằng bất kỳ tùy chọn nào trong số đó là rất nhiều công việc nhưng bạn sẽ không hỏi liệu đây có phải là vấn đề với bạn không.


0

Người ta luôn có thể tách bộ sưu tập các giá trị khỏi bối cảnh toàn cầu và xử lý các tham số đó.

def do_the_thing():
    """Provides the public (rather untestable) context.
    _do_the_thing(global1, global2, publicParams)"""

def _do_the_thing(blah, blah, blah):
    "Actually does the thing"
    pass
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.