Veikia unittest su tipiniu testo katalogo struktūra

Labai dažna katalogų struktūra, net ir paprastam „Python“ moduliui, atrodo, yra vieneto testų atskyrimas į savo test katalogą:

 new_project/ antigravity/ antigravity.py test/ test_antigravity.py setup.py etc. 

pavyzdžiui, žr . projekto „Python“ projektą .

Mano klausimas yra paprastas: koks yra įprastas testų atlikimo būdas? Įtariu, kad tai akivaizdu visiems, išskyrus mane, bet jūs negalite tiesiog paleisti „ python test_antigravity.py iš bandymų katalogo, nes jo import antigravity nepavyks su klaida, nes modulis nėra kelyje.

Žinau, kad galiu pakeisti PYTHONPATH ir kitus su paieškos keliu susijusius gudrybės, bet negaliu patikėti, kad paprasčiausias būdas yra geras, jei esate kūrėjas, bet nėra realu tikėtis, kad naudotojai naudos, jei tik nori patikrinti bandymai praeina.

Kita alternatyva - tiesiog nukopijuoti bandomąjį failą į kitą katalogą, bet atrodo šiek tiek kvaila ir neatsižvelgiama į tai, kad jis turi būti atskirame kataloge, kad pradėtų.

Taigi, jei ką tik įkėlėte šaltinį į savo naują projektą, kaip vykdytumėte vieneto testus? Norėčiau, kad atsakymas leistų man pasakyti savo naudotojams: „Vykdyti vieneto testus, padaryti X“.

545
13 дек. Pagrindinis majoras yra nustatytas gruodžio 13 d 2009-12-13 19:10 '09 19:10 2009-12-13 19:10
@ 19 atsakymų

Geriausias sprendimas, mano nuomone, yra naudoti unittest komandų eilutės unittest , kuri pridės katalogą prie sys.path taigi jums nereikės (padaryta TestLoader klasėje).

Pavyzdžiui, šios katalogo struktūros:

 new_project ├── antigravity.py └── test_antigravity.py 

Galite tiesiog paleisti:

 $ cd new_project $ python -m unittest test_antigravity 

Jei naudojate katalogų struktūrą, pvz .:

 new_project ├── antigravity │  ├── __init__.py # make it a package │  └── antigravity.py └── test ├── __init__.py # also make test a package └── test_antigravity.py 

Be to, bandymų moduliuose test pakete galite importuoti antigravity paketą ir jo modulius kaip įprasta:

 # import the package import antigravity # import the antigravity module from antigravity import antigravity # or an object inside the antigravity module from antigravity.antigravity import my_object 

Vykdyti vieną testavimo modulį:

Šiuo atveju paleisti vieną testavimo modulį test_antigravity.py :

 $ cd new_project $ python -m unittest test.test_antigravity 

Tiesiog nusiųskite testavimo modulį taip pat, kaip jį importuojate.

Vykdykite vieną bandymo atvejį arba bandymo metodą:

Taip pat galite paleisti vieną TestCase arba vieną bandymo metodą:

 $ python -m unittest test.test_antigravity.GravityTestCase $ python -m unittest test.test_antigravity.GravityTestCase.test_method 

Vykdykite visus testus:

Taip pat galite naudoti testo aptikimą , kuris aptiks ir atliks visus jūsų bandymus, jie turėtų būti moduliai arba paketai, vadinami test*.py (gali būti modifikuoti naudojant -p, --pattern ):

 $ cd new_project $ python -m unittest discover 

Taip bus paleisti visi test*.py moduliai test pakete.

510
17 июня '14 в 17:49 2014-06-17 17:49 atsakymas perduotas Pierre'ui birželio 17 d. 14 d. 5:49 2014-06-17 17:49

Paprasčiausias jūsų naudotojų sprendimas yra pateikti vykdomąjį scenarijų failą ( runtests.py arba tam tikrą), kuris įkelia reikiamą bandymų aplinką, įskaitant, jei reikia, laikiną projekto šakninio katalogo pridėjimą prie sys.path. Tai nereikalauja, kad naudotojai nustatytų aplinkos kintamuosius, tai panašūs į scenarijaus įkrovos schemą:

 import sys, os sys.path.insert(0, os.path.dirname(__file__)) 

