Slide 1

Slide 1 text

5FTUJOH%KBOHP BQQMJDBUJPOTXJUI QZUFTU "OESFBT1FMNFBOESFBT!QFMNFTF 5XJUUFS!BOESFBTQFMNF

Slide 2

Slide 2 text

.F w $PGPVOEFSEFWFMPQFSBU1FSTPOBMLPMMFO w 1ZUIPOQSPGFTTJPOBMMZTJODF XSJUJOHUFTUT TJODF

Slide 3

Slide 3 text

5FTUJOHJO%KBOHP

Slide 4

Slide 4 text

5FTU$BTFIJFSBSDIZ

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

.VMUJQMFUFTUpMFT # Typical contents of app/tests/__init__.py: from .test_foo import * from .test_bar import * from .test_spam import *

Slide 7

Slide 7 text

QZUFTU w (FOFSBMQVSQPTF1ZUIPOUFTUJOHUPPM w 6TFECZ1Z1Z .P[JMMB TJY 4FOUSZ  w *OOPWBUJWFGFBUVSFT pYUVSFT QPXFSGVMQMVHJO TZTUFN w -PUTPGFYJTUJOHQMVHJOT w $PWFSBHF EJTUSJCVUFEUFTUJOH 1&1DIFDLJOH w %KBOHPQMVHJOQZUFTUEKBOHP w 8SJUFUFTUTJOBQZUIPOJDTUZMF

Slide 8

Slide 8 text

QZUFTUUFTUTUZMF def  greeter(name):        return  'Hello  %s!'  %  name def  test_greeter():        assert  greeter('Andreas')  ==  'Hello  Andreas'

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

QZUFTUEKBOHP w *OUFHSBUFTQZUFTUBOE%KBOHP w .BOBHFTUIFUFTUEBUBCBTF w "MMPXTEBUBCBTFSFVTF w 1SPWJEFT%KBOHPUFTUIFMQFSTJOBQZUFTUXBZ w $IBOHJOHPGTFUUJOHT w -JWF4FSWFS w VSMDPOGPWFSSJEFT w *OWPLFEWJBpy.testOPUmanage.py  test

Slide 12

Slide 12 text

QZUFTUEKBOHPTFUVQ w pip  install  pytest-­‐django   w 3FRVJSFTZPVSDPEFUPCFPO1ZUIPOQBUI w add2virtualenv  your/project/directory w $POpHVSFTFUUJOHT w 4FUDJANGO_SETTINGS_MODULEJOZPVSTIFMM w 03DSFBUFQZUFTUJOJBOETFU DJANGO_SETTINGS_MODULE=mysettings w #POVT3VO1ZUIPOTIFMMEJSFDUMZXJUIpython

Slide 13

Slide 13 text

8IFSFUPQVUUFTUT w #ZEFGBVMUBOZpMFUIBUNBUDIFTtest_*.py w 5FTUEJTDPWFSZJTDPOpHVSBCMF w 4FUpython_files  =  *.pyJOQZUFTUJOJ w 5FTUTJOBQQEJSFDUPSZ w BQQUFTUTWJFXTQZ w 5FTUTJOTFQBSBUFEJSFDUPSZ w VOJU@UFTUTBQQWJFXTQZ w JOUFHSBUJPO@UFTUTUFTU@TPNFUIJOHQZ w %FQFOETPOZPVSQSPKFDU

Slide 14

Slide 14 text

&YJTUJOHUFTUTVJUF w %KBOHP5FTU$BTFBOEVOJUUFTU5FTU$BTF TVCDMBTTFTJTQJDLFEVQBOESVOBVUPNBUJDBMMZ

Slide 15

Slide 15 text

)PXUPSVOUFTUT #  run  all  tests $  py.test #  run  a  specific  file $  py.test  tests/app/test_views.py #  run  test  which  matches  tests  named  *test_foo* $  py.test  tests/app/test_views.py  -­‐k  test_foo #  run  all  non  database  tests  (more  on  this  later) $  py.test  tests/app  -­‐m  'not  django_db'

Slide 16

Slide 16 text

l5IFSFJTOPTFDSFUUPXSJUJOH UFTUTUIFSFBSFPOMZTFDSFUT UPXSJUJOHUFTUBCMFDPEFz .JãLP)FWFSZ

Slide 17

Slide 17 text

