90

Unit Testing XQuery on MarkLogic

Embed Size (px)

DESCRIPTION

Unit testing is a required part of a healthy software development lifecycle. Business logic in MarkLogic Xquery needs the same insurance of superb testing as any other language. Principles: Come learn the motivation for unit testing and how test-driven development can increase your productivity writing solid Xquery code in an Agile-coding environment. Skills: We'll code Xquery examples to learn general skills including the TDD workflow, how to isolate your code for unit testability, and how to test one thing at a time. In each case, we'll address how to apply these skills specifically to development in the MarkLogic environment. Tools: We'll also introduce you to in-house-developed tooling for creating unit tests and running them. This tooling provides an all-Xquery method of creating test functions, annotating them as such so they're runnable in the test runner, isolating certain modules to test, and viewing clear test results. With a few principles, skills, and tools for unit testing, you can go forward with increased confidence that the Xquery code you write on MarkLogic is more awesome than ever. This slide deck is from a presentation at the MarkLogic Users Conference 2011. More info available at RockyCode.com

Citation preview

Page 1: Unit Testing XQuery on MarkLogic
Page 2: Unit Testing XQuery on MarkLogic
Page 3: Unit Testing XQuery on MarkLogic
Page 4: Unit Testing XQuery on MarkLogic
Page 5: Unit Testing XQuery on MarkLogic
Page 6: Unit Testing XQuery on MarkLogic
Page 7: Unit Testing XQuery on MarkLogic
Page 8: Unit Testing XQuery on MarkLogic
Page 9: Unit Testing XQuery on MarkLogic
Page 10: Unit Testing XQuery on MarkLogic
Page 11: Unit Testing XQuery on MarkLogic
Page 12: Unit Testing XQuery on MarkLogic
Page 13: Unit Testing XQuery on MarkLogic
Page 14: Unit Testing XQuery on MarkLogic
Page 15: Unit Testing XQuery on MarkLogic
Page 16: Unit Testing XQuery on MarkLogic
Page 17: Unit Testing XQuery on MarkLogic
Page 18: Unit Testing XQuery on MarkLogic
Page 19: Unit Testing XQuery on MarkLogic
Page 20: Unit Testing XQuery on MarkLogic
Page 21: Unit Testing XQuery on MarkLogic
Page 22: Unit Testing XQuery on MarkLogic
Page 23: Unit Testing XQuery on MarkLogic
Page 24: Unit Testing XQuery on MarkLogic
Page 25: Unit Testing XQuery on MarkLogic

declare function testFeature() {

let $actual := feature:doFeature()

(: assert feature condition :)

};

declare function doFeature() {

() (: todo: impl :)

};

Page 26: Unit Testing XQuery on MarkLogic

declare function doFeature() {

let $output := lotsOfLogic()

return $output

};

Page 27: Unit Testing XQuery on MarkLogic
Page 28: Unit Testing XQuery on MarkLogic
Page 29: Unit Testing XQuery on MarkLogic
Page 30: Unit Testing XQuery on MarkLogic
Page 31: Unit Testing XQuery on MarkLogic
Page 32: Unit Testing XQuery on MarkLogic
Page 33: Unit Testing XQuery on MarkLogic
Page 34: Unit Testing XQuery on MarkLogic
Page 35: Unit Testing XQuery on MarkLogic
Page 36: Unit Testing XQuery on MarkLogic

declare namespace its = “http://www.w3.org/2005/11/its”;

declare function buildXmlWithTranslateFlags() {

element data {

attribute its:translate {

“yes”

},

businessLogicToBuildXml();

}

};

Page 37: Unit Testing XQuery on MarkLogic

declare function buildXml() {

element data {

businessLogicToBuildXml();

}

};

declare namespace its = “http://www.w3.org/2005/11/its”;

