Upgrade to Pro — share decks privately, control downloads, hide ads and more …

33rd Degree - recap

33rd Degree - recap

Nedeljko Damnjanovic

April 18, 2015
Tweet

More Decks by Nedeljko Damnjanovic

Other Decks in Programming

Transcript

  1. Why test? • system works as expected • changes do

    not hurt • documentation What happens if we do it wrong? • Angry clients • Depressed developers
  2. No Assertions • Test should never require us to do

    any kind of manual verification Bad IResult result = format.execute(); System.out.println(result.size()); Iterator iter = result.iterator(); while (iter.hasNext()) { IResult r = (IResult) iter.next(); System.out.println(r. getMessage()); } Good IResult result = format.execute(); assertThat(result.size()).isEqualTo (3); Iterator iter = result.iterator(); while (iter.hasNext()) { IResult r = (IResult) iter.next(); assertThat(r.getMessage()). contains("error"); }
  3. TestCare • writing tests makes sense only if you (and

    your team) take care about them every day Bad class SystemAdminSmokeTest extends GroovyTestCase { void testSmoke() { // do not remove below code // def ds = new org.h2.jdbcx.JdbcDataSource( // URL: 'jdbc:h2:mem:test;DB_CLOSE_DELAY=-1; MODE=Oracle', // user: 'sa', password: '') // // def jpaProperties = new Properties() // jpaProperties.setProperty( // 'hibernate.cache.use_second_level_cache', 'false') // jpaProperties.setProperty( // ) ... } • Good intentions are not enough • Writing and maintaining tests is an effort which has to be taken by the whole team
  4. • Independency ◦ keep tests independent from each other (or

    make dependency explicit) ◦ do not modify global state (system properties, file system...) • Single Responsibility Principle ◦ Each test method should verify one scenario ▪ test should have one and only one reason to fail ◦ Why? ◦ such test methods are pretty simple to understand, ◦ if they fail you know *exactly* which functionality
  5. • Single Responsibility Principle • using “And” • one feature

    at a time forget about methods! TIP: Watch the method names. Are they intention- revealing? TIP: No logic in tests! Even the simplest one is evil! BAD GOOD • abstract from implementation
  6. • use the real object obscures test Bad • real

    objects which are irrelevant to the tested scenario • distracts the reader from the testing scenario Tip: • Creating objects only to create other objects so you can create other objects? Do not do that!
  7. • database assumptions Bad @Test public void shouldAddAUser() { User

    user = new User(); userService.save(user); assertEquals(dao.getNbOfUsers(), 1); } 1. it does not really verify if the user was added, 2. it makes some assumptions regarding the state of the database before it is executed Good @Test public void shouldAddAUser() { int nb = dao.getNbOfUsers(); User user = new User(); userService.save(user); assertEquals(dao.getNbOfUsers(), nb + 1); } • Do not make assumptions about the database content. • Use relative rather than absolute values
  8. Bad @DataProvider public static Object[][] usersPermissions() { return new Object[][]{

    {"user_1", Permission.READ}, {"user_1", Permission.WRITE}, {"user_1", Permission.REMOVE}, {"user_2", Permission.WRITE}, {"user_2", Permission.READ}, {"user_3", Permission.READ} }; } Good @DataProvider public static Object[][] userPermissions() { return new Object[][]{ {"guest", READ}, {"logged", READ}, {"logged", WRITE}, {"admin", READ}, {"admin", WRITE}, {"admin", DELETE} }; } • readability is the king
  9. • Do not make me learn the API! Bad server

    = new MockServer(responseMap, true, new URL(SERVER_ROOT).getPort(), false); Good • private static final boolean RESPONSE_IS_A_FILE = true; private static final boolean NO_SSL = false; server = new MockServer(responseMap, RESPONSE_IS_A_FILE, new URL(SERVER_ROOT).getPort(), NO_SSL); • server = createFileNonSSLMockServer(responseMap);
  10. • Test methods names are important ◦ When test fails

    ◦ Relation to focused tests • “should” is better than “test” ◦ Start with "should". Think about scenario Starting test method names with “should” steers you in the right direction. “test” prefix makes your test method a limitless bag where you throw everything worth testing
  11. Tips • do it everyday or forget about it •

    use the right tool for the job and learn to use it! • do not live with broken windows • keep it simple • write good code, and you will also write good tests • or rather write good tests and you will get good code for free • code review your tests • do more than happy path testing • do not make the reader learn the API, make it obvious • bad names lead to bad tests • make tests readable using matchers, builders and good names • test behaviour not methods • automate! • always concentrate on what is worth testing • use the front door – state testing before interaction testing (mocks)