Tada jūsų naudotojų nurodymai gali būti tokie paprasti kaip „python runtests.py“.

Žinoma, jei jums tikrai reikia kelio os.path.dirname(__file__) , jums nereikia jo pridėti prie sys.path ; „Python“ visada runtests.py šiuo metu veikiančio scenarijaus katalogą sys.path pradžioje, taigi, priklausomai nuo jūsų katalogo struktūros, tiesiog runtests.py reikiamoje vietoje gali būti būtinas.

Be to, nepaprastiausias „Python 2.7+“ modulis (kuris įdiegtas kaip unittest2 „Python 2.6“ ir ankstesnėms versijoms) dabar turi testo aptikimą , todėl nosies nereikia, jei norite automatinio bandymo aptikimo: naudotojo instrukcijos gali būti tokios paprastos kaip "python -m unittest aptikimas".

45
13 дек. Atsakymą pateikė Carl Meyer gruodžio 13 d. 2009-12-13 23:40 '09, 23:40 PM 2009-12-13 23:40

Paprastai projekto kataloge sukuriu scenarijų „paleisti testus“ (vieną, kuris yra bendras tiek šaltinio katalogui, tiek test ), kuris įkelia rinkinį „Visi testai“. Paprastai tai yra šablono kodas, todėl galiu jį panaudoti iš projekto į projektą.

run_tests.py:

 import unittest import test.all_tests testSuite = test.all_tests.create_test_suite() text_runner = unittest.TextTestRunner().run(testSuite) 

test / all_tests.py (iš Kaip paleisti visus Python vieneto testus kataloge? )

 import glob import unittest def create_test_suite(): test_file_strings = glob.glob('test/test_*.py') module_strings = ['test.'+str[5:len(str)-3] for str in test_file_strings] suites = [unittest.defaultTestLoader.loadTestsFromName(name) \ for name in module_strings] testSuite = unittest.TestSuite(suites) return testSuite 

Naudodami šį nustatymą, galite tiesiog include antigravity į savo bandymo modulius. Trūkumas yra tas, kad jums reikia papildomo palaikymo kodo, kad atliktumėte konkretų testą.

19
07 июня '10 в 22:30 2010-06-07 22:30 atsakymas pateikiamas stw_dev 07 birželio 10 d. 22:30 val. 2010-06-07 22:30

Iš straipsnio, kurį nurodote:

Sukurkite test_modulename.py failą ir įdėkite vieneto testus. Kadangi bandymo moduliai yra atskirame kataloge, iš jūsų kodo gali tekti pridėti modulių pagrindinį katalogą į PYTHONPATH, kad juos paleistumėte:

 $ cd /path/to/googlemaps $ export PYTHONPATH=$PYTHONPATH:/path/to/googlemaps/googlemaps $ python test/test_googlemaps.py 

Galiausiai, Python yra dar viena populiari vieneto testavimo aplinka (tai labai svarbu!), Nosis. Nosis padeda supaprastinti ir išplėsti įterptąją vieneto testų infrastruktūrą (pvz., Jis gali automatiškai surasti jūsų testo kodą ir sukonfigūruoti PYTHONPATH), tačiau jis nėra įtrauktas į standartinį „Python“ paskirstymą.

Galbūt turėtumėte pažvelgti į nosį, kaip jis siūlo?

18
13 дек. Mark Byers atsakymas gruodžio 13 d 2009-12-13 19:25 '09 19:25 2009-12-13 19:25

Turėjau tą pačią problemą su atskiru vieneto testo aplanku. Iš minėtų sakinių pridedu absoliutų šaltinio kelią į sys.path .

Šio sprendimo privalumas yra tas, kad galite paleisti test/test_yourmodule.py prieš tai nepakeisdami jo bandymų kataloge:

 import sys, os testdir = os.path.dirname(__file__) srcdir = '../antigravity' sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir))) import antigravity import unittest 
