Slide 1

Slide 1 text

Behavior-Driven Development in Python @zacstewart

Slide 2

Slide 2 text

import unittest

Slide 3

Slide 3 text

import unittest import pyspec

Slide 4

Slide 4 text

This Talk

Slide 5

Slide 5 text

What is behavior-driven development?

Slide 6

Slide 6 text

How does PySpec realize it?

Slide 7

Slide 7 text

What's inside?

Slide 8

Slide 8 text

Behavior-Driven Development

Slide 9

Slide 9 text

Specific about behavior, not implementation

Slide 10

Slide 10 text

G i v e n a n A T M A n d a d e b i t c a r d W h e n I w i t h d r a w $ 4 0 T h e n t h e A T M s h o u l d d i s p e n s e $ 4 0

Slide 11

Slide 11 text

Ubiquitous language

Slide 12

Slide 12 text

Stories and specifications

Slide 13

Slide 13 text

PySpec

Slide 14

Slide 14 text

Expectations

Slide 15

Slide 15 text

# B o o l e a n a s s e r t i o n e x p e c t ( i s _ p r i m e ( 1 7 ) ) . t o ( b e ( T r u e ) ) # N e g a t i o n e x p e c t ( i s _ p r i m e ( 4 ) ) . n o t _ t o ( b e ( T r u e ) ) # E q u a l i t y e x p e c t ( f i z z b u z z ( 3 ) ) . t o ( e q ( ' f i z z ' ) )

Slide 16

Slide 16 text

# C o m p a r i s o n e x p e c t ( g o k u . p o w e r _ l e v e l ) . t o ( b e _ g t ( 9 0 0 0 ) ) # I n c l u s i o n e x p e c t ( l i b r a r y ) . t o ( i n c l u d e ( ' O n e H u n d r e d Y e a r s o f S o l i t u d e ' ) ) # R e g u l a r e x p r e s s i o n m a t c h i n g e x p e c t ( p a g e . b o d y ) . t o ( m a t c h ( r ' W e l c o m e , b a c k ! ' ) ) # E r r o r s e x p e c t ( c o n n e c t i o n . e x e c u t e , i n v a l i d _ q u e r y ) . t o ( r a i s e _ e r r o r ( I n v a l i d Q u e r y E r r o r ) )

Slide 17

Slide 17 text

Specifications

Slide 18

Slide 18 text

w i t h s p e c i f i c a t i o n ( ' d i s p l a y s a w e l c o m e m e s s a g e ' ) : s i g n _ i n ( u s e r ) e x p e c t ( p a g e . b o d y ) . t o ( m a t c h ( r ' W e l c o m e , b a c k ! ' ) )

Slide 19

Slide 19 text

w i t h s p e c i f i c a t i o n ( ' d i s p e n s e s t h e m o n e y ' ) : a t m . w i t h d r a w ( 4 0 . 0 0 , c a r d = c a r d ) e x p e c t ( a t m . d i s p e n s a t i o n ) . t o ( e q ( 4 0 . 0 0 ) )

Slide 20

Slide 20 text

Contexts

Slide 21

Slide 21 text

