6

Pracuję nad moim pierwszym pakietem dystrybucyjnym Pythona. Moja krzywa uczenia się na Pakowanie w języku Python wydaje się nieco wygładzać, ale wciąż mam problem z kilkoma otwartymi pytaniami. Jednym z nich jest to, czy powinienem spowodować, że moje testy jednostkowe zostaną zainstalowane razem z moim kodem.Czy ma sens instalowanie testów jednostkowych w Pythonie w pakietach witryn?

Rozumiem, it's important to include tests in a source distribution. Zastanawiam się, czy powinienem je skonfigurować?

Widziałem co najmniej jeden pakiet popularne, że wydaje się to zrobić celowo (PyHamcrest), a co najmniej jeden inny, że wydaje się to zrobić przez przypadek (behave).

Więc moja (wieloczęściowe) Pytanie jest takie:

  • Czy kiedykolwiek sensu instalować moje testy jednostkowe opakowania obok mojego kodu pakietu?

  • Jeśli tak, jaki jest przypadek użycia? Kto by ich użył i po co? To znaczy, kto użyłby tych, którzy nie byliby całkowicie zadowoleni z pobrania źródłowej dystrybucji i uruchomienia python setup.py test?

  • A jak będą korzystać z zainstalowanych testów jednostkowych? lubisz import test; test.run() lub coś w tym stylu?

+0

Off szczycie mojej głowy, wskazane byłoby, aby być w stanie określić, że pakiet działa/zainstalowany prawidłowo, zwłaszcza gdy się dystrybucją do różnych platform i/lub mają współzależności osób trzecich, które mogą lub nie może różnić się od wersji do wersji. –

+2

Cześć Joel, pytanie, które tu zadam, dotyczy właśnie tego, dlaczego sensowne może być ** instalowanie ** testów, a nie tylko włączanie ich do dystrybucji źródłowej. – scanny

+0

'numpy'' scipy' 'pandy'' sympatyczne' 'blaze'' numba'' skimage' wszystkie mają testy zainstalowane w pakietach serwisowych, dla czego warto – endolith

Odpowiedz

6

Po zbadaniu tego problemu i dopóki ktoś bardziej doświadczony nie ma minuty, by odważyć się na coś przeciwnego, rozumiem, że prosta odpowiedź brzmi: "Nie, testy jednostkowe nie powinny być instalowane, tylko włączone do dystrybucji źródłowej ".

W nielicznych przypadkach znalazłem gdzie zostały zainstalowane testy, wszystko okazało się być przypadkowemu i to łatwiejsze niż mogłoby się wydawać, aby błąd niezauważalnie.

Oto jak to się dzieje:

  1. Parametr packages=find_packages() jest stosowany w setup.py więc pakiety można znaleźć bez konieczności wymienić je wyraźnie.
  2. Folder test jest tworzony w pakiecie (przez dodanie __init__.py), dzięki czemu testy mogą odwoływać się do testowanych modułów przy użyciu względnego nazewnictwa (np. from .. import pkg.mod).
  3. setuptools instaluje się jako osobny pakiet wraz z innymi projektami. Uwaga to oznacza, że ​​można wykonać import test w interpreter Pythona i to działa, prawie na pewno nie to, co ma, zwłaszcza, że ​​wiele innych ludzi użyć tej nazwy dla swojego katalogu testów :)

Rozwiązaniem jest użycie ustawienie: packages=find_packages(exclude=['test']), aby zapobiec instalowaniu katalogu testowego.

+0

przy okazji, w jaki sposób testujesz instalację pakietu, korzystając z testów z dystrybucji źródłowej? Chodzi mi o to, czy istnieje charakterystyczna linia poleceń lub wywołanie funkcji, aby to zrobić? – n611x007

+0

'garść znalezionych przypadków' pamiętasz które? – n611x007

1

Jednak nie jestem ekspertem, chciałbym podzielić się moją opinią.

Zawsze umieszczałbym testy razem z kodem, jeśli mogę oczekiwać, że coś może się nie udać w zależności od przyczyn zewnętrznych. Czy to kolejność bitów, dziwne strefy czasowe, kodowanie znaków, 24-bitowe liczby całkowite lub coś dziwnego, z czym można się spotkać i przetestować.

Kto nie byłby szczęśliwy, gdyby mógł pobrać źródło i przeprowadzić testy? Może niektórzy użytkownicy, debian, że pakiety są usuwane ze źródeł (wiem, że mówisz o pythonie, ale pozwól mi być trochę ogólna) i twoja biblioteka może czasami zawieść z powodu dziwnych rzeczy w systemie.

Jeśli twoje testy gwarantują tylko wewnętrzne zdrowie psychiczne, pomijając je, tak jak w przypadku źródeł zewnętrznych, nie są one wiele warte, ponieważ nigdy nie zmienisz ustawień biblioteki.

