solutions for when documentation fails
Post on 22-Jan-2018
314 Views
Preview:
TRANSCRIPT
SOLUTIONS FOR WHEN DOCUMENTATION
AVOIDANCE
MARTIJN DASHORST TOPICUS
FAILS
MARTIJN DASHORSTTOPICUSPARNASSYS, SOMTODAY, EDUARTE, ZIEN!VO, IRIS+, TEACHER, CONFERENCE ORGANIZER ENGINEERJAVA, DOCKER, ECLIPSE, MAVEN, WICKET HOBBIESLEGO, STAR TREK, STAR WARS, PODCASTS@DASHORST
LET'S DISCUSS THE RELATIONSHIP
BETWEEN DEVELOPERS AND DOCUMENTATION
WHO USES DOCUMENTATION?✋
CHALLENGES AT WORK
STACKOVERFLOW DEVELOPER SURVEY 2016
CHALLENGES AT WORK
TRYING TO BE NICE 8%
12% STACKOVERFLOW DEVELOPER SURVEY
2016
CHALLENGES AT WORK
TRYING TO BE NICE
POOR INFRASTRUCTURE
8%
12% STACKOVERFLOW DEVELOPER SURVEY
2016
STACKOVERFLOW DEVELOPER SURVEY
2016
CHALLENGES AT WORK
TRYING TO BE NICE
POOR INFRASTRUCTURE
UNSPECIFIC SPECIFICATIONS
: : : : : : : : : : :
: : : : : : : : : : :
8%
12%
34%
35%
35%
STACKOVERFLOW DEVELOPER SURVEY
2016
CHALLENGES AT WORK
TRYING TO BE NICE
POOR INFRASTRUCTURE
UNSPECIFIC SPECIFICATIONS
: : : : : : : : : : :
POOR DOCUMENTATION
UNREALISIC EXPECTATIONS
: : : : : : : : : : :
8%
12%
34%
35%
35%
IMPORTANT FACTORS IN APIs
PROGRAMMABLE WEBSURVEY
2013
PRICE
: : : : : : : : : : :
IMPORTANT FACTORS IN APIs
PROGRAMMABLE WEBSURVEY
2013
SERVICE RESPONSIVENESS/PERFORMANCE
SERVICE AVAILABLITY/UPTIME
: : : : : : : : : : :
PRICE
: : : : : : : : : : :
IMPORTANT FACTORS IN APIs
PROGRAMMABLE WEBSURVEY
2013
SERVICE RESPONSIVENESS/PERFORMANCE
SERVICE AVAILABLITY/UPTIME
COMPLETE AND ACCURATE DOCUMENTATION
: : : : : : : : : : :
PRICE
: : : : : : : : : : :
WHO WRITES DOCUMENTATION?✋
WHO ENJOYS IT?✋
IT'S COMPLICATED
The lack of documentationcan lead to meetings – Peter Hilton
JFALL 2016
LEAVE YOUR PHONE# IN EVERY SOURCE FILE
JUST-IN-TIME DOCUMENTATION
WRITE GREAT CODE, COMMENT IT
WRITE JUST ENOUGH DOCS, BUT NOT MORE
CASES WHEN DOCUMENTATION AVOIDANCE FAILS
user manualapi guideonboarding guidecode commentsdesign docs...
everywhere a user meets developmentYOU NEED DOCUMENTATION
everywhere a user meets developmentYOU NEED DOCUMENTATION
a new team member is a userALSO,
OPTIONS FOR WRITING
DOCUMENTATION
CODE
good naminggood structurecommentsjavadocis documentation
up-to-date
CODEas documentation fails when > 30k
good naminggood structurecommentsjavadocup-to-date
JAVADOC
good for APIsuse overview.htmluse package.htmlno stupid javadocup-to-date
*drivegoogle microsoft icloud sharepoint "f-share"
WIKIsnobody got fired for buying atlassian
WIKIs are where documentation goes to die – Joseph Wilk
CODE and JAVADOC
mostly up-to-date
CODE and
JAVADOC and DOCS
up-to-date?
WHAT IF WE COULD USE DEV TOOLS FOR
DOCUMENTATION?
gitmavenjenkinsdocker
1. docs → git 2. docs → build tools 3. docs → deployment tools
GIT ❤ TEXT FILES
PLAIN TEXT OPTIONSmarkdown
docbook
asciidoctorDITAA HTML
PLAIN TEXT OPTIONSmarkdown
docbook
asciidoctorDITAA HTML##
#
MARKDOWN+ light weight + easy to write + easy to read - limited
AFirstLevelHeader====================
ASecondLevelHeader---------------------
Nowisthetimeforallgoodmentocometotheaidoftheircountry.Thisisjustaregularparagraph.
Thequickbrownfoxjumpedoverthelazydog'sback.
###Header3
>Thisisablockquote.>>Thisisthesecondparagraphintheblockquote.>>##ThisisanH2inablockquote
FIRST THERE WAS MARKDOWNMarkdown (John Gruber)
http://daringfireball.net/projects/markdown
THEN THERE WAS MARKDOWNMarkdown Github Flavored Markdown Extra MultiMarkdown
(John Gruber)
THEN THERE WAS MARKDOWNMarkdown Github Flavored Markdown Extra MultiMarkdown CommonMark https://xkcd.com/927/
ASCIIDOCTOR+ medium weight + easy to write + easy to read + comprehensive + maven support + 1 version
#AFirstLevelHeader
##ASecondLevelHeader
Nowisthetimeforallgoodmentocometotheaidoftheircountry.Thisisjustaregularparagraph.
Thequickbrownfoxjumpedoverthelazydog'sback.
###Header3
>Thisisablockquote.>>Thisisthesecondparagraphintheblockquote.>>##ThisisanH2inablockquote
ASCIIDOCTOR+ Table of contents + Output to epub, pdf, html, docbook + Bibliography + Footnotes + Macros+ Substitutions
ASCIIDOCTOR+ file inclusions:
[source,java]----include::org/asciidoctor/Asciidoctor.java[lines=5..10]----
ASCIIDOCTOR+ code callouts
[source,xml]----include::pom.xml----<1>AddsArquillianCube<2>Fromthepointofview
PLAIN TEXT CHOICES
markdown asciidoctorREADME:1 EVERYTHING ELSE:
1 github does support README.adoc using asciidoctor format
1. docs → git 2. docs → build tools 3. docs → deployment tools
maven
maven+
guide.html
guide.pdf
=
1. docs → git 2. docs → build tools 3. docs → deployment tools
guide.pdf +guide.html
=+ maven
mavendockerhttpd
profit
result
WHAT IF WE COULD USE DEV TOOLS FOR A
USER MANUAL?
text and screenshotsUSER MANUAL:
text and screenshotsUSER MANUAL:
screenshots considered harmful
I have made this longer than usual because I have not had time to make it shorter.
I have made this longer than usual because I have not had time to make it shorter.
screenshots are always out-of-date
Windows™ 10 Admin Guide
1. Logging inAn administrator is someone who can make changes on a computer that will affect other users of the computer. Administrators can change security settings, install software and hardware, access all files on the computer, and make changes to other user accounts. To log on as an administrator, you need to have a user account on the computer with an Administrator account type.
If your account type is not Administrator, then you cannot log on as an administrator unless you know the user name password for another
«intentionally left blank for dramatic purposes»
UP-TO-DATE USER MANUAL
CASE STUDY
Identity & access management - 2FA for critical infrastructure - Localized authorization - 4 eyes principle - Installs as software appliance - Web App - Native mobile apps
vaults for secure team shares4 eyes principle
85 PAGES88 IMAGES
USER MANUAL
the 85 pages are written in asciidoc, converted using asciidoctor(all text is written by a human)
the 88 screenshots are captured during testing, achieving 90% code coverage
100%automated
arquillianmaven
mavenaShotgraphene
TOOLS USED FOR DOCUMENTATION
arquillianmaven
mavenaShotgraphene
a functional, integration and acceptance test platform
http://arquillian.org/
modules
a functional, integration and acceptance test platform
http://arquillian.org/
deploymentcontainers packaging injection
webdriver
http://arquillian.org/
integrationrecording
wildfly cube
tomcat
etcglassfish
Captures screenshot on test failure with Arquillian Recorder
http://arquillian.org/recording
Skips a testif the issue is not done.
Runs a testif the issue is done.
Closes a issue if the test is successful
http://arquillian.org/integration
@Test@Jira("ARQ-1907")publicvoidtest1(){}
@Test@Github("123")publicvoidtest2(){}
@RunWith(Arquillian.class) public class LoginTest { @Drone private WebDriver browser;
@Test public void step1LogIn() { } }
Anatomy of a test case1
3
2
@RunWith(Arquillian.class) public class LoginTest { @Drone private WebDriver browser;
@Test public void step1LogIn() { } }
Anatomy of a test case1
3
2
@RunWith(Arquillian.class) public class LoginTest { @Drone private WebDriver browser;
@Test public void step1LogIn() { } }
Anatomy of a test case1
3
2
@Test public void login() { browser .navigate() .to("https://test.com/login");
browser .findElement(By.name("username")) .sendKeys("bertjan");
Implement test case1
3
2
4
5
@Test public void login() { browser .navigate() .to("https://test.com/login");
browser .findElement(By.name("username")) .sendKeys("bertjan");
Implement test case1
3
2
4
5
browser .findElement(By.name("username")) .sendKeys("bertjan");
browser .findElement(By.name("password")) .sendKeys("schrijver");
Implement test case1
3
2
4
5
browser .findElement(By.name("password")) .sendKeys("schrijver");
browser .findElement(By.id("login")) .click();
Implement test case1
3
2
4
5
browser .findElement(By.id("login")) .click();
Assert.assertEquals("home", browser .findElement(By.tagName("title")) .text()); }
Implement test case1
3
2
4
5
arquillianmaven
mavenaShotgraphene
a wrapper for Selenium/WebDriver
graphenehttp://arquillian.org/arquillian-graphene/
Page Objects encapsulate requests and HTML
https://martinfowler.com/bliki/PageObject.html
browser .navigate() .to("https://test.com/login");
Using Page Objects
browser .navigate() .to("https://test.com/login");
Using Page Objects
LoginPage loginPage = Graphene.goTo(LoginPage.class);
browser .findElement(By.name("username")) .sendKeys("bertjan"); browser .findElement(By.name("password")) .sendKeys("schrijver"); browser.findElement(By.id("login")).click();
Using Page Objects
browser .findElement(By.name("username")) .sendKeys("bertjan"); browser .findElement(By.name("password")) .sendKeys("schrijver"); browser.findElement(By.id("login")).click();
loginPage.login("bertjan", "schrijver");
Using Page Objects
WEBDRIVER@Test public void login() { browser .navigate() .to("https://test.com/login"); browser .findElement(By.name("username") .sendKeys("bertjan"); browser .findElement(By.name("password") .sendKeys("schrijver"); browser .findElement(By.id("login")) .click(); }
@Test public void login() { LoginPage loginPage = Graphene.goTo(LoginPage.class); loginPage .login("bertjan", "schrijver"); }
GRAPHENE
arquillianmaven
mavenaShotgraphene
WebDriver Screenshot utility. Take screenshots, crop, prettify, compare.
aShothttps://github.com/yandex-qatools/ashot
take full screenshots
\
aShothttps://github.com/yandex-qatools/ashot
Screenshot screenshot = new AShot().takeScreenshot(browser);
Path targetFile = Paths.get( "target/screenshots", name + ".png");
ImageIO.write( screenshot.getImage(), "png", targetFile.toFile());
Take a Screenshot1
3
2
Screenshot screenshot = new AShot().takeScreenshot(browser);
Path targetFile = Paths.get( "target/screenshots", name + ".png");
ImageIO.write( screenshot.getImage(), "png", targetFile.toFile());
Take a Screenshot1
3
2
Screenshot screenshot = new AShot().takeScreenshot(browser);
Path targetFile = Paths.get( "target/screenshots", name + ".png");
ImageIO.write( screenshot.getImage(), "png", targetFile.toFile());
Take a Screenshot1
3
2
compose partials
aShothttps://github.com/yandex-qatools/ashot
Screenshot screenshot = new AShot() .takeScreenshot(browser, browser.findElement( By.id("username")));
Screenshot Composition1
3
2
Screenshot screenshot = new AShot() .takeScreenshot(browser, browser.findElement( By.id("username")));
Screenshot Composition1
3
2
requires JQuery in target page
Screenshot screenshot = new AShot() .imageCropper(new IndentCropper(50)) .takeScreenshot(browser, browser.findElement( By.id("username")));
Screenshot Composition1
3
2
new AShot().takeScreenshot(browser, browser.findElements( ByJQuery.selector( "input[name='username'], a:contains('Sign in')")));
Screenshot Composition1
3
2
new AShot().takeScreenshot(browser, browser.findElements( ByJQuery.selector( "input[name='username'], a:contains('Sign in')")));
Screenshot Composition1
3
2
PLURAL!
arquillianmaven
mavenaShotgraphene
keyhub-backend
Maven module dependencieswar
keyhub-tests
keyhub-backend
Maven module dependencieswar
keyhub-tests
keyhub-backend
keyhub-manual
Maven module dependencies
war
war
keyhub-tests
keyhub-backend
keyhub-manual
keyhub-app
Maven module dependencies
war
war
graphene aShotarquillian++ =
screenshots
Maven module: keyhub-tests
maven
maven+ =
screenshots
maven test module
+ maven
maven+
manual.html
manual.pdf
=manual.adoc
maven manual module
+ maven
mavenmanual.war=
manual.html
manual.pdf
maven manual module
application.war +manual.war
=+ maven
mavendockerwildfy
profit
maven app module
THE RESULT
ANUP-TO-DATEUSER MANUAL
THE RESULT
THE RESULT
THE RESULT 90%
TEST COVERAGE
AUTOMATE
ALL THE THINGS!
$
$%
$%
&
SOLUTIONS FOR WHEN DOCUMENTATION
AVOIDANCEFAILS
1. use plain text2. keep code and docs together3. integrate docs into your dev process4. automate all the things
writethedocs.orgasciidoctor.orgarquillian.orgmaven.apache.org
sources
THANK YOU!
@dashorst
QUESTIONS?
@dashorst
top related