w i t h d e s c r i p t i o n ( A T M ) : a t m = A T M ( ) w i t h d e s c r i p t i o n ( ' . w i t h d r a w ' ) : c a r d = C a r d ( ) w i t h s p e c i f i c a t i o n ( ' d i s p e n s e s t h e m o n e y ' ) : a t m . w i t h d r a w ( 4 0 . 0 0 , c a r d = c a r d ) e x p e c t ( a t m . d i s p e n s a t i o n ) . t o ( e q ( 4 0 . 0 0 ) ) w i t h c o n t e x t ( ' w h e n u s e r h a s a c a r d f r o m a n o t h e r b a n k ' ) : c a r d = C a r d ( b a n k = ' O t h e r B a n k ' ) w i t h s p e c i f i c a t i o n ( ' n o t i f i e s t h e u s e r o f a f e e ' ) : a t m . w i t h d r a w ( 4 0 . 0 0 , c a r d = c a r d ) e x p e c t ( a t m . d i s p l a y ) . t o ( m a t c h ( r ' $ 3 . 0 0 f e e ' )

Slide 22

Slide 22 text

What's inside

Slide 23

Slide 23 text

expect(actual).to(eq(expected)) e x p e c t creates a T a r g e t wrapping the a c t u a l value matcher functions like e q and i n c l u d e create M a t c h e r s with the e x p e c t e d value t o and n o t _ t o methods of T a r g e t verify that the M a t c h e r matches or does not match

Slide 24

Slide 24 text

c l a s s E q u a l i t y M a t c h e r ( M a t c h e r ) : d e f m a t c h ( s e l f , e x p e c t e d , a c t u a l ) : r e t u r n e x p e c t e d = = a c t u a l @ p r o p e r t y d e f f a i l u r e _ m e s s a g e ( s e l f ) : r e t u r n " E x p e c t e d { 0 } t o b e e q u a l t o { 1 } " . f o r m a t ( s e l f . a c t u a l , s e l f . e x p e c t e d ) @ p r o p e r t y d e f f a i l u r e _ m e s s a g e _ w h e n _ n e g a t e d ( s e l f ) : r e t u r n " E x p e c t e d { 0 } n o t t o b e e q u a l t o { 1 } " . f o r m a t ( s e l f . a c t u a l , s e l f . e x p e c t e d ) d e f e q ( e x p e c t e d ) : r e t u r n E q u a l i t y M a t c h e r ( e x p e c t e d )

Slide 25

Slide 25 text

c l a s s P o s i t i v e H a n d l e r ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , a c t u a l , m a t c h e r ) : s e l f . a c t u a l = a c t u a l s e l f . m a t c h e r = m a t c h e r d e f r e s o l v e ( s e l f ) : i f n o t s e l f . m a t c h e r . m a t c h e s ( s e l f . a c t u a l ) : s e l f . h a n d l e _ f a i l u r e ( ) d e f h a n d l e _ f a i l u r e ( s e l f ) : r a i s e E x p e c t a t i o n N o t M e t E r r o r ( s e l f . m a t c h e r . f a i l u r e _ m e s s a g e )

Slide 26

Slide 26 text

with specification('dispenses the money'):

Slide 27

Slide 27 text

c l a s s s p e c i f i c a t i o n ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , d e s c r i p t i o n ) : s e l f . d e s c r i p t i o n = d e s c r i p t i o n d e f _ _ e n t e r _ _ ( s e l f ) : p a s s d e f _ _ e x i t _ _ ( s e l f , t y p e , v a l u e , t r a c e b a c k ) : i f t y p e i s N o n e : s u i t e . r e p o r t _ s u c c e s s ( s e l f ) e l i f i s i n s t a n c e ( v a l u e , A s s e r t i o n E r r o r ) : s u i t e . r e p o r t _ f a i l u r e ( s e l f , v a l u e ) e l s e : s u i t e . r e p o r t _ e r r o r ( s e l f , v a l u e ) r e t u r n T r u e . . .

Slide 28

Slide 28 text

with context('using a card from another bank'):

Slide 29

Slide 29 text

c l a s s c o n t e x t ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , d e s c r i p t i o n = N o n e ) : s e l f . d e s c r i p t i o n = d e s c r i p t i o n d e f _ _ e n t e r _ _ ( s e l f ) : s u i t e . c o n t e x t = C o n t e x t ( s u i t e . c o n t e x t , s e l f . d e s c r i p t i o n ) d e f _ _ e x i t _ _ ( s e l f , t y p e , v a l u e , t r a c e b a c k ) : s u i t e . c o n t e x t = s u i t e . c o n t e x t . p a r e n t

Slide 30

Slide 30 text

c l a s s S u i t e ( o b j e c t ) : d e f _ _ i n i t _ _ ( s e l f , o u t = s y s . s t d o u t ) : d e f i s _ g r e e n ( s e l f ) : d e f r e p o r t _ s u c c e s s ( s e l f , s p e c i f i c a t i o n ) : d e f r e p o r t _ f a i l u r e ( s e l f , s p e c i f i c a t i o n , f a i l u r e ) : d e f r e p o r t _ e r r o r ( s e l f , s p e c i f i c a t i o n , e r r o r ) : d e f r e p o r t _ r e s u l t s ( s e l f ) :

Slide 31

Slide 31 text

The worst thing I've ever done to Python?

Slide 32

Slide 32 text

d e f r u n _ s p e c ( f i l e n a m e ) : a s t = c o m p i l e ( o p e n ( f i l e n a m e , ' r b ' ) . r e a d ( ) , f i l e n a m e , ' e x e c ' ) e x e c ( a s t , g l o b a l s ( ) , l o c a l s ( ) )

Slide 33

Slide 33 text

Thank you! Questions? @zacstewart github.com/zacstewart/pyspec