8
04 дек. Atsakymas pateiktas andpei 04 Dec. 2013-12-04 12:45 '13, 12:45 2013-12-04 12:45

jei paleisite „python setup.py kūrimą“, tuomet paketas bus tranzitu. Bet jūs negalite to padaryti, nes galite užkrėsti savo „Python“ sistemos diegimą, todėl yra tokių įrankių kaip virtualenv ir buildout .

8
13 дек. Atsakymą pateikė Tom Willis gruodžio 13 d. 2009-12-13 19:27 '09, 19:27 PM 2009-12-13 19:27

Jei naudojate VS kodą, o jūsų testai yra tokiame pačiame lygyje, kaip ir jūsų projektas, tuomet kodas neveikia ir derinamas. Ką galite padaryti, tai pakeisti failą launch.json:

 { "version": "0.2.0", "configurations": [ { "name": "Python", "type": "python", "request": "launch", "stopOnEntry": false, "pythonPath": "${config:python.pythonPath}", "program": "${file}", "cwd": "${workspaceRoot}", "env": {}, "envFile": "${workspaceRoot}/.env", "debugOptions": [ "WaitOnAbnormalExit", "WaitOnNormalExit", "RedirectOutput" ] } ] } 

Pagrindinė eilutė čia yra envFile

 "envFile": "${workspaceRoot}/.env", 

Į projekto šaknį pridėkite .env failą

Į savo .env failą pridėkite kelią į savo projekto šaknį. Tai bus laikinai pridėta

PYTHONPATH = C: JŪSŲ PYTHONAS PROJEKTAS ROOT_DIRECTORY

jūsų projektui, ir galite naudoti „VS Code“ modulio derinimo bandymus

5
28 мая '17 в 2:45 2017-05-28 02:45 atsakymą pateikė Vladas Bezdenas gegužės 28 d. 17 d. 2:45

Sprendimas / pavyzdys „Python Erase“ moduliui

Atsižvelgiant į šią projekto struktūrą:

 ProjectName ├── project_name | ├── models | | └── thing_1.py | └── __main__.py └── test ├── models | └── test_thing_1.py └── __main__.py 

Projektą galite paleisti iš šakninio katalogo, naudodami python project_name , kuris vadina ProjectName/project_name/__main__.py .


Jei norite atlikti testus naudojant „ python test , efektyviai vykdant „ ProjectName/test/__main__.py , turite atlikti šiuos veiksmus:

1) Pasukite test/models katalogą į paketą, pridėdami failą __init__.py . Tokiu būdu pagalbiniai katalogai bandymų atvejais pasiekiami iš pirminio katalogo test .

 # ProjectName/test/models/__init__.py from .test_thing_1 import Thing1TestCase 

2) Pakeiskite savo sistemos kelią į test/__main__.py kad įtrauktumėte projekto_pavadinimo katalogą.

 # ProjectName/test/__main__.py import sys import unittest sys.path.append('../project_name') loader = unittest.TestLoader() testSuite = loader.discover('test') testRunner = unittest.TextTestRunner(verbosity=2) testRunner.run(testSuite) 

Dabar galite sėkmingai importuoti elementus iš projekto_pavadinimo į savo bandymus.

 # ProjectName/test/models/test_thing_1.py import unittest from project_name.models import Thing1 # this doesn't work without 'sys.path.append' per step 2 above class Thing1TestCase(unittest.TestCase): def test_thing_1_init(self): thing_id = 'ABC' thing1 = Thing1(thing_id) self.assertEqual(thing_id, thing.id) 
5
29 июня '17 в 2:45 2017-06-29 02:45 Atsakymą pateikė Derek Soike , birželio 29 d. 17 d. 2:45 am 2017-06-29 02:45

Naudokite „ setup.py develop , kad jūsų darbo katalogas būtų įdiegtos „Python“ aplinkos dalis, tada atlikite bandymus.

5
13 дек. Atsakymą davė Ned Batchelder gruodžio 13 d. 2009-12-13 19:24 '09 19:24 2009-12-13 19:24

