Slide 1

Slide 1 text

5FTUJOH%KBOHPBQQMJDBUJPOT XJUI QZUFTU "OESFBT1FMNF BOESFBT!QFMNFTF !BOESFBTQFMNF personalkollen fredag 5 juli 13

Slide 2

Slide 2 text

5PQJDT w5FTUJOHJO%KBOHP wQZUFTU w%KBOHPBOEQZUFTU w%KBOHPUFTUJOHUJQTUSJDLT fredag 5 juli 13

Slide 3

Slide 3 text

5FTUJOHJO%KBOHP fredag 5 juli 13

Slide 4

Slide 4 text

%KBOHP`TUFTUJOH EPDVNFOUBUJPO fredag 5 juli 13

Slide 5

Slide 5 text

%KBOHPEPDVNFOUBUJPO l*GZPV`WFCFFOVTJOH1ZUIPO GPSBXIJMF EPDUFTUXJMM QSPCBCMZGFFMNPSF lQZUIPOJDzz fredag 5 juli 13

Slide 6

Slide 6 text

%KBOHP`TUFTUJOH EPDVNFOUBUJPO fredag 5 juli 13

Slide 7

Slide 7 text

fredag 5 juli 13

Slide 8

Slide 8 text

%KBOHP`TUFTUSVOOFS fredag 5 juli 13

Slide 9

Slide 9 text

*UJTHFUUJOHCFUUFS Photo: http://www.flickr.com/photos/bee/3290452839/ fredag 5 juli 13

Slide 10

Slide 10 text

