2013-03-21 17 views
27

Sözlük veren bir işlev için bir doktrin yazıyorum. Onu çalıştırdığınızda, bu başarısızlığın nedeni olarakSözlük-eşitliğini Python'un doctest-paketi ile nasıl test ederim?

Expected: 
    {'this': 'is', 'a': 'dictionary'} 
Got: 
    {'a': 'dictionary', 'this': 'is'} 

Benim iyi tahminde başarısız

>>> my_function() 
{'this': 'is', 'a': 'dictionary'} 

gibi doctest.testmod doctest sözlük eşitliğini kontrol fakat __repr__ eşitlik olmamasıdır görünüyor. This post, sözlük eşitliğini kontrol etmek için dolandırıcılık yapmanın bir yolunun olduğunu belirtir. Bunu nasıl yapabilirim?

+0

beri olduğu gibi, sen dicti kullanamazsınız: doctest belgelerinde özel bir bölüm var. Bunu sıralı bir nesneye dönüştürmelisiniz – ornoone

+0

Aşağıda listelenen yanıtların tümü doctest belgelerinde yer almaktadır: http://docs.python.org/2/library/doctest.html#warnings –

+0

@ornoone Peki neden? Onlar eşit nesnelerdir, bu da doktrinin kontrol etmesi gereken şeydir. – endolith

cevap

19

, sadece çıkış için aynı olacağını denetler. Yazdırılan her şeyin aynı sözlük için aynı olmasını sağlamalısınız. Bu tek satırlık yer ile yapabilirsiniz: çözümünüz bu varyasyon temizleyici olabilir

>>> sorted(my_function().items()) 
[('a', 'dictionary'), ('this', 'is')] 

rağmen:

>>> my_function() == {'this': 'is', 'a': 'dictionary'} 
True 
+2

Çözümünüz daha temizdir, ancak my_function öğesinin gerçekte ne değerlendirildiğini size söyleyemeyiz. – jQwierdy

+0

pprint çözümü çok daha temiz görünüyor, bkz. Charlax'ın cevabı –

+1

, ama ne bir dokümantasyon örneğiyse ve gerçekçi bir girdi ve gerçekçi çıktı göstermek istersek? Tam dizeleri yerine eşitliği kontrol etmenin bir yolu var mı? – endolith

2

dict.items aracılığıyla bir liste dönüştürebilecek() ve ardından sıralamak ...

>>> l = my_function().items() 
>>> l.sort() 
>>> l 
[('a', 'dictionary'), ('this', 'is')] 
+0

veya tek liner olarak: 'sıralanmış (my_function(). Items())' – hardmooth

12

Bunu kullanarak sona erdi. Hacky, ama işe yarıyor. Doctest başına __repr__ eşitliği, kontrol etmez

>>> p = my_function() 
>>> {'this': 'is', 'a': 'dictionary'} == p 
True 
+3

Bence bu hacky değil (p == {etc} 'yazıyor olsa da) - bu önerilen ilk teknik [docs] 'un ilgili bölümünde (http://docs.python.org/3/library/doctest.html # uyarı). – DSM

+5

neden my_function() == {'this': 'is', 'a': 'dictionary'} '? – endolith

+0

Buradaki dezavantaj, bir kez iddiaların başarısızlığa uğradığı, hangi anahtarların tam olarak yanlış olduğunu bilmediğinizdir. "Pprint" ile çözüm, yararlı bir fark gösterir. – geekQ

34

başka iyi bir yolu (standart kütüphanesinde) pprint kullanmaktır.

>>> import pprint 
>>> pprint.pprint({"second": 1, "first": 0}) 
{'first': 0, 'second': 1} 

kaynak koduna göre, sizin için dicts sıralama ediyor:

http://hg.python.org/cpython/file/2.7/Lib/pprint.py#l158

items = _sorted(object.items()) 
Sen Doctestler içindeki unittest.TestCase sınıfının bir örneğini oluşturmak ve sözlükleri karşılaştırmak için kullanabilirsiniz
+4

'u kullanabilirsiniz. python devs [bunu önermeyin] (https://bugs.python.org/issue20310) çünkü sürümler arasında pprint stabilitesini garanti etmiyorlar. – max

+0

da, bu çözüm zorunlu olarak diğer veri türleri (set gibi) için çalışır. – hardmooth

+0

Avantaj burada bir kez başarısızlık iddiasında, "pprint" bir helisel fark gösterecektir. Python sürümü arasında pprint uygulaması değişiyorsa, testlerimizi düzeltmemiz ya da uygulamayı sabit tutmak için kodumuzda çoğaltmamız gerekiyor. – geekQ

1

:

def my_function(x): 
    """ 
    >>> from unittest import TestCase 
    >>> t = TestCase() 

    >>> t.assertDictEqual(
    ...  my_function('a'), 
    ...  {'this': 'is', 'a': 'dictionary'} 
    ...) 

    >>> t.assertDictEqual(
    ...  my_function('b'), 
    ...  {'this': 'is', 'b': 'dictionary'} 
    ...) 

    """ 
    return {'this': 'is', x: 'dictionary'} 

Not: Bu yaklaşım daha iyi Sözlüklerin eşit olup olmadığını basitçe kontrol etmekten çok, çünkü iki sözlük arasında fark gösterecektir.

İlgili konular