Osobiście słyszałem o czymś, co się nie udaje, ponieważ zostało przeniesione na maszynę IBM, która miała inne zamawianie bitów. Nie pamiętam, czy zależało to od operacji bitowej, czy też było coś wstępnie obliczone i zapisane w pamięci podręcznej statycznie. Czasem jednak mądrze jest sprawdzić, czy załadujesz to, co myślisz, że uratowałeś.

EDYCJA: Może lepiej będzie przeformułować. Chciałbym zainstalować testy, gdy czujesz, że mogą istnieć zastrzeżenia dotyczące przenośności. Myślę, że zawsze dobrze jest sprawdzać rzeczy, gdy wdrażasz coś w innym systemie.

2

Moim zdaniem właściwą odpowiedzią jest NIE, ale znajdziesz sporo dystrybucji, które instalują testy. Testy nie powinny być instalowane, ale powinny być zawarte w dystrybucji źródłowej. Moim zdaniem w idealnym świecie testowanie zainstalowanych pakietów powinno być zadaniem wykonywanym przez menedżera pakietów (pip), a katalog site-packages nie powinien być zanieczyszczony źródłami testowymi.

Niedawno zbadałem ten temat i zebrałem informacje z różnych źródeł oraz znalazłem kilka różnych sposobów struktury hierarchii katalogów/pakietów dystrybucji, która zawiera zarówno źródła biblioteki, jak i testy. Większość tych struktur wydaje się być przestarzała i zostały wymyślone jako próby obejścia niekompletnych zestawów funkcji starszych systemów dystrybucji w tym czasie. Niestety wiele źródeł internetowych (starszych blogów/dokumentacji) wciąż reklamuje przestarzałe metody, więc bardzo łatwo jest znaleźć nieaktualne instrukcje dotyczące dystrybucji/samouczka dotyczące wyszukiwania online.

Załóżmy, że masz bibliotekę o nazwie "my_lib" i chcesz uporządkować źródła swojej dystrybucji. Pokażę dwa popularne i pozornie przestarzałe sposoby na uporządkowanie twojej dystrybucji i trzeci sposób, który uważam za najbardziej uniwersalny. Trzecia metoda może być również nieaktualna, ale jest to najlepsza, jaką znam, kiedy opublikować tę odpowiedź. ;-)

Sposób nr 1

Rozkłady że (świadomie lub nieświadomie) Instalacja testy zwykle używają tej metody.

hierarchia

+- my_lib 
| +- __init__.py 
| +- source1.py 
| +- source2.py 
| +- tests 
|  +- __init__.py 
|  +- test_1.py 
|  +- test_2.py 
+- setup.py 

Sposób nr 2

Testy nie są zainstalowane, ale powinny być one zawarte w dystrybucji źródłowej poprzez akt MANIFEST.in.

hierarchia

+- my_lib 
| +- __init__.py 
| +- source1.py 
| +- source2.py 
+- tests 
| +- __init__.py 
| +- test_1.py 
| +- test_2.py 
+- setup.py 

Sposób nr 3 (wolę ten.)

Jest to dość dużo podobna do Sposób nr 2 z małym skręcie (The src dir).

hierarchia

+- src 
| +- my_lib 
|  +- __init__.py 
|  +- source1.py 
|  +- source2.py 
+- tests 
| +- __init__.py 
| +- test_1.py 
| +- test_2.py 
+- setup.py 

setup() wywołanie w setup.py

from setuptools import setup, find_packages 

setup(
    ... 
    packages=find_packages('src'), 
    package_dir={'': 'src'}, 
    ... 
) 

MANIFEST.in

recursive-include tests *.py 

Testy nie będzie być zainstalowane, ale będą one zawarte w dystrybucji źródłowej poprzez naszą MANIFEST.in.

W przypadku metody nr 3 masz katalog src, który zwykle zawiera tylko jedną paczkę, która jest katalogiem głównym twojej biblioteki. Umieszczenie pakietu my_lib do katalogu src katalogu (a nie pakiet, więc nie potrzebują src/__init__.py) ma następujące zalety:

  • Po wykonaniu setup.py katalog, który zawiera setup.py jest domyślnie dodawany do ścieżki Pythona . Oznacza to, że w twoim setup.py możesz przypadkowo i nieprawidłowo importować rzeczy z biblioteki, jeśli pakiet znajduje się w tym samym katalogu, co setup.py. Po umieszczeniu pakietu my_lib w src możemy uniknąć tego problemu.
  • można łatwo korzystać z rozproszonych źródeł do testów zarówno rozproszonych źródeł biblioteki oraz zainstalowaną bibliotekę:

    • Po uruchomieniu testów z setup.py testpackage_dir={'': 'src'} część swojego setup() gwarancji wywoławczych, że testy będą zobacz Twój pakiet biblioteki my_lib przechowywany w src/my_lib.
    • Można również uruchomić testy bez setup.py. W najprostszym przypadku możesz to zrobić za pomocą polecenia python -m unittest. W tym przypadku katalog src nie będzie częścią ścieżki pythona, więc można użyć tej metody do przetestowania zainstalowanej wersji biblioteki zamiast źródeł w wersji src.