2009-06-22 18 views
37

'a iletmenin bir yolu var. Envanteri içe aktaran ve bazı Test Noktalarına sahip bir modülüm var. Bazı komut satırı seçeneklerini (örneğin, bir veri dosyasının adı), kabul etmek için olmasını isterim ama seçeneği iletmeye çalıştığımda "seçenek-tanınmadı" iletisini alırım. Uygulamaya uygun olmayan + seçenekler sunmak mümkün mü (not: seçenekleri işlemek için optparse kullanıyorum)? Teşekkürler.python, unittest: komut satırı seçeneklerini app

$ python test_app_data.py -i data_1.txt 

option -i not recognized 

=====================

takip:

import cfg_master #has the optparse option-handling code 

... 

if __name__ == '__main__':  
    #add you app's options here... 
    options_tpl = ('-i', '--in_dir', '-o', '--out_dir') 
    del_lst = [] 
    for i,option in enumerate(sys.argv): 
     if option in options_tpl: 
      del_lst.append(i) 
      del_lst.append(i+1) 

    del_lst.reverse() 
    for i in del_lst: 
     del sys.argv[i] 

    unittest.main() 
: Bu önerilen çözümün bir uygulamasıdır Eğer unittest koduna kontrolünü geçmesi önce ikinci kod komut satırı seçeneklerini yorumlamaya çalışmaz böylece bize gösterilmiyor sizin if __name__ == '__main__': bölümünde,
+0

unittest.main diyoruz. Bu durumda, cevap vermediğiniz ayrıntılara çok bağlı görünmektedir. –

+0

(@jd. "Takip" iniz bir cevap olarak yayınlanmalıdır - sorunuz sadece ... iyi ... soruyu içermelidir. – user1251007

cevap

45

Yapı Alex'in cevabı üzerine, bu argparse kullanarak yapmak aslında oldukça kolaydır:

if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('--input', default='My Input') 
    parser.add_argument('filename', default='some_file.txt') 
    parser.add_argument('unittest_args', nargs='*') 

    args = parser.parse_args() 
    # TODO: Go do something with args.input and args.filename 

    # Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone) 
    sys.argv[1:] = args.unittest_args 
    unittest.main() 

Sana çalıştıkları olmadığını görmek için unittest içine geçebilir bayrakların tüm test etmedim ama testi geçen yaptığı işlerde, örneğin isim: foo ve data.txt ile MyTest

python test.py --input=foo data.txt MyTest 

çalıştırır.

küçük bağımsız uygulamalar için
+3

Güzel! Daha da iyisi, 'unittest.main()' bir argv parametresini kabul eder, böylece global sys.argv ile uğraşmak zorunda kalmazsınız, ör. öylesine: 'unit_argv = [sys.argv [0]] + args.unittest_args; unittest.main (argv = unit_argv) ' – wutz

+3

' .parse_known_args() 'yi kullanabilirsiniz ve' nargs = '*' 'seçeneğini kullanmanız gerekmez; [Python: sürümüm için unittest.main()?] (http://stackoverflow.com/a/17259773) çağrılmadan bir unittest.TestCase çalıştırın. –

+0

Bu cevabı @MartijnPieters tarafından başvurulan sorudan bağladım çünkü yaklaşım bana hitap ediyordu. Ancak, bu cevabı uygularken, bayrakların (--failfast ve --catch) geçişi sırasında işe yaramadı, bu yüzden Martijn'in cevabına geri döndüm. –

31

, sen, o zaman del sys.argv[1:]optparse gerekiyor ve olacak tekrar ne zaman Onlarla zaten uğraştınız. (ve'un bazı seçeneklerine sahip olmak biraz daha zordur; bu nedenle, bazı karmaşık gereksinimleriniz varsa, unittest'a da geçebilirsiniz). Onları farklı, daha az tahmin edilebilir şartlar altında bu şekilde çalıştırmak yaptıkça

+0

harika, teşekkürler; sadece onaylamak için: önce (muhtemelen birden fazla ve değişken) uygulama seçeneklerini işlemek için optparse izin verin, sonra onları sys.argv 'den silin ve nihayet unittest'in devralmasına izin verin. –

+0

@jd yep, işte bu! –

+0

Parlak, teşekkürler Alex! Ben hiç bu işe yaramadı: P – Skilldrick

-7

Sen unittests çalıştırmak için argümanlar ve seçenekleri almamalıdır. Farklı verilerle neden test çalıştırmanız gerektiğini ve her defasında farklı bir şekilde çalıştırılmadan tüm veri kümelerinin zemini kapsayacak şekilde test paketini tamamlamanız gerektiğini anlamanız gerekir.

+0

Haftalık veri raporları alıyorum (dosyalar); Bu yeni raporları kamuya açık raporlar üretmeden önce, açıklamamaya beslemek istiyorum. Herhangi bir nedenden ötürü, verilerin yapısı veya türü değişmişse (ör. Yeni bir sütun alanı eklenmiş, bir veri aralığı değişmiş ve bir hata açığa çıkarılmıştır) testlerle bunları yakalamak istiyorum. Umarım bu mantıklıdır. –

+2

emin değil ama bu veri doğrulama, onaylama değil. – ironfroggy

+2

Koşullu sınama atlama hakkında ne dersiniz?Tüm test senaryolarımı, testten geçme sınavını yaparak yürütüyorum, ama kolay bir komut satırı yoluna sahip olabilmem için @skipUnless ('- full' in sys.argv) gibi bazı testlerde ek açıklamalara sahip olmak güzel olurdu. Tüm testleri çalıştırmanın ya da sadece bazılarının. –

1

, ben bir başlangıç ​​gözcü seçeneği (-t) kullanan ve evet, genel anlamda() argparse.ArgumentParser çağırmadan önce()

if __name__ == "__main__": 
    if len(sys.argv) > 1 and sys.argv[1] in ["-t", "--test"]: 
     del(sys.argv[1]) 
     sys.exit(unittest.main()) # pass sys.argv[ 

    p = argparse.ArgumentParser() 
    . . . 
İlgili konular