5FTUBCMF%KBOHPDPEF w %BUBCBTFBDDFTTNBLFTUFTUTTMPX w %KBOHP`T03.BOENPEFMTJTHSFBU w 5IFEJTUJODUJPOCFUXFFORVFSZDPEFBOE BQQMJDBUJPODPEFDBOCFCMVSSZ w 1VURVFSZDPEFJONBOBHFSNFUIPET w 5FTUUIPTFXJUIUIFSFBMEBUBCBTF w 1VUBQQMJDBUJPOMPHJDJONFUIPETXIJDIEPFTOPU UIFRVFSZUIFEBUBCBTF w 4UVCCJOHNPDLJOHDBOIFMQXJUIJTPMBUJPO

Slide 18

Slide 18 text

5FTUBCMF%KBOHPDPEF w ,FFQWJFXTWFSZTMJN w 1VTIMPHJDUPGPSNT NPEFMNFUIPETBOE VUJMJUZGVODUJPOTUIBUDBOCFUFTUFEJO JTPMBUJPO w "WPJECSBODIFTJOWJFXTXIFOQPTTJCMF w 5FTUWJFXTXJUIBDPVQMFPGIJHIMFWFMUFTUT XJUIGVMMEBUBCBTFBDDFTT w 4FMFOJVNBOEXFCUFTUBSFHPPEUPPMT

Slide 19

Slide 19 text

5FTUBCMF%KBOHPDPEF w %PO`UCFTDBSFEPGDSFBUJOHPUIFSNPEVMFT FYDFQUWJFXTQZ NPEFMTQZ w 5IFNPSFPGZPVSBQQMJDBUJPOUIBUEPFTOPU EFQFOEPO%KBOHPUIFCFUUFS w .BLFVTFPGUIF1ZUIPONPEVMFTZTUFN JUJT SFBMMZHPPE 

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

%BUBCBTFVTBHF w 8JUIQZUFTUEKBOHP ZPVNVTUCFFYQMJDJUBCPVU EBUBCBTFBDDFTT w %BUBCBTFBDDFTTJTSFRVFTUFEXJUIUIF pytest.mark.django_dbNBSLFS

Slide 22

Slide 22 text

%BUBCBTFVTBHF import  pytest def  test_without_db_access():        #  any  db  accesses  will  raise  an  error        pass @pytest.mark.django_db def  test_with_db_access():        #  test  db  is  available        pass

Slide 23

Slide 23 text

%BUBCBTFVTBHF import  pytest #  Allow  all  tests  in  this  module  database  access pytestmark  =  pytest.mark.django_db def  test_with_db_access_1():        pass def  test_with_db_access_2():        pass def  test_with_db_access_3():        pass

Slide 24

Slide 24 text

5FTUEBUBCBTFSFVTF w 5FTUTTIPVMESVOBHBJOTUUIFSFBMEBUBCBTF w 5BCMFDSFBUJPOUBLFTUJNF w QZUFTUEKBOHPQSPWJEFTUIF-­‐-­‐reuse-­‐dbPQUJPO w 1VUaddopts  =  -­‐-­‐reuse-­‐dbJOQZUFTUJOJ w 1FSTJTUUIFUFTUEBUBCBTFCFUXFFOSVOT w 8IFOVTJOH-­‐-­‐reuse-­‐db QBTT-­‐-­‐create-­‐dbUP GPSDFSFDSFBUJPOPGUIFEBUBCBTF

Slide 25

Slide 25 text

.PEFMUFTUEBUB w )PXUPHFUNPEFMJOTUBODFTGPSUFTUT w $SFBUFPCKFDUTNBOVBMMZ w %KBOHPpYUVSFT OPUQZUFTUpYUVSFT w 'BDUPSJFT

Slide 26

Slide 26 text

%KBOHPUFTUpYUVSFT [ { "model": "myapp.person", "pk": 1, "fields": { "first_name": "John", "last_name": "Lennon" } }, { "model": "myapp.person", "pk": 2, "fields": { "first_name": "Paul", "last_name": "McCartney" } } ]

Slide 27

Slide 27 text

