Python'da birim testi için genel parametreleri nasıl doğru şekilde ele alabilirim?


11

Genellikle çok sayıda paylaşılan, halka açık ve güvenlikle ilgili parametreye sahip birçok algoritma uyguluyoruz.

Şu anda, tüm parametreleri ve önceden tanımlanmış iki global nesneyi içeren bir sınıf kullanıyoruz:

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)  

Algoritmalar daha sonra PublicParamsnesneyi varsayılan olarak üretken olanpublicParams_secure

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

ve

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

Bu şekilde, daha kolay birim testi için farklı genel parametreleri enjekte edebiliriz:

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

Bu yaklaşımla ilgili sevmediğim şeyler:

  • publicParamsVarsayılan bir değer vermek, bazı algoritmaları çağırırken bu değeri isteğe bağlı hale getirir. Bununla birlikte, AlgoTwoiçeriden çağırırken geçmeyi unutmak kolaylaşır AlgoOne, bu da test nesnesi geçilirse iki farklı nesnenin kullanılmasına neden olurAlgoOne

Daha az eğilimli ancak yine de birim testi için esneklik sunan daha iyi bir yol var mı? Bu gerçekten en iyi uygulama mı?

Yanıtlar:


1

Yapılandırma dosyaları oluşturun test_config.pyve production_config.py. Ortam değişkenini veya komut satırı bağımsız değişkenini kullanarak bunlardan birini seçin. İçe aktarın (veya .json/ .txtyerine seçerseniz okuyun / ayrıştırın .py) ve sonucu, herhangi bir yere aktarabileceğiniz bir modüldeki global bir nesne aracılığıyla tüm program için kullanılabilir hale getirin.

Bu, halihazırda yaptığınız şeye çok benzer, ancak küresel kapsamdan python'u çağırdığınız kabuğa kadar bir adım daha ileri götürür. Avantajı, artık üretim ve test yapılandırmasını yanlışlıkla karıştırma riskinin olmamasıdır: tek bir ortam değişkeni / komut satırı olduğundan, her iki dosyayı aynı python oturumunda okuyamazsınız.


0

Yapabileceğiniz birkaç şey var.

  • Globalleri kullanmayı bırak
  • Varsayılanları kullanmayı bırak
  • Her zaman varsayılanların kullanılmasına izin vermeyen özel yardımcı yöntemleri test edin

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

Tabii bu seçeneklerin herhangi bir çok iş vardır ama bunun sizin için bir sorun olup olmadığını sormak olmazdı.


0

Değerlerin toplanması her zaman küresel bağlamdan ve bu parametrelerin işlenmesinden ayrılabilir.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.