Pastebėjau, kad jei iš „src“ katalogo paleisite nepriekaištingiausią komandų eilutės sąsają, importas veiks be pakeitimų.

 python -m unittest discover -s ../test 

Jei norite įdėti jį į paketinį failą projekto kataloge, galite tai padaryti:

 setlocal  cd src  python -m unittest discover -s ../test 
4
08 авг. atsakymas pateikiamas Alan L 08 rug. 2017-08-08 02:13 '17, 2:13 2017-08-08 02:13

Galite naudoti apvalkalą, kuris vykdo pasirinktus arba visus bandymus.

Pavyzdžiui:

 ./run_tests antigravity*.py ) (suaktyvinkite su shopt -s globstar ). 

Apvalkalas gali dažniausiai naudoti argparse kad analizuotų tokius argumentus kaip:

 parser = argparse.ArgumentParser() parser.add_argument('files', nargs='*') 

Tada atsisiųskite visus testus:

 for filename in args.files: exec(open(filename).read()) 

tada pridėkite juos prie bandymo paketo (naudodami inspect ):

 alltests = unittest.TestSuite() for name, obj in inspect.getmembers(sys.modules[__name__]): if inspect.isclass(obj) and name.startswith("FooTest"): alltests.addTest(unittest.makeSuite(obj)) 

ir paleiskite juos:

 result = unittest.TextTestRunner(verbosity=2).run(alltests) 

Daugiau apie tai išsamiau.

Taip pat žiūrėkite: Kaip paleisti visus „Python“ bandymo atvejus kataloge?

4
07 июня '15 в 14:45 2015-06-07 14:45 Kenorb atsakymą pateikia birželio 07 d. 15 val. 14:45 2015-06-07 14:45

Kas yra įprastas testų atlikimo būdas

Aš naudoju Python 3.6.2

 cd new_project pytest test/test_antigravity.py 

Įdiegti pytest: sudo pip install pytest

Nenurodau jokio kelio kintamojo, o mano importas nepertraukiamas su ta pačia „testo“ projekto struktūra.

Aš pakomentavau šią medžiagą: if __name__ == '__main__' :

test_antigravity.py

 import antigravity class TestAntigravity(unittest.TestCase): def test_something(self): # ... test stuff here # if __name__ == '__main__': # # if __package__ is None: # # import something # sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) # from .. import antigravity # # else: # # from .. import antigravity # # unittest.main() 
3
27 июля '17 в 0:43 2017-07-27 00:43 Atsakymą pateikia „ aliopi “ liepos 27 d. 17 d. 0:43 2017-07-27 00:43

Žemiau yra mano projekto struktūra:

 ProjectFolder: - project: - __init__.py - item.py - tests: - test_item.py 

Man buvo lengviau importuoti setUp () metodą:

 import unittest import sys class ItemTest(unittest.TestCase): def setUp(self): sys.path.insert(0, "../project") from project import item # further setup using this import def test_item_props(self): # do my assertions if __name__ == "__main__": unittest.main() 
3
25 июля '17 в 17:01 2017-07-25 17:01 atsakymas pateikiamas rolika liepos 25 d. 17: 01:17-25 17:01

Negalite importuoti iš tėvų katalogo be voodoo. Čia yra dar vienas būdas, kuris veikia bent jau su Python 3.6.

Pirmiausia sukurkite failo testą / context.py su tokiu turiniu:

 import sys import os sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 

Tada atlikite toliau nurodytą importą į testo / test_antigravity.py failą:

 import unittest try: import context except ModuleNotFoundError: import test.context import antigravity 

Atkreipkite dėmesį, kad šio sakinio priežastis yra ta, kad

  • importuoti test.context nepavyko, pradedant nuo „python test_antigravity.py“ ir
  • Konteksto importas nepavyko, kai iš naujo_projekto katalogo pradedamas „python -m unittest“.

Su šia apgaule jie abu dirba.

Dabar jūs galite paleisti visus bandymų failus bandymų kataloge su:

 $ pwd /projects/new_project $ python -m unittest 

arba paleiskite atskirą bandomąjį failą su:

 $ cd test $ python test_antigravity 