declare function addTranslateFlags($xml) {

element {$xml/fn:name()} {

attribute its:translate {

“yes”

},

$xml/@*,

$xml/*

}

};

Page 38: Unit Testing XQuery on MarkLogic
Page 39: Unit Testing XQuery on MarkLogic

import module namespace build = “b” at “/build.xqy”;

declare function testBuildXml() {

let $actual := b:buildXml()

(: assert only xml is well-built :)

};

import module namespace translate = “t” at “/transl8.xqy”;

declare function testAddTranslateFlags() {

let $actual := t:addTranslateFlags()

(: assert only that translation flags added correctly :)

};

Page 40: Unit Testing XQuery on MarkLogic
Page 41: Unit Testing XQuery on MarkLogic

import module namespace build = “b” at “/build.xqy”;

declare function buildXml_condition1() {

(: ... :)

};

declare function buildXml_condition2() {

(: ... :)

};

(: etc. :)

Page 42: Unit Testing XQuery on MarkLogic
Page 43: Unit Testing XQuery on MarkLogic

declare function bizLogic($input as element()*) {

(: ... :)

};

import module namespace logic = “logic” at “/logic.xqy”;

declare function bizLogic_emptyInput() {

(: ... :)

};

declare function bizLogic_oneInput() {

(: ... :)

};

declare function bizLogic_manyInput() {

(: ... :)

};

Page 44: Unit Testing XQuery on MarkLogic
Page 45: Unit Testing XQuery on MarkLogic

declare function bizLogic($input as element()*) {

(: ... :)

};

import module namespace logic = “logic” at “/logic.xqy”;

declare function bizLogic_insufficientInput() {

(: ... :)

};

declare function bizLogic_malformedInput() {

(: ... :)

};

Page 46: Unit Testing XQuery on MarkLogic

declare function bizLogic($input as element()*) {

if (isInsufficientInput($input)) then

fn:error(xs:Qname(“ASSERT”), “Insufficient msg”)

else

(: normal process... :)

};

import module namespace logic = “logic” at “/logic.xqy”;

declare function bizLogic_insufficientInput() {

try {

(: call w/ insufficient input :)

} catch ($e) {

if ($e/error:name eq “ASSERT”) then

()

else

xdmp:rethrow()

}

};

Page 47: Unit Testing XQuery on MarkLogic

declare function businessLogic($input) {

let $moreInput := /more-input[@attr eq $input]

let $returnVal :=

for $item in $moreInput

let $details := /detail[@id eq $item/id]

return if ($details/thing eq

xdmp:get-request-field(“thing-id”)) then

$details

else ()

return if (fn:exists($returnVal)) then

let $audit :=

xdmp:document-insert(“/latest.xml”, element ok {})

return $returnVal

else

xdmp:redirect-response(“/empty.xqy”);

};

Page 48: Unit Testing XQuery on MarkLogic

declare function businessLogic($input) {

let $moreInput := /more-input[@attr eq $input]

let $returnVal :=

for $item in $moreInput

let $details := /detail[@id eq $item/id]

return if ($details/thing eq

xdmp:get-request-field(“thing-id”)) then

$details

else ()

return if (fn:exists($returnVal)) then

let $audit :=

xdmp:document-insert(“/latest.xml”, element ok {})

return $returnVal

else

xdmp:redirect-response(“/empty.xqy”);

};

Page 49: Unit Testing XQuery on MarkLogic
Page 50: Unit Testing XQuery on MarkLogic
Page 51: Unit Testing XQuery on MarkLogic
Page 52: Unit Testing XQuery on MarkLogic

xdmp:get-request-field(“var”)

xdmp:redirect-response(“/page.xqy”)

Page 53: Unit Testing XQuery on MarkLogic

xdmp:document-insert(“/trades.xml”, element beads {})

fn:collection()/dances/rain

Page 54: Unit Testing XQuery on MarkLogic
Page 55: Unit Testing XQuery on MarkLogic
Page 56: Unit Testing XQuery on MarkLogic
Page 57: Unit Testing XQuery on MarkLogic
Page 58: Unit Testing XQuery on MarkLogic

declare function feature() {

let $filter := xdmp:get-request-field(“filter”)

let $input := fn:collection()/data[@attr eq $filter]

let $result := businessLogic($input)

let $persist := xdmp:document-insert(“/doc.xml”, $result)

return xdmp:redirect-response(“complete.xqy”)

};

Page 59: Unit Testing XQuery on MarkLogic
Page 60: Unit Testing XQuery on MarkLogic
Page 61: Unit Testing XQuery on MarkLogic
Page 62: Unit Testing XQuery on MarkLogic
Page 63: Unit Testing XQuery on MarkLogic
Page 64: Unit Testing XQuery on MarkLogic

declare function feature() {

let $filter := xdmp:get-request-field(“filter”)

let $input := fn:collection()/data[@attr eq $filter]

let $result := businessLogic($input)

let $persist := xdmp:document-insert(“/doc.xml”, $result)

return xdmp:redirect-response(“complete.xqy”)

};

Page 65: Unit Testing XQuery on MarkLogic
Page 66: Unit Testing XQuery on MarkLogic
Page 67: Unit Testing XQuery on MarkLogic
Page 68: Unit Testing XQuery on MarkLogic
Page 69: Unit Testing XQuery on MarkLogic
Page 70: Unit Testing XQuery on MarkLogic

declare function (:TEST:) isolate_noUrlNoChannels()

{

(: ... :)

};

Page 71: Unit Testing XQuery on MarkLogic

<dependency>

<groupId>org.lds.marklogic.shared</groupId>

<artifactId>xqtest</artifactId>

<version>1.0-SNAPSHOT</version>

<type>xar</type>

</dependency>

Page 72: Unit Testing XQuery on MarkLogic

import module namespace unit =

"http://lds.org/code/shared/xqtest/html" at

"/shared/xqtest/html.xqy";

html:test()

Page 73: Unit Testing XQuery on MarkLogic
Page 74: Unit Testing XQuery on MarkLogic
Page 75: Unit Testing XQuery on MarkLogic

import module namespace unit =

"http://lds.org/code/shared/xqtest/testng" at

"/shared/xqtest/testng.xqy";

testng:test()

Page 76: Unit Testing XQuery on MarkLogic
Page 77: Unit Testing XQuery on MarkLogic
Page 78: Unit Testing XQuery on MarkLogic
Page 79: Unit Testing XQuery on MarkLogic

<channels>

<channel>

<name>Dress &amp; Grooming</name>

<path>/dress-grooming/</path>

<channels>

<!-- ... -->

<channels>

</channel>

<!-- ... -->

</channels>

Page 80: Unit Testing XQuery on MarkLogic
Page 81: Unit Testing XQuery on MarkLogic
Page 82: Unit Testing XQuery on MarkLogic

...

test - show only active subchannels - green

test - show only active subchannels - red

test - 1 child level all children - green

test - 1 child level, 2 exist - green

test - 1 child level, 2 exist - red

test - 1 child level - green

test - child level - red

test - get closest url - green

test - get closest url - red

test - match level 2 - green

test - match level 2 - red

test - active chg - match whole tree & match lvl1 partial tree - green

test - active chg - match whole tree & match lvl1 partial tree - red

test - match lvl1 partial tree - red

test - match whole tree - green

test - match whole tree – red

...

Page 83: Unit Testing XQuery on MarkLogic

Demo'able parameters

style adjustment

added stylesheet for sidebar

added demo page, adjusted reverse tree builder to handle queried docs

testng runner added

xqtest ver .5 - update to work with new api

test - limit shallow non-hierarchical url - green

test - shallow limit 1 level, 2 exist - green

test - adjust test (only work with hierarchical urls) - shallow …

test - shallow limit 1 level, 2 exist - red

test - deep limit 1 level, 2 exist - green

test - adjust test - deep limit 1 level, 2 exist - red

test - limit 1 level, 2 exist - red

test - level 3 active link - green

test - level 3 active link - red

test - level 3 list none active (and fixed level 2 test data) - green

test - level 3 list none active - red

cleanup - privatize fn's

test - level 2 list none active - green

test - level 2 list none active - red

test - header only multiple level 1 channel - green

test - header only multiple level 1 channel - red

test - header only - green

test - header only - red

test - no channels data - green

test - no channels data - red

test - no channels - green

added sidebar renderer - no channels test - red

renamed build->render fn

added build fn

test - build max child levels of set to more - green

test - no match 3 levels, 2 exist, 2 shown (fixed bug) - green

test - no match 3 levels, 2 exist, 2 shown - red

test - no match level 1, 2 exist - fix - green

test - no match level 1, 2 exist - green

test - no match levels more than exists - green

test - no match level 1 - green

test - no match level 1 - red

cleanup long fn signatures

test - show only active subchannels - green

test - show only active subchannels - red

test - 1 child level all children - green

test - 1 child level, 2 exist - green

test - 1 child level, 2 exist - red

test - 1 child level - green

test - child level - red

test - get closest url - green

test - get closest url - red

test - match level 2 - green

test - match level 2 - red

test - active chg - match whole tree & match lvl1 partial tree - green

test - active chg - match whole tree & match lvl1 partial tree - red

test - match lvl1 partial tree - red

test - match whole tree - green

test - match whole tree - red

Rename isolateChannels -> isolate

Rename nav -> channel

Rename nav2 -> nav

Added gitignore

Initial import - base test cases (no input)

Page 84: Unit Testing XQuery on MarkLogic

Demo'able parameters

style adjustment

added stylesheet for sidebar

added demo page, adjusted reverse tree builder to handle queried docs

testng runner added

xqtest ver .5 - update to work with new api

test - limit shallow non-hierarchical url - green

test - shallow limit 1 level, 2 exist - green

test - adjust test (only work with hierarchical urls) - shallow …

test - shallow limit 1 level, 2 exist - red

test - deep limit 1 level, 2 exist - green

test - adjust test - deep limit 1 level, 2 exist - red

test - limit 1 level, 2 exist - red

test - level 3 active link - green

test - level 3 active link - red

test - level 3 list none active (and fixed level 2 test data) - green

test - level 3 list none active - red

cleanup - privatize fn's

test - level 2 list none active - green

test - level 2 list none active - red

test - header only multiple level 1 channel - green

test - header only multiple level 1 channel - red

test - header only - green

test - header only - red

test - no channels data - green

test - no channels data - red

test - no channels - green

added sidebar renderer - no channels test - red

renamed build->render fn

added build fn

test - build max child levels of set to more - green

test - no match 3 levels, 2 exist, 2 shown (fixed bug) - green

test - no match 3 levels, 2 exist, 2 shown - red

test - no match level 1, 2 exist - fix - green

test - no match level 1, 2 exist - green

test - no match levels more than exists - green

test - no match level 1 - green

test - no match level 1 - red

cleanup long fn signatures

test - show only active subchannels - green

test - show only active subchannels - red

test - 1 child level all children - green

test - 1 child level, 2 exist - green

test - 1 child level, 2 exist - red

test - 1 child level - green

test - child level - red

test - get closest url - green

test - get closest url - red

test - match level 2 - green

test - match level 2 - red

test - active chg - match whole tree & match lvl1 partial tree - green

test - active chg - match whole tree & match lvl1 partial tree - red

test - match lvl1 partial tree - red

test - match whole tree - green

test - match whole tree - red

Rename isolateChannels -> isolate

Rename nav -> channel

Rename nav2 -> nav

Added gitignore

Initial import - base test cases (no input)

Page 85: Unit Testing XQuery on MarkLogic
Page 86: Unit Testing XQuery on MarkLogic
Page 87: Unit Testing XQuery on MarkLogic
Page 88: Unit Testing XQuery on MarkLogic
Page 89: Unit Testing XQuery on MarkLogic

Green Apple (modified) http://www.flickr.com/photos/_fxr/2335186114/ _FXR's photostream Salt Lake Temple http://www.flickr.com/photos/midiman/2503776540/ midiman's photostream Belay http://www.flickr.com/photos/picsbycam/5173647461/ Cameron Cassan's photostream Thinker http://www.flickr.com/photos/garysoup/2705102139/ Gary Soup's photostream Multipurpose Tool http://www.flickr.com/photos/paalb/11772559/ Pål Berge's photostream Clean Up http://www.flickr.com/photos/emilyrides/5188289325/lightbox/ emilydickinsonridesabmx's photostream Cliff http://www.flickr.com/photos/elsie/144702426/ Elsie esq.'s photostream Paper Pile http://www.flickr.com/photos/loty/326761635/ lotyloty's photostream Candles http://www.flickr.com/photos/picsbycam/4023646774/in/photostream/ Cameron Cassan's photostream Elephant http://www.flickr.com/photos/greenboots76/2924276160/ Henry Brett's photostream Assembly Line http://www.flickr.com/photos/jurvetson/5201796697/ jurvetson's photostream Chihuahua http://www.flickr.com/photos/62337512@N00/3727104807/ apdk's photostream Angry Dog http://www.flickr.com/photos/javiercito/2083111412/lightbox/ Javiercit0's photostream Clean up Pet http://www.flickr.com/photos/pointshoot/1144799868/ Eddie~S' photostream

Hugging Fingers http://www.flickr.com/photos/ganesha_isis/4439563089/ ganesha.isis' photostream Fail Whale http://www.flickr.com/photos/coletivomambembe/3882172324/ Coletivo Mambembe's photostream Lego Death Star http://www.flickr.com/photos/dudeoflego/5104751355/ Dude of Lego's photostream Road Runner http://www.flickr.com/photos/snowpeak/4815685925/ snowpeak's photostream Keyboard Sleep http://www.flickr.com/photos/ytruly/1718468702/ YTruly's photostream Lotus http://www.flickr.com/photos/thecarspy/2571799871/in/photostream/ The Car Spy's photostream Neon Pipes http://www.flickr.com/photos/krossbow/3619931451/ krossbow's photostream - CC Attribution license Calculator http://www.flickr.com/photos/scoobay/2463236523/ Scoobay's photostream Dragon Boat http://www.flickr.com/photos/wiifm69/3410782558/ wiifm's photostream Ping Pong http://www.flickr.com/photos/ncc_badiey/4932760753/ Nima Badiey's photostream Solitary Confinement http://www.flickr.com/photos/59195512@N00/143521274/ dospaz's photostream Flags http://www.flickr.com/photos/markchapmanphoto/5138832677/ ::: Radar Communication :::'s photostream Pointing Caterpillar http://www.flickr.com/photos/pinkstockphotos/5266977224/ PinkStock Photos!'s photostream Multiplication http://www.flickr.com/photos/somegeekintn/4048155967/ somegeekintn's photostream

A l l C r e a t i v e C o m m o n s 2 . 0 A t t r i b u t i o n L i c e n s e u n l e s s o t h e r w i s e n o t e d

Decoupled http://www.flickr.com/photos/daquellamanera/2213902727/ Daquella manera's photostream Water Droplet http://www.flickr.com/photos/shannonkringen/4680455907/ shannonkringen's photostream

Page 90: Unit Testing XQuery on MarkLogic

Pig Egg http://www.flickr.com/photos/katerha/5423107783/ katerha's photostream Spaghetti Noodle http://www.flickr.com/photos/pinksherbet/2201247567/ Pink Sherbet Photography's photostream Girl Eating Spaghetti http://www.flickr.com/photos/pinksherbet/5008273559/ Pink Sherbet Photography's photostream Salute Flag http://www.flickr.com/photos/soldiersmediacenter/3920702814/ The U.S. Army's photostream Camoflauge Lizard http://www.flickr.com/photos/lofink/4453281926/ dlofink's photostream Call on Beach http://www.flickr.com/photos/zitona/2268296925/ » Zitona «'s photostream Indian Chief http://www.flickr.com/photos/boston_public_library/4100786887/in/photostream/ Boston Public Library's photostream Ninja Turtle http://www.flickr.com/photos/86805724@N00/1581833575/ ianmalcm's photostream Phone Booth http://www.flickr.com/photos/bexwalton/4204409348/ Bex.Walton's photostream Suit http://www.flickr.com/photos/pss/4830803189/ Paul Stevenson's photostream Underwater http://www.flickr.com/photos/andreweick/4000567498/in/photostream/ AndrewEick's photostream Picasso http://www.flickr.com/photos/oddsock/101164507/ oddsock's photostream Spider Tunnel http://www.flickr.com/photos/b1gw1ght/900924265/ b1gw1ght's photostream

Safety Net http://www.flickr.com/photos/iamchadhearmesnore/3629410556/ iamchad's photostream Black Box http://www.flickr.com/photos/amagill/34762677/ AMagill's photostream Tool Belt http://www.flickr.com/photos/blue_diamond/3995257652/ Blue Diamond Photography's photostream The Swede By David Quinn, used with permission Garden Gnome http://www.flickr.com/photos/mukluk/196177233/ Dano's photostream Blueprint http://www.flickr.com/photos/wscullin/3770016707/ Will Scullin's photostream Flux Capacitor http://www.flickr.com/photos/popculturegeek/4533455371/ popculturegeek.com's photostream Power Plug http://www.flickr.com/photos/randomurl/438112948/ Zevotron's photostream Runner http://www.flickr.com/photos/lululemonathletica/5197327623/lightbox/ lululemon athletica's photostream Yoga Man http://www.flickr.com/photos/lululemonathletica/4774517755/ lululemon athletica's photostream Lego City Men http://www.flickr.com/photos/mac_filko/5491561002/ mac_filko's photostream Port Said http://www.flickr.com/photos/48722974@N07/5036484008/ eutrophication&hypoxia's photostream Vote for Pedro http://www.flickr.com/photos/emdot/79863648/ emdot's photostream Dusty Road http://www.flickr.com/photos/generated/5554654197/ jared's photostream

Mexican Hat Rock Formation http://www.flickr.com/photos/wolfgangstaudt/4879456199/in/set-72157624891093384 Wolfgang Staudt's photostream Red Apple (modified) http://www.flickr.com/photos/emzee/273289101/ *Micky's photostream Kodak Roll http://www.flickr.com/photos/picsbycam/4550970565/in/photostream/ Cameron Cassan's photostream Gnuolane Free font http://typodermicfonts.com Free for personal and commercial use