D o m a i n - S p e c i f i c T e s t i n g T - - PowerPoint PPT Presentation

d o m a i n s p e c i f i c t e s t i n g t o o l s l e s
SMART_READER_LITE
LIVE PREVIEW

D o m a i n - S p e c i f i c T e s t i n g T - - PowerPoint PPT Presentation

D o ma i n - S p e c i f i c T e s t i n g T o o l s D o m a i n - S p e c i f i c T e s t i n g T o o l s L e s s o n s l e a r n e d f r o m t h e A p a c h e S l i


slide-1
SLIDE 1

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

D

  • ma

i n

  • S

p e c i f i c T e s t i n g T

  • l

s

D

  • m

a i n

  • S

p e c i f i c T e s t i n g T

  • l

s L e s s

  • n

s l e a r n e d f r

  • m

t h e A p a c h e S l i n g P r

  • j

e c t R

  • b

e r t M u n t e a n u A p a c h e C

  • n

C

  • r

e E u r

  • p

e 2 1 5

slide-2
SLIDE 2

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

W h

  • I

a m

 $

D A Y J O B

 A

d

  • b

e E x p e r i e n c e M a n a g e r

 A

p a c h e S l i n g

 A

p a c h e J a c k r a b b i t

 A

p a c h e F e l i x

 F

O S S

 A

p a c h e S l i n g

 M

a n t i s B T

 M

y l y n C

  • n

n e c t

  • r

f

  • r

M a n t i s B T

 M

y l y n C

  • n

n e c t

  • r

f

  • r

R e v i e w B

  • a

r d

Speaker.currentSpeaker().interrupt();

slide-3
SLIDE 3

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

A g e n d a

 T

e s t i n g t

  • l

s i n g e n e r a l

 B

u i l d i n g d

  • m

a i n

  • s

p e c i f i c t e s t i n g t

  • l

s

 D

  • m

a i n

  • s

p e c i f i c

  • t
  • l

s b u i l t b y A p a c h e S l i n g

slide-4
SLIDE 4

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

H

  • w

d

  • I

t e s t my a p p l i c a t i

  • n

?

Testing and testing tools

slide-5
SLIDE 5

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g @Test public void isNull() { assertThat( StringUtils.isNull( null ), is(true)); }