0UIFSUFTUJOHUPPMT OPTF UPY 5XJTUFE5SJBM [PQFUFTUSVOOFS fredag 5 juli 13

Slide 11

Slide 11 text

BGVMMGFBUVSFE1ZUIPOUFTUJOHUPPM QZUFTU fredag 5 juli 13

Slide 12

Slide 12 text

TJY .PJO.PJO fredag 5 juli 13

Slide 13

Slide 13 text

1MVHJOT w%JTUSJCVUFEQBSBMMFMJ[FE QZUFTUYEJTU w%KBOHP QZUFTUEKBOHP w-PHDBQUVSF QZUFTUDBQUVSFMPH w$PWFSBHFSFQPSUJOH QZUFTUDPW wBOENBOZNPSF fredag 5 juli 13

Slide 14

Slide 14 text

XJUIPVUCPJMFSQMBUF 1ZUIPOJDUFTUT fredag 5 juli 13

Slide 15

Slide 15 text

from  django.test  import  TestCase class  TestHelloWorld(TestCase):        def  test_hello_world(self):                response  =  self.client.get('/hi/')                self.assertEqual(response.status_code,                                                  200)                self.assertEqual(response.content,                                                  'Hello  World!') fredag 5 juli 13

Slide 16

Slide 16 text

def  test_hello_world(client):        response  =  client.get('/hi/')      assert  response.status_code  ==  200      assert  response.content  ==  'Hello  World!' fredag 5 juli 13

Slide 17

Slide 17 text

def  test_hello_world(client):        response  =  client.get('/hi/')      assert  response.status_code  ==  200      assert  response.content  ==  'Hello  World!' fredag 5 juli 13

Slide 18

Slide 18 text

$  py.test F ===================  FAILURES  ==================== _______________  test_hello_world  ________________ client  =      def  test_hello_world(client):          response  =  client.get('/hi/')          assert  response.status_code  ==  200 >        assert  response.content  ==  'Hello  World!' E        assert  'Hello  EuroPython!'  ==  'Hello  World!' E            -­‐  Hello  EuroPython! E            +  Hello  World! test_hello_world.py:5:  AssertionError fredag 5 juli 13

Slide 19

Slide 19 text

assertAlmostEqual assertAlmostEquals assertDictContainsSubset assertDictEqual assertEqual assertEquals assertFalse assertGreater assertGreaterEqual assertIn assertIs assertIsInstance assertIsNone assertIsNot assertIsNotNone assertItemsEqual assertLess assertLessEqual assertListEqual assertMultiLineEqual assertNotAlmostEqual assertNotAlmostEquals assertNotEqual assertNotEquals assertNotIn assertNotIsInstance assertNotRegexpMatches assertRaises assertRaisesRegexp assertRegexpMatches assertSequenceEqual assertSetEqual assertTrue assertTupleEqual fredag 5 juli 13

Slide 20

Slide 20 text

*OUFHSBUJPOCFUXFFOQZUFTUBOE%KBOHP QZUFTUEKBOHP fredag 5 juli 13

Slide 21

Slide 21 text

*OTUBMMTQZUFTUEKBOHPBOEQZUFTU pip  install  pytest-­‐django fredag 5 juli 13

Slide 22

Slide 22 text

"EETZPVSQSPKFDUUP1ZUIPOQBUI SFRVJSFTBTFUVQQZUPCFQSFTFOU pip  install  -­‐e  . fredag 5 juli 13

Slide 23

Slide 23 text

%FpOF%KBOHPTFUUJOHTJOZPVSTIFMM FOWJSPONFOU export  DJANGO_SETTINGS_MODULE=settings fredag 5 juli 13

Slide 24

Slide 24 text

#POVT -BVODIB1ZUIPOTIFMM XJUIPVUNBOBHFQZ Photo: http://www.flickr.com/photos/mark_i_geo/3498456758 fredag 5 juli 13

Slide 25

Slide 25 text

$BOBMTPCFDPOpHVSFEJOQZUFTUJOJ [pytest] DJANGO_SETTINGS_MODULE=settings fredag 5 juli 13

Slide 26

Slide 26 text

)PXUPSVOUIFUFTUT fredag 5 juli 13

Slide 27

Slide 27 text

3VOBMMUIFUFTUT $  py.test fredag 5 juli 13

Slide 28

Slide 28 text

3VOBMMUFTUTJOBTQFDJpDpMF $  py.test  test_views.py fredag 5 juli 13

Slide 29

Slide 29 text

3VOBMMUFTUDBTFTUIBUBSFOBNFE UFTU@GPP $  py.test  -­‐k  test_foo fredag 5 juli 13

Slide 30

Slide 30 text

8IFSFUPQVUUIFUFTUT fredag 5 juli 13

Slide 31

Slide 31 text

#ZEFGBVMU UFTUTBSFGPVOEJO test_*.py fredag 5 juli 13

Slide 32

Slide 32 text

$POpHVSBCMFJOQZUFTUJOJ [pytest] python_files  =  *.py fredag 5 juli 13

Slide 33

Slide 33 text

5FTUTDBOMJWFVOEFS%KBOHPBQQT polls/tests/views.py blog/tests/views.py fredag 5 juli 13

Slide 34

Slide 34 text

5FTUTDBOMJWFJOUIFJSPXOSPPUEJSFDUPSZ tests/polls/views.py tests/blog/models.py fredag 5 juli 13

Slide 35

Slide 35 text

5FTUTCFTQMJUVQJOUPEJGGFSFOUSPPU EJSFDUPSJFT unit_tests/blog/models.py functional_tests/test_foo.py fredag 5 juli 13

Slide 36

Slide 36 text

%KBOHP5FTU$BTFT KVTUXPSLT fredag 5 juli 13

Slide 37

Slide 37 text

3FVTFEBUBCBTFGSPNMBTUSVO py.test  -­‐-­‐reuse-­‐db fredag 5 juli 13

Slide 38

Slide 38 text

1VUUIJTJOQZUFTUJOJUPBMXBZTSFVTFUIF EBUBCBTF 1BTTDSFBUFECUPGPSDFSFDSFBUJPO [pytest] addopts  =  -­‐-­‐reuse-­‐db fredag 5 juli 13

Slide 39

Slide 39 text

5FTUBCMF%KBOHPDPEF fredag 5 juli 13

Slide 40

Slide 40 text

.JãLP)FWFSZ l5IFSFJTOPTFDSFUUPXSJUJOH UFTUTUIFSFBSFPOMZTFDSFUT UPXSJUJOHUFTUBCMFDPEFz fredag 5 juli 13

Slide 41

