32
Refreshing Documentation An Introduction to Dexy Ana Nelson dexy.it July 12, 2011

Refresh Austin - Intro to Dexy

Embed Size (px)

DESCRIPTION

Slides for my Refreshing Documentation talk at Refresh Austin on July 12, 2011. Sources and handouts available from bitbucket: http://bit.ly/qXU3yP

Citation preview

Page 1: Refresh Austin - Intro to Dexy

Refreshing DocumentationAn Introduction to Dexy

Ana Nelson

dexy.it

July 12, 2011

Page 2: Refresh Austin - Intro to Dexy

Dexy for Web Apps

• Install Guide

• User Guide

• Developer Docs

Page 3: Refresh Austin - Intro to Dexy

Dexy for Web Apps

• Install Guide

• User Guide

• Developer Docs

Page 4: Refresh Austin - Intro to Dexy

Dexy for Web Apps

• Install Guide

• User Guide

• Developer Docs

Page 5: Refresh Austin - Intro to Dexy

The Big Idea

No Dead Code

• Any code you show comes from a live, runnable file.

• Any images or output you show comes from running live code.

Page 6: Refresh Austin - Intro to Dexy

Benefits

• Correctness

• Maintainability

• Workflow

Page 7: Refresh Austin - Intro to Dexy

Tool for the job

Dexy

• Open Source (mostly MIT, some AGPL)

• Written in Python

• Command Line, Text Based

• * Agnostic

• My Day Job and my Mission in Life

Page 8: Refresh Austin - Intro to Dexy

Demo

What we want to create:

• Install Guide

• User Guide

• Developer Docs

What we need:

• An App!

• Install Script

• Watir Script

Page 9: Refresh Austin - Intro to Dexy

An App

web.py todo list app http://webpy.org/src/todo-list/0.3

Page 10: Refresh Austin - Intro to Dexy

DB Schema

CREATE TABLE todo (

id INTEGER PRIMARY KEY AUTOINCREMENT,

title TEXT

);

Page 11: Refresh Austin - Intro to Dexy

model.py

import web

db = web.database(dbn= ’ sqlite ’ , db= ’ todo.sqlite3 ’ )

def get_todos():

return db.select( ’ todo ’ , order= ’ id ’ )

def new_todo(text):

db.insert( ’ todo ’ , title=text)

def del_todo(id):

db.delete( ’ todo ’ , where= " id=$id " , vars=locals())

Page 12: Refresh Austin - Intro to Dexy

base.html

$def with (page)

<html>

<head>

<title>Todo list</title>

</head>

<body>

$:page

</body>

</html>

Page 13: Refresh Austin - Intro to Dexy

index.html

$def with (todos, form)

<table>

<tr>

<th>What to do ?</th>

<th></th>

</tr>

$for todo in todos:

<tr>

<td>$todo.title</td>

<td>

<form action= "/del/$todo.id" method= "post" >

<input type= "submit" value= "Delete" />

</form>

</td>

</tr>

</table>

<form action= "" method= "post" >

$:form.render()

</form>

Page 14: Refresh Austin - Intro to Dexy

todo.py

""" Basic todo list using webpy 0.3 """

import web

import model

urls = (

’ / ’ , ’ Index ’ ,

’ /del/( \ d+) ’ , ’ Delete ’

)

render = web.template.render( ’ templates ’ , base= ’ base ’ )

Page 15: Refresh Austin - Intro to Dexy

todo.py

class Index:

form = web.form.Form(

web.form.Textbox( ’ title ’ , web.form.notnull,

description= " I need to: " , size=75),

web.form.Button( ’ Add todo ’ ),

)

Page 16: Refresh Austin - Intro to Dexy

todo.py

def GET(self):

""" Show page """

todos = model.get_todos()

form = self.form()

return render.index(todos, form)

Page 17: Refresh Austin - Intro to Dexy

todo.py

def POST(self):

""" Add new entry """

form = self.form()

if not form.validates():

todos = model.get_todos()

return render.index(todos, form)

model.new_todo(form.d.title)

raise web.seeother( ’ / ’ )

Page 18: Refresh Austin - Intro to Dexy

todo.py

class Delete:

def POST(self, id):

""" Delete based on ID """

id = int(id)

model.del_todo(id)

raise web.seeother( ’ / ’ )

Page 19: Refresh Austin - Intro to Dexy

todo.py

app = web.application(urls, globals())

if __name__ == ’ __main__ ’ :

app.run()

Page 20: Refresh Austin - Intro to Dexy

install script

Install Script

Page 21: Refresh Austin - Intro to Dexy

install script

apt-get update

apt-get upgrade -y --force-yes

apt-get install -y python-webpy

apt-get install -y mercurial

apt-get install -y sqlite3

Page 22: Refresh Austin - Intro to Dexy

install script

hg clone https://bitbucket.org/ananelson/dexy-examples

cd dexy-examples

cd webpy

sqlite3 todo.sqlite3 < schema.sql

python todo.py

Page 23: Refresh Austin - Intro to Dexy

install script

export UBUNTU_AMI= "ami-06ad526f" # natty

cd ~/.ec2

ec2run $UBUNTU_AMI -k $EC2_KEYPAIR \

-t t1.micro -f ~/dev/dexy-examples/webpy/ubuntu-install.sh

(Make sure to allow access to port 8080 in security group.)

Page 24: Refresh Austin - Intro to Dexy

Now What

• We have an app and we have it running.

• We have an install script which we can use to create an install guide.

• Now we need a script to show how the app works.

Page 25: Refresh Austin - Intro to Dexy

Watir

• Watir lets us automate the web browser

• Can be integrated with functional tests

• For extra awesomeness, let’s use Watir to take screenshots

Page 26: Refresh Austin - Intro to Dexy

watir

require ’rubygems’

require ’safariwatir’

IP_ADDRESS = ENV[ ’EC2_INSTANCE_IP’ ]

PORT = ’8080’

BASE = " http:// #{ IP_ADDRESS } : #{ PORT } / "

Page 27: Refresh Austin - Intro to Dexy

watir

We create a reference to the browser:browser = Watir::Safari.new

And define a helper method to take screenshots:def take_screenshot(filename)

sleep(1) # Make sure page is finished loading.

‘ screencapture #{ filename } ‘

‘ convert -crop 800x500+0+0 #{ filename } #{ filename } ‘

end

Page 28: Refresh Austin - Intro to Dexy

watir

Now we’re ready to go!browser.goto(BASE)

take_screenshot( " dexy--index.png " )

Page 29: Refresh Austin - Intro to Dexy

watir

Let’s enter a TODO:browser.text_field( :name , " title " ).set( " Prepare Refresh Austin Talk Demo " )

take_screenshot( " dexy--enter.png " )

Page 30: Refresh Austin - Intro to Dexy

watir

Click the ”Add todo” button to add it. We’ll verify that it was actually added.

browser.button( :name , " Add todo " ).click

raise unless browser.html.include?( " <td>Prepare Refresh Austin Talk Demo</td> " )

take_screenshot( " dexy--add.png " )

Page 31: Refresh Austin - Intro to Dexy

watir

And delete it again:

browser.form( :index , 1).submit

take_screenshot( " dexy--delete.png " )

Page 32: Refresh Austin - Intro to Dexy

• Now we have screenshots we can use in our documentation, and whichwe can update any time.

• We also know that the steps described in our screenshots WORK.

• Note that we are also validating our install script.

• You will want to return your DB to its original state within your script, orhave a reset method in your app.