Na, tai nėra daug gražesnė nei konteksto.py turinys test_antigravity.py, bet galbūt ne daug. Pasiūlymai yra sveikintini.

2
20 окт. atsakymas duotas tjk 20 okt. 2018-10-20 19:25 '18, 7:25 pm 2018-10-20 19:25

Python 3+

Pridėti @Pierre

unittest katalogų naudojimas:

 new_project ├── antigravity │  ├── __init__.py # make it a package │  └── antigravity.py └── test ├── __init__.py # also make test a package └── test_antigravity.py 

Jei norite paleisti testavimo modulį test_antigravity.py :

 $ cd new_project $ python -m unittest test.test_antigravity 

Arba viena „ TestCase

 $ python -m unittest test.test_antigravity.GravityTestCase 

Būtinai nepamirškite __init__.py net jei __init__.py vertė neveiks.

1
28 сент. atsakymas pateikiamas eusoubrasileiro 28 sep . 2018-09-28 18:21 '18, 18:21 pm 2018-09-28 18:21

Šis BASH scenarijus paleis python unittest testų katalogą iš bet kurios failų sistemos vietos, nesvarbu, koks darbinis katalogas yra.

Tai naudinga, kai ./src darbo kataloge ./src arba ./example ir jums reikia greito vieneto testo:

 #!/bin/bash this_program="$0" dirname="'dirname $this_program'" readlink="'readlink -e $dirname'" python -m unittest discover -s "$readlink"/test -v 

test/__init__.py failo test/__init__.py nereikia įkelti pakuotės / atminties pridėtinės vertės gamybos metu.

1
13 авг. atsakymas, kurį pateikė Egbert S 13 rug. 2018-08-13 03:50 '18 - 3:50 2018-08-13 03:50

Jei bandymų kataloge yra keletas katalogų, tuomet turite pridėti __init__.py failą į kiekvieną katalogą.

 /home/johndoe/snakeoil └── test ├── __init__.py └── frontend └── __init__.py └── test_foo.py └── backend └── __init__.py └── test_bar.py 

Tada paleiskite kiekvieną testą iš karto:

 python -m unittest discover -s /home/johndoe/snakeoil/test -t /home/johndoe/snakeoil 

Šaltinis: python -m unittest -h

  -s START, --start-directory START Directory to start discovery ('.' default) -t TOP, --top-level-directory TOP Top level directory of project (defaults to start directory) 
0
30 окт. atsakymas pateikiamas Qlimax 30 Oct. 2018-10-30 18:31 '18, 18:31 pm 2018-10-30 18:31

Jei ieškote tik komandinės eilutės sprendimo:

Remiantis šia katalogo struktūra (apibendrinta specialiu šaltinio katalogu):

 new_project/ src/ antigravity.py test/ test_antigravity.py 

„Windows“ : ( new_project )

 $ set PYTHONPATH=%PYTHONPATH%;%cd%\src $ python -m unittest discover -s test 

Žiūrėkite šį klausimą, jei norite jį naudoti paketo kilpoje.

„Linux“ : ( new_project )

 $ export PYTHONPATH=$PYTHONPATH:$(pwd)/src [I think - please edit this answer if you are a Linux user and you know this] $ python -m unittest discover -s test 

Taikant šį metodą, prireikus taip pat galima pridėti papildomus katalogus į PYTHONPATH.

0
01 февр. atsakymas pateikiamas pj.dewitte 01 vasaris 2019-02-01 12:57 '19 , 12:57 pm 2019-02-01 12:57

Tikrai turėtumėte naudoti „pip“ įrankį.

Norėdami pip install -e paketą kūrimo režimu, naudokite pip install -e . Tai labai gera praktika.

Žemiau esančiame URL yra 2 klasikiniai projektai (su bandymu), galite sekti bet kurį iš jų.

Nuoroda

-3
07 марта '14 в 10:51 2014-03-07 10:51 atsakymas į kalmarą pateikiamas kovo 14 d. 14 d. 10:51 2014-03-07 10:51

Peržiūrėkite kitus klausimus apie „ etikečių arba „ Užduoti klausimą“