Slide 41 text

NPEFMTQZ WJFXTQZ fredag 5 juli 13

Slide 42

Slide 42 text

NPEFMTQZ WJFXTQZ BENJOQZ GPSNTQZ fredag 5 juli 13

Slide 43

Slide 43 text

NPEFMTQZ WJFXTQZ BENJOQZ GPSNTQZ FHH@NBLFSQZ TQBN@IFMQFSTQZ DPPLJF@FBUFSQZ fredag 5 juli 13

Slide 44

Slide 44 text

,FFQUIFNTNBMM GFXCSBODIFT 5FTUJOHWJFXT fredag 5 juli 13

Slide 45

Slide 45 text

from  datetime  import  datetime,  time from  django.http  import  HttpResponse def  greet(request):        now  =  datetime.now().time()        if  time(5)  <  now  <  time(12):                greeting  =  'morning'        elif  time(18)  <  now  <  time(21):                greeting  =  'evening'        else:                greeting  =  'day'        return  HttpResponse('Good  %s!'  %  greeting) fredag 5 juli 13

Slide 46

Slide 46 text

from  datetime  import  datetime,  time from  django.http  import  HttpResponse def  greet(request):        now  =  datetime.now().time()        if  time(5)  <  now  <  time(12):                greeting  =  'morning'        elif  time(18)  <  now  <  time(21):                greeting  =  'evening'        else:                greeting  =  'day'        return  HttpResponse('Good  %s!'  %  greeting) fredag 5 juli 13

Slide 47

Slide 47 text

#  greeter.py from  datetime  import  time def  greeting_at(time_of_day):        if  time(5)  <  time_of_day  <  time(12):                return  'morning'        elif  time(18)  <  time_of_day  <  time(21):                return  'evening'        else:                return  'day' fredag 5 juli 13

Slide 48

Slide 48 text

#  views.py from  datetime  import  time from  django.http  import  HttpResponse from  .greeter  import  greeting_at def  greet(request):        now  =  datetime.now().time()        greeting  =  greeting_at(now)        return  HttpResponse('Good  %s!'  %                                                greeting) fredag 5 juli 13

Slide 49

Slide 49 text

NBLFTZPVSUFTUTTMPX %BUBCBTFBDDFTT fredag 5 juli 13

Slide 50

Slide 50 text

fredag 5 juli 13

Slide 51

Slide 51 text

UFTUJOH UFTUJOH fredag 5 juli 13

Slide 52

Slide 52 text

5IF03.CMVSTUIFMJOFCFUXFFO BQQMJDBUJPODPEFBOERVFSZDPEF 4FQBSBUFUIFRVFSZDPEFJOUPJUTPXO NFUIPET .JOEZPVSRVFSJFT fredag 5 juli 13

Slide 53

Slide 53 text

fredag 5 juli 13

Slide 54

Slide 54 text

! 6 '" fredag 5 juli 13

Slide 55

Slide 55 text

fredag 5 juli 13

Slide 56

Slide 56 text

QZUFTUEKBOHPBOEEBUBCBTFT fredag 5 juli 13

Slide 57

Slide 57 text

5IJTXJMMBMMPXEBUBCBTFBDDFTT import  pytest @pytest.mark.django_db def  test_user_count():        assert  User.objects.count()  ==  0 fredag 5 juli 13

Slide 58

Slide 58 text

5IJTXJMMGBJM EBUBCBTFBDDFTTJTOPU BMMPXFE def  test_user_count():        assert  User.objects.count()  ==  0 fredag 5 juli 13

Slide 59

Slide 59 text

___________  test_user_count  ____________ test_db_access.py:4:  in  test_user_count >      assert  User.objects.count()  ==  0 ...  snip  ... E      Failed:  Database  access  not  allowed,        use  the  "django_db"  mark  to  enable fredag 5 juli 13

Slide 60

Slide 60 text

.BSLBOFOUJSFNPEVMFGPSEBUBCBTF VTBHF import  pytest pytestmark  =  pytest.mark.django_db def  test_foo():  pass def  test_bar():  pass fredag 5 juli 13

Slide 61

