Refresh Austin - Intro to Dexy

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

description

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

Transcript of Refresh Austin - Intro to Dexy

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.