slide-6
SLIDE 6

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g w i t h mo c k s @Test public void persist() { MyDao dao = mock(MyDao.class); MyService service = new MyService(dao); service.persist(new ServiceObject()); // must not fail }

slide-7
SLIDE 7

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g w i t h mo c k s @Test(expected=ServiceException.class) public void persist() { MyDao dao = mock(MyDao.class); MyService service = new MyService(dao); when(dao.persist(anyObject)).thenThrow(new DaoUnavailableException("mocked")); service.persist(new ServiceObject()); }

slide-8
SLIDE 8

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

I n t e g r a t i

  • n

t e s t i n g @Test public void persist() { MyDao dao = new MyRealDao(/* config */); MyService service = new MyService(dao); service.persist(newServiceObject()); // must not fail }

slide-9
SLIDE 9

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

I n t e g r a t i

  • n

t e s t i n g

  • c

l e a n s l a t e @Before public void ensureCleanSlate() { MyDao dao = new MyRealDao(/* config */); dao.deleteAll(); }

slide-10
SLIDE 10

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

E n d

  • t
  • e

n d t e s t i n g @Test public void login() { Client client = new MyBrowserBasedClient(); AuthResult result = client.login("admin", "admin"); assertThat(result.isLoggedIn(), is(true)); }

slide-11
SLIDE 11

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

T e s t i n g p y r a mi d

slide-12
SLIDE 12

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

T e s t i n g p y r a mi d

slide-13
SLIDE 13

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

Opinionated testing tools?

slide-14
SLIDE 14

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

T e s t i n g t

  • l

s g a l

  • r

e

slide-15
SLIDE 15

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

Sling's Domain

slide-16
SLIDE 16

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

O S G i

  • P

r

  • v

i s i

  • n

a n d d e p l

  • y

b u n d l e s

  • C
  • n

f i g u r e , r e g i s t e r a n d l

  • k

u p s e r v i c e s

  • E

v e n t i n g

  • W

e b C

  • n

s

  • l

e

slide-17
SLIDE 17

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g O S G i w i t h S l i n g M

  • c

k s

public class ExampleTest { @Rule public final OsgiContext context = new OsgiContext(); @Test public void testSomething() { // register and activate service MyService service1 = context.registerInjectActivateService(new MyService(), ImmutableMap.<String, Object>of("prop1", "value1")); // get service instance OtherService service2 = context.getService(OtherService.class); } }

slide-18
SLIDE 18

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g O S G i w i t h t h e H u mb l e O b j e c t P a t t e r n

public interface RouterAdmin { void doStuff(); } public class RouterAdminImpl implements RouterAdmin { // constructor and field elided public void doStuff() { // implementation } } @Component @Properties({ @Property(name="url") }) public class RouterAdminComponent implements RouterAdmin { private RouterAdmin delegate; protected void activate(ComponentContext ctx) throws Exception { delegate = new RouterAdminImpl(new URL(requireString(ctx, "url"))); } public void doStuff() { delegate.doStuff(); } }

slide-19
SLIDE 19

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

I n t e g r a t i

  • n

t e s t i n g O S G i w i t h P a x

  • E

x a m

public static Option[] paxConfig() { final File thisProjectsBundle = new File(System.getProperty( "bundle.file.name", "BUNDLE_FILE_NOT_SET" )); final String launchpadVersion = System.getProperty("sling.launchpad.version", "LAUNCHPAD_VERSION_NOT_SET"); log.info("Sling launchpad version: {}", launchpadVersion); return new DefaultCompositeOption( SlingPaxOptions.defaultLaunchpadOptions(launchpadVersion), CoreOptions.provision(CoreOptions.bundle(thisProjectsBundle.toU RI().toString())) ).getOptions(); }

slide-20
SLIDE 20

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

I n t e g r a t i

  • n

t e s t i n g O S G i w i t h P a x

  • E

x a m

@RunWith(PaxExam.class) public class FileNameExtractorImplIT { @Inject private FileNameExtractor fileNameExtractor; @Test public void testFileNameExtractor(){ String rawPath = "http://midches.com/images/uploads/default/demo.jpg#anchor? query=test"; String expectedFileName = "demo.jpg"; assertEquals(expectedFileName, fileNameExtractor.extract(rawPath)); } @Configuration public Option[] config() { return U.paxConfig(); } }

slide-21
SLIDE 21

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

J C R

slide-22
SLIDE 22

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

J C R

blog hello-world images jcr:content some-cat.jpg

  • ther-cat.jpg
slide-23
SLIDE 23

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

J C R

  • jcr:primaryType = app:asset
  • jcr:title = Some Cat
  • jcr:description = A longer description of this picture
  • f a cat
  • jcr:created = 2014-06-03T00:00:00.000+02:00
  • jcr:lastUpdated = 2014-06-03T11:00:00.000+02:00
  • tags = [Animal, Cat, Color]
  • width = 400
  • height = 600
slide-24
SLIDE 24

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

U n i t t e s t i n g J C R c

  • d

e

public class FindResourcesTest { @Rule public SlingContext context = new SlingContext(ResourceResolverType.JCR_MOCK); @Before public void setUp() { Resource resource = context.create().resource("test", ImmutableMap.<String, Object> builder().put("prop1", "value1") .put("prop2", "value2").build()); // snip ... MockJcr.setQueryResult(session, Collections.singletonList(node)); } @Test public void testFindResources() { Resource resource = context.resourceResolver().getResource("/test"); Assert.assertNotNull("Resource with name 'test' should be there", resource); Iterator<Resource> result = context.resourceResolver().findResources("/test", Query.XPATH); Assert.assertTrue("At least one result expected", result.hasNext()); Assert.assertEquals("/test", result.next().getPath()); Assert.assertFalse("At most one result expected", result.hasNext()); } }

slide-25
SLIDE 25

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

B e t t e r u n i t t e s t i n g w i t h H a mc r e s t ma t c h e r s

@Test public void loadResources() { Map<String, Object> expectedProperties = /* define properties */; Resource resource = /* load resource */ null; assertThat(resource, resourceOfType("my/app")); assertThat(resource, hasChildren("header", "body")); assertThat(resource, resourceWithProps(expectedProperties)); }

slide-26
SLIDE 26

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

I n t e g r a t i

  • n

t e s t i n g J C R c

  • d

e

  • Unit testing with JCR Mocks
  • JCR_MOCK
  • SLING_MOCK
  • Integration testing with JCR Mocks
  • JCR_JACKRABBIT
  • JCR_OAK
slide-27
SLIDE 27

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

S e r v e r

  • s

i d e t e s t i n g

public class ServerSideInstallerTest { @Rule public final TeleporterRule teleporter = TeleporterRule.forClass(getClass(), "Launchpad"); @Before public void setup() throws LoginException { ip = teleporter.getService(InfoProvider.class); is = ip.getInstallationState(); } @Test public void noUntransformedResources() { final List<?> utr = is.getUntransformedResources(); if(utr.size() > 0) { fail("Untransformed resources found: " + utr); } } }

slide-28
SLIDE 28

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

S c r i p t a b l e S e r v e r

  • s

i d e t e s t i n g

// test imports that fail on Java 8, SLING-3405 %><%@page import="java.util.Arrays"%><% %><%@page import="java.lang.CharSequence"%><% %>TEST_PASSED

slide-29
SLIDE 29

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

S l i n g t e s t i n g t

  • l

s c r

  • s

s

  • r

e f e r e n c e OSGi JCR Sling Unit Testing

Sling (OSGi) mocks Hamcrest Matchers Sling (JCR) Mocks Hamcrest Matchers Sling Mocks Hamcrest Matchers

Integration testing

Pax-Exam || Humble Object || Server-Side tests

End-To-End testing

Sling HTTP Testing Tools

slide-30
SLIDE 30

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

F i n a l t h

  • u

g h t s

  • Identify what is particular to your

application/product

  • Try to be testing tool agnostic
  • Recognise that difgerent organisations test in

difgerent ways

slide-31
SLIDE 31

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

R e s

  • u

r c e s

  • http://sling.apache.org
  • https://sling.apache.org/documentation/develop

ment/sling-mock.html

  • http://jackrabbit.apache.org/
slide-32
SLIDE 32

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

C

  • l
  • p

h

  • n

Images

  • Tools IMG_0171 by OzinOH on Flickr
  • One Way Una Via by David Amsler on Flickr
  • Slingshots by by Anne and Tim on Flickr

World cloud generated with https://www.jasondavies.com/wordcloud/

slide-33
SLIDE 33

h t t p : / / r

  • b

e r t . mu n t e a . n u @r

  • mb

e r t

Q & A