'BDUPSJFTGBDUPSZ@CPZ w )FMQFSGPSDSFBUJOHUFTUPCKFDUT w 4VQQPSUTBVUPNBUJDBMMZDSFBUJOHSFMBUFENPEFMT w .BLFTNPEFMUFTUEBUBNBJOUBJOBCMF w 0WFSSJEFUIFTQFDJpDBUUSJCVUFTUIBUBSF JOUFSFTUJOHJOBUFTU w $BOCFVTFEJOJOUFHSBUJPOUFTUTBOEVOJUUFTUT

Slide 28

Slide 28 text

GBDUPSZ@CPZFYBNQMF #  models.py from  django.db  import  models class  Group(models.Model):        name  =  models.TextField() class  Person(models.Model):        first_name  =  models.TextField()        last_name  =  models.TextField()        group  =  models.ForeignKey(Group)        def  group_letter(self):                return  self.group.name[0].upper()        def  full_name(self):                return  '%s  %s'  %  (self.first_name,                                                    self.last_name) #  factories.py import  factory from  app.models  import  Person,  Group class  GroupFactory(factory.Factory):        FACTORY_FOR  =  Group        name  =  'Developers' class  PersonFactory(factory.Factory):        FACTORY_FOR  =  Person        first_name  =  'John'        last_name  =  'Doe'        group  =  factory.SubFactory(GroupFactory)

Slide 29

Slide 29 text

GBDUPSZ@CPZFYBNQMF from  factories  import  PersonFactory def  test_full_name():        person  =  PersonFactory.build(first_name='Andreas',                                                                  last_name='Pelme')        assert  person.full_name()  ==  'Andreas  Pelme' def  test_group_letter():        person  =  PersonFactory.build(group__name='admins')        assert  person.group_letter()  ==  'A'

Slide 30

Slide 30 text

QZUFTUpYUVSFT w /PUUPCFDPOGVTFEXJUI%KBOHPpYUVSFT w "XBZPGDPOTUSVDUJOHUFTUPCKFDUTBOEUFTU EFQFOEFODJFT w 4JNJMBSUPTFU6QUFBS%PXOCVUNPSFFYQMJDJU BOENPEVMBS

Slide 31

Slide 31 text

QZUFTUpYUVSFT import  pytest from  my_module  import  MyClass @pytest.fixture def  my_object():        return  MyClass() def  test_foo(my_object):        assert  my_object.foo()  ==  'foo' def  test_bar(my_object):        assert  my_object.bar()  ==  'bar'

Slide 32

Slide 32 text

QZUFTUEKBOHPpYUVSFT def  test_changing_settings(settings):        settings.DATE_FORMAT  =  'Y-­‐m-­‐d'        #  call  code  that  uses  settings.DATE_FORMAT  ...          #  the  settings  will  be  automatically  reset  after  this  test def  test_with_testclient(client):        #  client  is  an  instance  of  Django's  TestClient,  just  like        #  self.client  in  a  Django  TestCase        response  =  client.get('/foo/bar')        assert  response.status_code  ==  200

Slide 33

Slide 33 text

'BDUPSZ pYUVSFT import  pytest from  factories  import  PersonFactory @pytest.fixture def  person():        return  PersonFactory.build() def  test_with_person(person):        #  Test  something  on  the  Person  object        pass

Slide 34

Slide 34 text

'BDUPSZ pYUVSFT import  pytest from  factories  import  UserFactory @pytest.fixture def  user_in_db(db):        #  The  db  argument  makes  database  access  allowed        return  UserFactory.create() @pytest.mark.django_db def  test_with_saved_user(user_in_db):        #  user_in_db  is  a  saved  user        pass

Slide 35

Slide 35 text

(SFBUSFTPVSDFT w )PMHFS,SFLFM QZUFTU 1Z$PO w *OUSPEVDUJPOUPQZUFTU TIPXTQZUFTUGFBUVSFTJOEFQUI w IUUQXXXZPVUVCFDPNXBUDI W-7R#2D'NZX w $BSM.FZFS 5FTUJOHBOE%KBOHP 1Z$PO w "MPUPG%KBOHPUFTUJOHCFTUQSBDUJDFT w IUUQXXXZPVUVCFDPNXBUDI WJDL/2D/9J4 w QZUFTUEPDVNFOUBUJPO w IUUQQZUFTUPSH w QZUFTUEKBOHPEPDVNFOUBUJPO w IUUQQZUFTUEKBOHPSFBEUIFEPDTPSH

Slide 36

Slide 36 text

No content