See inside your app
What you'll build
This step adds nothing new to your app. Instead, you will learn to read the debug panel that appears below every Drafter app you run. The panel shows what your app is doing: the current state, every page visit so far, and your test results. Learning to read it now will save you hours later, because most "why is my app doing that?" questions can be answered by looking at it.
What you need
- The counter app from the previous steps.
- About ten minutes.
Step 1: Find the panel
Run this app, click the "debug" button in the top-right corner, and look below the page content:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
count: int
@route
def index(state: State) -> Page:
return Page(state, [
"Current count: " + str(state.count) + "\n",
Button("+1", "increment"),
Button("Reset", "reset_count")
])
@route
def increment(state: State) -> Page:
state.count = state.count + 1
return index(state)
@route
def reset_count(state: State) -> Page:
state.count = 0
return index(state)
assert_state(increment(State(0)), State(1))
assert_state(reset_count(State(7)), State(0))
start_server(State(0))
The area under the page is the debug panel. It has five tabs. The two you will use most often are:
- Current shows your state right now: every field of your
Statedataclass and its value. Click +1 in the app above, then look at Current. Thecountfield changed. Watching state change as you click is the fastest way to understand what your app is doing. - History lists every page your app has shown, in order, with the state at each moment. If something went wrong three clicks ago, History lets you look back at exactly what happened.
You will need the other three tabs less often:
- Overview lists all your routes and how they connect.
- Tests shows the results of your
assert_lines. The two tests in this app appear there, marked as passing. Break one on your computer (changeState(1)toState(2)) and watch it fail with an explanation of the difference. - Environment shows files, packages, and configuration details.
Step 2: See where print() goes
You can print(...) from inside a route to see what is happening while it
runs.
Note
If nothing seems to print, remember that printed output does not appear in the browser version of this demo. Run the program in Thonny to see it.
Run this, click the button, and watch:
from drafter import *
from dataclasses import dataclass
@dataclass
class State:
count: int
@route
def index(state: State) -> Page:
return Page(state, [
"Current count: " + str(state.count) + "\n",
Button("Double it", "double_count")
])
@route
def double_count(state: State) -> Page:
print("Before doubling:", state.count)
state.count = state.count * 2
print("After doubling:", state.count)
return index(state)
start_server(State(1))
The printed lines appear in the app's console area instead of disappearing. Printing the state before and after a change is the most basic debugging tool you have, and it works everywhere. Print and the console covers the details.
When the panel is missing
The debug panel exists to help the author, so it appears while you are building. When you publish your finished app for others, the panel is hidden. If you ever run your app and see no panel, it is in production mode; nothing is wrong.
Common problems
- The panel shows an old state value: state updates when a route runs. If you expected a change and Current does not show it, the route that should have changed it either did not run or did not assign the field. History will show which routes ran.
- Your tests do not appear in the Tests tab:
assert_lines must run when your program starts, so put them after your routes are defined and beforestart_server(...). - The panel is gone: see above; the app is in production mode.
Name it
- The area under your app is the debug panel (or debugger).
- The record of visited pages is the page history. Later, you will turn history into regression tests automatically.
Make it yours
- Add a third test to the counter that you predict will fail, run the app, and read the failure message in the Tests tab. Then fix the test.
- Add a
printtoindexand observe exactly when it runs. Every click? Only sometimes? What does that tell you?
Next steps
-
Next: How Drafter works
You have built, broken, fixed, and inspected an app. The next page spends five minutes naming what actually happened.