Test du futur avec Spock

2,028 views
1,914 views

Published on

Mathilde lemee @Mix-IT 2011

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,028
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
7
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • Pas que du mock Test full stack
  • Exemple 1
  • Pour les prochains slides voilà la méthode sur laquelle nous allons nous appuyer
  • Exemple 2 simple
  • Test du futur avec Spock

    1. 1. Tests du futur avec Spock LEMEE Mathilde Indépendante Email : mathilde@java-freelance.fr Twitter : @MathildeLemee LinkedIn : http://fr.linkedin.com/in/ MathildeLemee Blog : http://www.java-freelance.fr
    2. 2. Problématique
    3. 3. Spock
    4. 4. <ul><li>def &quot;stack should pus h&quot; (){ </li></ul><ul><li>given: </li></ul><ul><li>def stack = new Stack(); </li></ul><ul><li>def elem = &quot;push me&quot; </li></ul><ul><li>when: </li></ul><ul><li>stack.push(elem) </li></ul><ul><li>then: </li></ul><ul><li>!stack.empty </li></ul><ul><li>stack.size() == 1 </li></ul><ul><li>stack.peek() == elem </li></ul><ul><li>} </li></ul>
    5. 5. <ul><li>Map<String, User> dummyData ; </li></ul><ul><li>public UserService() { </li></ul><ul><li>dummyData = new HashMap<String, User>(); </li></ul><ul><li>dummyData .put( &quot;user1&quot; , new User( &quot;John&quot; , &quot;Doe&quot; , 123456)); </li></ul><ul><li>dummyData .put( &quot;user2&quot; , new User( &quot;Jane&quot; , &quot;Doe&quot; , 654321)); </li></ul><ul><li>dummyData .put( &quot;user3&quot; , new User( &quot;John&quot; , &quot;Smith&quot; , 789987));} </li></ul><ul><li>public User get(String username) { </li></ul><ul><li>return dummyData .get(username);} </li></ul>
    6. 6. <ul><li>public void userShouldBeWellFilled() { </li></ul><ul><li>given: </li></ul><ul><li>UserService service = new UserService() </li></ul><ul><li>when: </li></ul><ul><li>User user = service.get( &quot;user1&quot; ) </li></ul><ul><li>then: </li></ul><ul><li>user. firstName == 'John' </li></ul><ul><li>user. lastName == 'Doe' </li></ul><ul><li>user. id == 123456 } </li></ul><ul><li>} </li></ul>
    7. 7. Blocs <ul><li>given = setup </li></ul><ul><li>when – then ou expect </li></ul><ul><li>where </li></ul><ul><li>cleanup </li></ul>
    8. 8. <ul><li>when: </li></ul><ul><li>def x = Math.max(1, 2) </li></ul><ul><li>then: </li></ul><ul><li>x == 2 </li></ul><ul><li>expect: </li></ul><ul><li>Math.max(1, 2) == 2 </li></ul>
    9. 9. Equivalent Spock - jUnit <ul><li>setup() @Before </li></ul><ul><li>cleanup() @After </li></ul><ul><li>setupSpec() @BeforeClass </li></ul><ul><li>cleanupSpec() @AfterClass </li></ul>
    10. 10. setup <ul><li>SecurityService securityService ; </li></ul><ul><li>UserService service ; </li></ul><ul><li>def setup() { </li></ul><ul><li>securityService = Mock(SecurityService) </li></ul><ul><li>service = new UserService() </li></ul><ul><li>service . securityService = securityService </li></ul><ul><li>} </li></ul>
    11. 11. Rappel <ul><li>Stub = Bouchon = Stupide </li></ul><ul><ul><li>=> Test d'état </li></ul></ul><ul><li>Mock = Simulacre = Intelligent </li></ul><ul><ul><li>=> Test comportement </li></ul></ul>
    12. 12. <ul><li>public User getManager(String username) { </li></ul><ul><li>User manager = securityService .getManager(username); </li></ul><ul><li>if (manager == null ) { </li></ul><ul><li>manager = dummyData .get( &quot;user1&quot; ); </li></ul><ul><li>} </li></ul><ul><li>return manager; </li></ul><ul><li>} </li></ul>
    13. 13. + Spock <ul><li>securityService.getManager( &quot;user2&quot; )>> new User(firstName: &quot;John&quot; , lastName: &quot;Smith&quot; , id: 789986 ) </li></ul><ul><li>securityService.getManager( &quot;user2&quot; ) </li></ul><ul><li>>>>[ new User( &quot;John&quot; ),new User( &quot;J&quot;)] </li></ul>
    14. 14. Stub <ul><li>given: </li></ul><ul><li>securityService .getManager( &quot;user2&quot; )>> new User( &quot;John&quot; , &quot;Smith&quot; , 789986 ) </li></ul><ul><li>when: </li></ul><ul><li>User manager = service .getManager( &quot;user2&quot; ) </li></ul><ul><li>then: </li></ul><ul><li>manager. id == 789986 </li></ul>
    15. 15. Interaction <ul><li>mock.receive() </li></ul><ul><li>mock.receive(_) </li></ul><ul><li>mock.receive(!null) </li></ul><ul><li>mock.receive(event) </li></ul><ul><li>mock.receive(!event) </li></ul><ul><li>mock.receive(_ as Message) </li></ul><ul><li>mock./set.*/(_) </li></ul>
    16. 16. <ul><li>def &quot;getManager should securityService.getManage r&quot; () { </li></ul><ul><li>when: </li></ul><ul><li>service . getManager &quot;user1&quot; </li></ul><ul><li>then: </li></ul><ul><li>1 * securityService .getManager ( _ ) </li></ul>
    17. 17. Cardinalité <ul><li>1 * </li></ul><ul><li>(n.._) </li></ul><ul><li>(_..n) </li></ul><ul><li>0 * _ </li></ul>
    18. 18. Argument Matcher <ul><li>public Boolean auditByUser(String username) { </li></ul><ul><li>User user = dummyData .get(username); </li></ul><ul><li>return securityService .hasAccess(user); </li></ul><ul><li>} </li></ul>
    19. 19. <ul><li>@Test </li></ul><ul><li>public void testArgumentMatcher() { </li></ul><ul><li>userService .auditByUser( &quot;user1&quot; ); </li></ul><ul><li>verify ( securityService ).hasAccess( argThat ( new isUserId123456())); </li></ul><ul><li>} </li></ul><ul><li>class isUserId123456 extends ArgumentMatcher<User> { </li></ul><ul><li>public boolean matches(Object object) { </li></ul><ul><li>return ((User) object).getId() == 123456; </li></ul><ul><li>}} </li></ul>
    20. 20. <ul><li>when: </li></ul><ul><li>service.auditByUser( &quot;user1&quot; ) </li></ul><ul><li>then: </li></ul><ul><li>1 *securityService.hasAccess { it . id == 123456 } </li></ul><ul><li>} </li></ul>
    21. 21. Exceptions <ul><li>@Test (expected = RuntimeException. class ) </li></ul><ul><li>public void testRuntimeExceptionShouldNotBeCatch() { </li></ul><ul><li>when ( userService .getManager( &quot;user1&quot; )).thenThrow( new RuntimeException()); </li></ul><ul><li>userService .getManager( &quot;user1&quot; ); </li></ul><ul><li>} </li></ul>
    22. 22. <ul><li>securityService.getManager( &quot;user2&quot; )>>{ throw new RuntimeException()} </li></ul><ul><li>when: </li></ul><ul><li>service.getManager( &quot;user2&quot; ) </li></ul><ul><li>then: </li></ul><ul><li>thrown(RuntimeException) </li></ul>
    23. 23. Exceptions <ul><li>… >> {throw …} </li></ul><ul><li>thrown / notThrown </li></ul><ul><li>@FailsWith </li></ul>
    24. 24. Data Driven Testing
    25. 25. <ul><li>def &quot;user should be well file d&quot; () { </li></ul><ul><li>setup: </li></ul><ul><li>User service = new UserService() </li></ul><ul><li>expect: </li></ul><ul><li>User user = service.get( username ) </li></ul><ul><li>user. firstName == firstname </li></ul><ul><li>user. id == userID </li></ul><ul><li>where: </li></ul><ul><li>username << [ 'user1' , 'user2' , 'user3' ] </li></ul><ul><li>firstname << [ 'John' , 'Jane' , 'John' ] </li></ul><ul><li>UserID << [ 123456 , 654321 , 789987 ] </li></ul><ul><li>} </li></ul>
    26. 26. <ul><li>def &quot;user should be well filed with table forma t&quot; () { </li></ul><ul><li>setup: </li></ul><ul><li>UserService service = new UserService() </li></ul><ul><li>expect: </li></ul><ul><li>User user = service.get( username ) </li></ul><ul><li>user. firstName == firstname </li></ul><ul><li>user. id == userID </li></ul><ul><li>where: </li></ul><ul><li>username | firstname | lastname | userID </li></ul><ul><li>'user1' | 'John' | 'Doe' | 123456 </li></ul><ul><li>'user2' | 'Jane' | 'Doe' | 654321 </li></ul><ul><li>'user3' | 'John' | 'Smith' | 789987 </li></ul>
    27. 27. @Unroll <ul><li>@Unroll ( &quot;user #username should be #firstname #lastname with id #userID&quot; ) </li></ul><ul><li>def &quot;user should be well filed with table format and unrol l&quot; () { </li></ul><ul><li>[...] </li></ul><ul><li>where: </li></ul><ul><li>username | firstname | lastname | userID </li></ul><ul><li>'user1' | 'John' | 'Doe' | 123456 </li></ul><ul><li>'user2' | 'Jane' | 'Doe' | 654321 </li></ul><ul><li>'user3' | 'John' | 'Smith' | 789987 </li></ul><ul><li>} </li></ul>
    28. 28. Comparaison <ul><li>Junit </li></ul>
    29. 29. <ul><li>@RunWith (Parameterized. class ) </li></ul><ul><li>public class DataDrivenSimpleTest { </li></ul><ul><li>private String username ; </li></ul><ul><li>private String firstName ; </li></ul><ul><li>private String lastName ; </li></ul><ul><li>private int id ; </li></ul><ul><li>@Parameters </li></ul><ul><li>public static Collection<Object[]> data() { </li></ul><ul><li>return Arrays. asList ( new Object[][] { </li></ul><ul><li> { &quot;user1&quot; , &quot;John&quot; , &quot;Doe&quot; , 123456}, </li></ul><ul><li> { &quot;user2&quot; , &quot;Jane&quot; , &quot;Doe&quot; , 654321}, </li></ul><ul><li> { &quot;user3&quot; , &quot;John&quot; , &quot;Smith&quot; , 789987 }}); </li></ul><ul><li>} </li></ul>
    30. 30. <ul><li>public DataDrivenSimpleTest(String username,String firstName, String lastName, int id) { </li></ul><ul><li>super (); </li></ul><ul><li>this . username =username; </li></ul><ul><li>this . firstName = firstName; </li></ul><ul><li>this . lastName = lastName; </li></ul><ul><li>this . id = id; } </li></ul><ul><li>@Test </li></ul><ul><li>public void testUserService() { </li></ul><ul><li>UserService userService = new UserService(); </li></ul><ul><li>User user = (User)userService.get( username ); </li></ul><ul><li>assertEquals (user.getFirstName(), firstName ); </li></ul><ul><li>assertEquals (user.getLastName(), lastName ); </li></ul><ul><li>assertEquals (user.getId(), id ); </li></ul>
    31. 31. <ul><li>@Test </li></ul><ul><li>public void testUserService() { </li></ul><ul><li>def userService = new UserService() </li></ul><ul><li>[ </li></ul><ul><li>user1: [ 'John' , 'Doe' , 123456 ], </li></ul><ul><li>user2: [ 'Jane' , 'Doe' , 654321 ], </li></ul><ul><li>user3: [ 'John' , 'Smith' , 789987 ], </li></ul><ul><li>]. each { username, userData -> </li></ul><ul><li>def user = userService.get(username) </li></ul><ul><li>assert user. firstName == userData[ 0 ] </li></ul><ul><li>assert user. lastName == userData[ 1 ] </li></ul><ul><li>assert user. id == userData[ 2 ] </li></ul>
    32. 32. <ul><li>def &quot;user should be well filed with table forma t&quot; () { </li></ul><ul><li>setup: </li></ul><ul><li>def service = new UserService() </li></ul><ul><li>expect: </li></ul><ul><li>def user = service.get( username ) </li></ul><ul><li>user. firstName == firstname </li></ul><ul><li>user. id == userID </li></ul><ul><li>where: </li></ul><ul><li>username | firstname | lastname | userID </li></ul><ul><li>'user1' | 'John' | 'Doe' | 123456 </li></ul><ul><li>'user2' | 'Jane' | 'Doe' | 654321 </li></ul><ul><li>'user3' | 'John' | 'Smith' | 789987 </li></ul>
    33. 33. Léger
    34. 34. Vraiment différent
    35. 35. Nouveautés <ul><li>Dynamic reordering </li></ul><ul><li>Hamcrest </li></ul><ul><li>IDE </li></ul>
    36. 36. Démo 1
    37. 37. Et ailleurs ?
    38. 38. Geb <ul><li>class GebGoogleTest extends GebTest { </li></ul><ul><li>String getBaseUrl() { </li></ul><ul><li>&quot;http://geb.codehaus.org&quot; </li></ul><ul><li>} </li></ul><ul><li>void testSomething() { </li></ul><ul><li>go &quot;/manual/latest/index.html&quot; </li></ul><ul><li>assert $ ( &quot;h1&quot; ). text () == &quot;The Book Of Geb&quot; </li></ul><ul><li>} </li></ul>
    39. 39. <ul><li>void testGoogleHomePage(){ </li></ul><ul><li>go &quot;/wiki/Wikip%C3%A9dia:Accueil_principal&quot; </li></ul><ul><li>assert $ ( &quot;title&quot; ). text () == &quot;Wikipédia, l'encyclopédie libre&quot; </li></ul><ul><li>} </li></ul><ul><li>void testGoogleHomePage(){ </li></ul><ul><li>when : </li></ul><ul><li>go &quot;/wiki/Wikip%C3%A9dia:Accueil_principal&quot; </li></ul><ul><li>then : </li></ul><ul><li>$ ( &quot;title&quot; ). text () == &quot;Wikipédia, l'encyclopédie libre&quot; </li></ul><ul><li>} </li></ul>
    40. 40. <ul><li>void testWikipediaSearch() { </li></ul><ul><li>go &quot;/wiki/Wikip%C3%A9dia:Accueil_principal&quot; </li></ul><ul><li>// enter wikipedia into the search field </li></ul><ul><li>$ ( &quot;input&quot; , name: &quot;search&quot; ). value ( &quot;spock&quot; ) </li></ul><ul><li>def firstLink = $ ( &quot;button&quot; , name: &quot;button&quot; ) </li></ul><ul><li>firstLink. click () </li></ul><ul><li>assert $ ( &quot;a&quot; , title: &quot;Spock (Star Trek)&quot; ). text () == &quot;Spock&quot; </li></ul><ul><li>} </li></ul>
    41. 41. <ul><li>void testWikipediaSearch() { </li></ul><ul><li>given : </li></ul><ul><li>go &quot;/wiki/Wikip%C3%A9dia:Accueil_principal&quot; </li></ul><ul><li>$ ( &quot;input&quot; , name: &quot;search&quot; ). value ( &quot;spock&quot; ) </li></ul><ul><li>def firstLink = $ ( &quot;button&quot; , name: &quot;button&quot; ) </li></ul><ul><li>when : </li></ul><ul><li>firstLink. click () </li></ul><ul><li>then : </li></ul><ul><li>$ ( &quot;a&quot; , title: &quot;Spock (Star Trek)&quot; ). text () == &quot;Spock&quot; </li></ul><ul><li>} </li></ul>
    42. 42. Page Object Pattern
    43. 43. <ul><li>Demo 2 </li></ul>
    44. 44. Grails <ul><li>mockDomain(class, testInstances = )mockForConstraintsTests(class,testInstances= </li></ul><ul><li>mockLogging(class, enableDebug = false) </li></ul><ul><li>mockController(class) </li></ul><ul><li>mockTagLib(class) </li></ul>
    45. 45. <ul><li>class Author { </li></ul><ul><li>String firstname </li></ul><ul><li>String lastname </li></ul><ul><li>static hasMany = [books:Book] </li></ul><ul><li>static constraints = { </li></ul><ul><li>firstname (blank: false ,maxSize: 20 ) </li></ul><ul><li>lastname (blank: false ,maxSize: 20 ) </li></ul><ul><li>} </li></ul><ul><li>String toString(){ </li></ul><ul><li>&quot;$ firstname $ lastname ($ id )&quot; } </li></ul>
    46. 46. Grails Domain <ul><li>void testLastNameConstraints() { </li></ul><ul><li>mockForConstraintsTests(Author) </li></ul><ul><li>[test1: [ &quot;123456789012345678901&quot; , false ], </li></ul><ul><li>test2: [ &quot;12345678901234567890&quot; , true ], </li></ul><ul><li>test3: [ &quot;&quot; , false ], </li></ul><ul><li>]. each { test, testData -> </li></ul><ul><li>def author = new Author(firstname: &quot;John&quot; , lastname: testData[ 0 ]) </li></ul><ul><li>author.validate() </li></ul><ul><li>assert author. hasErrors () == !testData[ 1 ] } </li></ul>
    47. 47. <ul><li>def &quot;lastname constraint s&quot; () { </li></ul><ul><li>setup: </li></ul><ul><li>mockForConstraintsTests(Author) </li></ul><ul><li>when: </li></ul><ul><li>def author = new Author(firstname: &quot;John&quot; , lastname: lastname ) </li></ul><ul><li>author.validate() </li></ul><ul><li>then: </li></ul><ul><li>author. hasErrors () == ! valid </li></ul><ul><li>where: </li></ul><ul><li>lastname | valid </li></ul><ul><li>&quot;123456789012345678901&quot; | false </li></ul><ul><li>&quot;12345678901234567890&quot; | true </li></ul><ul><li>&quot;&quot; | false } </li></ul>
    48. 48. Grails Controller <ul><li>class AuthorController { </li></ul><ul><li>def index = { </li></ul><ul><li>redirect (action: &quot;list&quot; , params : params ) </li></ul><ul><li>} </li></ul><ul><li>def list = { </li></ul><ul><li>params . max = Math. min ( params . max ? params . int ( 'max' ) : 10 , 100 ) </li></ul><ul><li>[authorInstanceList: Author. list ( params ), authorInstanceTotal: Author. count ()] } </li></ul>
    49. 49. <ul><li>void testIndex() { </li></ul><ul><li>def controller = new AuthorController() </li></ul><ul><li>controller. index () </li></ul><ul><li>assertEquals &quot;list&quot; , controller. redirectArgs . action } </li></ul><ul><li>def 'index actio n' () { </li></ul><ul><li>when: </li></ul><ul><li>controller . index () </li></ul><ul><li>then: </li></ul><ul><li>redirectArgs . action == &quot;list&quot; } </li></ul>
    50. 50. <ul><li>void testList () { </li></ul><ul><li>def authorInstance = new Author ( firstname : &quot;John&quot; , lastname : &quot; Doe &quot; ) </li></ul><ul><li>mockDomain ( Author , [ authorInstance ]) </li></ul><ul><li>def controller = new AuthorController () </li></ul><ul><li>assert controller. list () == [ authorInstanceList : [ authorInstance ], authorInstanceTotal : 1 ] } </li></ul><ul><li>def ' list action: 1 autho r ' () { </li></ul><ul><li>setup: </li></ul><ul><li>mockDomain ( Author , [ authorInstance ]) </li></ul><ul><li>expect : </li></ul><ul><li>controller . list () == [ authorInstanceList : [ authorInstance ], authorInstanceTotal : 1 ] </li></ul><ul><li>where : </li></ul><ul><li>authorInstance = new Author ( firstname : &quot;John&quot; , lastname : &quot; Doe &quot; ) </li></ul>
    51. 51. Questions  ? Code Source sur : https://github.com/MathildeLemee/Spock-MixIt Et pour s’amuser en ligne : http://meetspock.appspot.com/

    ×