Upload
jake-trent
View
1.217
Download
0
Tags:
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
declare function testFeature() {
let $actual := feature:doFeature()
(: assert feature condition :)
};
declare function doFeature() {
() (: todo: impl :)
};
declare function doFeature() {
let $output := lotsOfLogic()
return $output
};
declare namespace its = “http://www.w3.org/2005/11/its”;
declare function buildXmlWithTranslateFlags() {
element data {
attribute its:translate {
“yes”
},
businessLogicToBuildXml();
}
};
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/*
}
};
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 :)
};
import module namespace build = “b” at “/build.xqy”;
declare function buildXml_condition1() {
(: ... :)
};
declare function buildXml_condition2() {
(: ... :)
};
(: etc. :)
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() {
(: ... :)
};
declare function bizLogic($input as element()*) {
(: ... :)
};
import module namespace logic = “logic” at “/logic.xqy”;
declare function bizLogic_insufficientInput() {
(: ... :)
};
declare function bizLogic_malformedInput() {
(: ... :)
};
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()
}
};
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”);
};
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”);
};
xdmp:get-request-field(“var”)
xdmp:redirect-response(“/page.xqy”)
xdmp:document-insert(“/trades.xml”, element beads {})
fn:collection()/dances/rain
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”)
};
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”)
};
declare function (:TEST:) isolate_noUrlNoChannels()
{
(: ... :)
};
<dependency>
<groupId>org.lds.marklogic.shared</groupId>
<artifactId>xqtest</artifactId>
<version>1.0-SNAPSHOT</version>
<type>xar</type>
</dependency>
import module namespace unit =
"http://lds.org/code/shared/xqtest/html" at
"/shared/xqtest/html.xqy";
html:test()
import module namespace unit =
"http://lds.org/code/shared/xqtest/testng" at
"/shared/xqtest/testng.xqy";
testng:test()
<channels>
<channel>
<name>Dress & Grooming</name>
<path>/dress-grooming/</path>
<channels>
<!-- ... -->
<channels>
</channel>
<!-- ... -->
</channels>
...
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
...
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)
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)
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
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