Slide 61 text

3VOBMMUFTUTXIJDIEPFTOPUUPVDIUIF EBUBCBTF $  py.test  -­‐m  'not  django_db' fredag 5 juli 13

Slide 62

Slide 62 text

.PEFMUFTUEBUB w$SFBUFPCKFDUTNBOVBMMZ w%KBOHPpYUVSFT w'BDUPSJFT fredag 5 juli 13

Slide 63

Slide 63 text

%KBOHPpYUVSFT [{"model": "myapp.person", "pk": 1, "fields": {"first_name": "John", "last_name": "Lennon"}}, {"model": "myapp.person", "pk": 2, "fields": {"first_name": "Paul", "last_name": "McCartney"}} ] Slow & hard to maintain.. avoid them! fredag 5 juli 13

Slide 64

Slide 64 text

GBDUPSZ@CPZJTBOFYDFMMFOUMJCSBSZ 5IFTPMVUJPOGBDUPSJFT fredag 5 juli 13

Slide 65

Slide 65 text

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() fredag 5 juli 13

Slide 66

Slide 66 text

import  factory from  yourapp.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) fredag 5 juli 13

Slide 67

Slide 67 text

from  yourfactories  import  PersonFactory def  test_group_letter():        person  =  PersonFactory.build(                group__name='admins')        assert  person.group_letter()  ==  'A' fredag 5 juli 13

Slide 68

Slide 68 text

import  pytest @pytest.mark.django_db def  test_group_letter():        person  =  PersonFactory.create(                group__name='admins')        assert  person.group_letter()  ==  'A' fredag 5 juli 13

Slide 69

Slide 69 text

3FQMBDFNFOUGPSVOJUUFTUTFU6QUFBS%PXO QZUFTUpYUVSFT fredag 5 juli 13

Slide 70

Slide 70 text

(FUBOJOTUBODFPGUIFUFTUDMJFOU def  test_with_client(client):        response  =  client.get('/foo/')        assert  response.status_code  ==  200 fredag 5 juli 13

Slide 71

Slide 71 text

5IFTFUUJOHTXJMMCFBVUPNBUJDBMMZSFTFU BGUFSUIFUFTU def  test_foo(settings):        settings.DATE_FORMAT  =  'Y-­‐m-­‐d' fredag 5 juli 13

Slide 72

Slide 72 text

$SFBUFZPVSPXOpYUVSFTXJUI QZUFTUpYUVSF import  pytest @pytest.fixture def  person():        return  PersonFactory.build() fredag 5 juli 13

Slide 73

Slide 73 text

3FRVFTU%KBOHPEBUBCBTFBDDFTT JOBpYUVSF import  pytest from  your_factories  import  UserFactory @pytest.fixture def  person_in_db(db):        return  PersonFactory.create() fredag 5 juli 13

Slide 74

Slide 74 text

(SFBUSFTPVSDFT w $BSM.FZFS 5FTUJOHBOE%KBOHP 1Z$PO w %KBOHPUFTUJOHCFTUQSBDUJDFTBOEJOTQJSBUJPOGPSUIJTUBML w IUUQXXXZPVUVCFDPNXBUDI WJDL/2D/9J4 w )PMHFS,SFLFM QZUFTUSBQJEBOETJNQMFUFTUJOHXJUI1ZUIPO  &VSP1ZUIPO w IUUQXXXZPVUVCFDPNXBUDI WL;+)6N;9. w QZUFTUEPDVNFOUBUJPO w IUUQQZUFTUPSH w QZUFTUEKBOHPEPDVNFOUBUJPO w IUUQQZUFTUEKBOHPSFBEUIFEPDTPSH fredag 5 juli 13

Slide 75

Slide 75 text

QZUFTUTQSJOU fredag 5 juli 13

Slide 76

Slide 76 text

8PSLTXJUICPUI XPSMET fredag 5 juli 13

Slide 77

Slide 77 text

4MJEFTIUUQTQFBLFSEFDLDPNQFMNF BOESFBT!QFMNFTF !BOESFBTQFMNF 5IBOL:PV fredag 5 juli 13