
OK
About Harry J.W. Percival
Customers Also Bought Items By
Are you an author?
Author Updates
-
Blog postFolks I've written a new book!
Along with my coauthor Bob, we are proud to release "Architecture Patterns with Python", which you can find out more about at cosmicpython.com.
The cosmic soubriquet is a little joke, Cosmos being the opposite of Chaos in ancient Greek, so we want to propose patterns to minimise chaos in your applications.
But the subtitle of the book is Enabling TDD, DDD, and Event-Driven Microservices, and the TDD part is relevant to this blog9 months ago Read more -
Blog postAt MADE.com i’ve been working on a new book with the chief architect, Bob Gregory, in which we talk about application architecture and design. What follows is an excerpt, a standalone chapter in which we talk about abstractions, testability, and coupling.
Have you ever struggled with writing tests for a bit of code that has a lot of dependencies? Someting involving I/O, interacting with 3rd parties, things like that? Wondering whether end-to-end/integration tests are the only way, and1 year ago Read more -
Blog postI've been learning lots of new stuff about application architecture recently, and I want to get a sense from you, dear reader, of whether these ideas are of interest, and whether we should try and build some more resources (blogs, talks, etc) around it.
How should we structure an application to get the most out of our tests? For me it all started with this question. At the end of my book I concluded on a chapter discussing how to get the most out of your tests, on the tradeoffs betwee2 years ago Read more -
Blog postThe problem: customisable fixtures in pytest Let's say you're running along merrily with some fixtures that create database objects for you:
@pytest.fixture def supplier(db): s = Supplier( ref=random_ref(), name=random_name(), country="US", ) db.add(s) yield s db.remove(s) @pytest.fixture() def product(db, supplier): p = Product( ref=random_ref(), name=random_name(), supplier=supplier, net_price=9.99, ) db2 years ago Read more -
Blog postHere's the tldr version:
DATABASES = { 'default': { 'ENGINE': 'your db settings as normal', [...] 'TEST': { # this gets you in-memory sqlite for tests, which is fast 'ENGINE': 'django.db.backends.sqlite3', } } } if 'test' in sys.argv and 'keepdb' in sys.argv: # and this allows you to use --keepdb to skip re-creating the db, # even faster! DATABASES['default']['TEST']['NAME'] = '/dev/shm/myproject.test.db.sqlite3' More co3 years ago Read more -
Blog postI'm still not great at selfies... Here you get two for the price of one tho. The second edition is officially out! on Amazon.com on Amazon.co.uk on ebooks.com (DRM-free) on Safari Thanks to everyone involved!
If you've been reading the free online edition and feel like showing your support, then now's the time! There's not a huge amount in it for me financially (I get about a dollar off every sale
3 years ago Read more -
Blog postHi all! A brief overview of changes in the latest version, with hopefully a few pointers for people half-way through the book and looking to adapt.
Python 3.6 and Django 1.11b: minimal changes, other than f-strings The main feature in Python 3.6 that's made an impact (for the book and, arguably, elsewhere) is f-strings.
I have to say when I first heard of them I was pretty skeptical, they sounded a bit like YOLO-ing **locals() all over your code, scary, but those concerns have4 years ago Read more -
Blog postSelenium 3 and Geckodriver Selenium 3 came out earlier this year, and the Mozilla project, those wonderful technohippies, have been pushing the standard forward (did someone say "bleeding edge"?), and the lastest versions of Firefox will only work with the new Selenium 3 and its "geckodriver" client driver.
The project it still young and has plenty of minor bugs still, but it's functional enough, and I don't want to have to continue recommending people downgrade t4 years ago Read more -
Blog postA brief update on my progress for the second edition.
Getting there!
Virtualenvs all the way down. In the first edition, I made the judgement call that telling people to use virtualenvs at the very beginning of the book would be too confusing for beginners. I've decided to revisit that decision, since virtualenvs are more and more de rigueur these days. I mean, if the djangogirls tutorial is recommending one, given that it's the most beginner-friendly tutorial on Earth, then i4 years ago Read more -
Blog postThe second edition was mostly prompted by the announcement by Mozilla that they were shutting down Persona in November 2016. Given that it would affect almost all the chapters from 15 thru to 21, it seemed a good excuse to do a full second edition rather than just an update.
Here, in brief, is an outline of the plan:
Chapter rewrites: Rewrite chapters 15 + 16, replace persona with passwordless auth: first draft done
Update chapters 17+ for persona changes: in progress4 years ago Read more -
Blog postComing to EuroPython? Will you be there by the Sunday before it all starts? (the 17th) Want to help some beginners to get to grips with Python, and get the most out of the conference? I need your help!
It's always surprising how many beginners come to Python conferences. The beginners' day is a full-day event aimed at helping them to get the best out of the conference -- getting them up to speed on the basics of Python, but also giving them a bit of a tour around the Python ecosystem,5 years ago Read more -
Blog postComing to Pycon? Want to help some beginners to get to grips with Python, and get the most out of the conference? I need your help!
Having observed the surprising number of beginners to be found at Python conferences, I organised a "beginners' day" at last year's EuroPython in Bilbao. We had about 30 beginners attend (from a crowd of 1200 at the conference) -- quite a few science types, some people who already knew another language but wanted to learn Python, and a few total5 years ago Read more -
Blog postMozilla has announced that they are retiring the Persona project, which I use in the book from chapter 15 onwards. This is sad news, because it was a great project, but also because it's going to break those chapters! So O'Reilly have suggested I write up a new edition of the book, and I'd like to get your suggestions and feedback.
It's not meant to be a wholesale rewrite, mainly just find a replacement for Persona, and then address a few improvements if I have time. So my questions t5 years ago Read more -
Blog postAfter many successful years of running my beginners' TDD/Django tutorial, I thought it might be time to have a crack at some more intermediate-level topics, so I'm announcing a couple of workshops.
the first is in London, on Monday the 4th of April, at Skillsmatter
the second is in Portland, Oregon, on Sunday the 29th of May, at Pycon
The aim will be to cover some intermediate-level topics. It assumes you've already started doing a bit of TDD, you've wrapped your head5 years ago Read more -
Blog postI recently did some experimenting with asyncio, and wanted to report back on how I got on with writing tests for it. While I was at it I was also able to compare its performance with a couple of other approaches to mutlitasking in Python, namely threads and gevent, so I'll report on that here too. (tl;dr: it's much of a muchness).
"hobbling" naughty user processes At PythonAnywhere we have a "tarpit" where we put users who exceed their usage limits. Their processes5 years ago Read more -
Blog postA colleague and I were staring at some ugly, mocky tests for our redis integration the other day, when I remembered someone at Pycon last year showing me a cool library called redislite -- basically, a lightweight, self-contained, pip installable version of redis, that can be installed almost anywhere and run totally separately from the system redis. (That was Dwight, who I now realise is the main author of redislite. Yay Pycon.)
He'd said "it's great for testing", so we tho5 years ago Read more -
Blog postTo my usual readers that come hear for TDD, apologies, this is off-topic, normal service will resume shortly.
I was in an autumnal mood yesterday, and found myself listening to 3 different versions of the jazz standard "Autumn Leaves", and since it's that sort of season, I thought I'd share them with you.
I realised I was surprisingly affected by the song, because actually I've been listening to it, in different forms, for much longer than I thought. Here are the thr5 years ago Read more -
Blog postThis post isn't about TDD, but I just wanted to gather some notes into one place about how to get Hi-DPI working on Ubuntu. I found other sources but my hope is that this will bring all the important tips into one place.
I have a character flaw as regards overly shiny laptops, and when my golden Sony Vaio Z series finally packed in after 3 years of service, it was time to get a new one. The sensible choice would have been a Thinkpad or a Galago from System 76, but then I saw this thin6 years ago Read more -
Blog postI've started working on a new appendix for the book, which is meant to be an intro to BDD. Will you head on over to the online version of the book and tell me what you think?
BDD appendix on Chimera
If you're an existing reader, do you think it makes a good addition to the book? If you're a BDD expert, is there anything I'm getting hideously wrong?
6 years ago Read more -
Blog postSomeone recently wrote to me asking about decorators, and saying they found them a bit confusing. Here's a post based on the email I replied to them with.
The best way to understand decorators is to build a couple of them, so here are two examples for you to try out. The first is in the Django world, the second is actually a simpler, pure-python one.
Challenge: build a decorator in a simple Django app We've built a very basic todo lists app using Django. It has views to deal w6 years ago Read more -
Blog post[Cross-posted on the PythonAnywhere blog]
We've been working on incorporating a Postgres database service into PythonAnywhere, and we decided to make it into a bit of a standalone project. The shiny is that we're using Docker to containerise Postgres servers for our users, and while we were at it we thought we'd try a bit of a different approach to testing. I'd be interested in feedback -- what do you like, what might you do differently?
Context: A Docker-based Postgres service <6 years ago Read more -
Blog postOft-heard is the folorn cry... Every so often you get bitten by a weird behaviour in one of your Selenium tests. You tell it to click a link, and then you ask it something about the new page, and it returns you something from the old page:
old_value = browser.find_element_by_id('my-id').text browser.find_element_by_link_text('my link').click() new_value = browser.find_element_by_id('my-id').text assert new_value != old_value ## fails unexpectedly (There's another example, in chapter6 years ago Read more -
Blog postMy copy of the print edition arrived in the post!
I am my own customer...
(OK that actually happened last month. This post is a little late. I was distracted by Oscons and stuff!)
Anyway, that's it, it's officially available. If you've been reading the free online version and have been holding out until the print version comes out, now's the time!
Or, if you've been waiting for the print version to come out before recommending the book to a friend, or buying a7 years ago Read more -
Blog postFor anyone that's been following the DHH / #isTDDDead controversy, or for anyone interested in what the limits of TDD are. Kent Beck (the godfather) had some really good reflections on what he was hoping to learn from the discussions:
I'm puzzled by the limits of TDD--it works so well for algorithm-y, data-structure-y code. I love the feeling of confidence I get when I use TDD. I love the sense that I have a series of achievable steps in front of me--can't imagine the implementation?7 years ago Read more -
Blog postIn a (futile) attempt to future-proof the book, I decided to upgrade it to Django 1.7. Here's how that went down.
Overview Unsurprisingly, the biggest change was to do with migrations. Like any new change, my initial reaction was dislike, and I resented the new things, but I think overall it's a definite improvment.
In brief, here's what happened:
The new migrations framework means 'any' change to models needs a migration, or tests won't pass.
This meant introd7 years ago Read more -
Blog postHere's a common set of questions about Django:
How do I get django to log errors to stderr? Why can't I see Django exceptions in the console? How do I get Django to log exceptions? How to print debug messages in Django? I know they're common because I've often found asking myself some kind of variant on these questions, at some point or other. Then I saw that, in Django 1.6/1.7, the default logging configuration actually does send logging messages to the console
So does this m7 years ago Read more -
Blog posttl;dr: I found myself going through increasing contortions trying to TDD some JavaScript code with Ajax in. Once I started using sinon.js, all the pain went away. Folks, don’t try to roll your own JavaScript mocks.
I’ve been playing around with Mozilla Persona as an authentication platform, and I knocked together this basic code to interact with their API. You can see it’s quite dense, but fairly readable:
var currentUser = '{{ user.email }}' || null; var csrf_token = '{{ csrf_tok7 years ago Read more -
Blog postThis blog post is a first rough draft of a planned appendix to my book. It follows on from Chapter 9, which is all about forms and validation. You can take a look at it here
If you want to check out the code to have a play with the examples, you’ll find them on GitHub under the chapter_09 branch and the appendix_II branch
As you’ll see, the content starts out sounding a lot like a "proper" chapter for a book, and turns into more of a blog post and request for comment7 years ago Read more -
Blog postIn chapter 8 of my book I introduce a fabric script as a way of automating the deployment of our example app. You can see the section where I do so here.
After 7 chapters of building everything step-by-step with TDD and detailed unit tests, this fairly large script leaps out fully-formed, It prompted one of my readers to write in (Thanks Nick):
It didn't work the first time I used it (I retype, rather than copy-paste, to better understand the code. Occasional typos are inevita7 years ago Read more -
Blog posttl;dr: I think there's a real danger that striving for an ultrafast test suite, will lead you to overly mocky, disjointed tests which don't help you catch bugs and don't help you code well.
At this year's DjangoCon, Casey Kinsey gave a talk in which he (at least ostensibly) advocated striving for faster test suites. As we'll find out, I've often thought that striving for fast tests suites can be a bit misguided, so I went along preparing to disagree loudly -- as anyone who knows me ca7 years ago Read more -
Blog postI can't believe the videos are already up! Here's a few links:
My usual TDD/Django Tutorial now featuring the example from the book! People's favourite bit seemed to be when I stand on the chair...
Me in a faster TDD/Python talk in Italiano. Still can't believe the organisers put me on as the first Italian talk of the whole week. I think it was some kind of evil joke.
Rob Collins' Test-Driven-Madness which I couldn't see because it was on at the same time as my tutori8 years ago Read more -
Blog postWARNING: this is not battle-tested wisdom of a massively experienced tornado tester. Today was the first time we ever tried to test something that actually uses the ioloop, and we've probably got it all totally backwards. Still, in case it helps...
Async. It's always hard to wrap your head around, so perhaps it's not surprising that it took us a few goes at work today before we got the hang of it.
Here's a bit of code that adds a callback to the tornado ioloop:
def sort_th8 years ago Read more -
Blog postHave been digging into the built-in forms and views from django.contrib.auth. I always knew you could get generic views for login, logout, even password reset, but I didn't know you could actually handle new user creation as well!
There's a form in django.contrib.auth.forms, and a class-based view for creating new objects called CreateView, and I believe this is all you need for a working registration form/view:
from django.views.generic.edit import CreateView from django.contrib.8 years ago Read more -
Blog postMy book has got to the stage of a minimum viable site. I want the next chapter to be about actually deploying the site, even though it's ridiculously early -- to encourage the habit of "deploy early, deploy often".
But how to introduce deployment in a beginner-friendly way? It's a very simple site, so we don't need to cover all the complexities of deployment, but what's the minimum? Here's what I've got so far..
Deploying a site to a live web server can be a tricky t8 years ago Read more -
Blog postJason, whom I met at PyCon this year, wrote a lovely review of my book on the O'Reily site. I'm very grateful because I think he actually helped me to see some things I didn't realise myself about the book. I'll reproduce it here, for which I hope my publisher will forgive me:
Programming books often fall into a few, easy to define categories. There are beginner's books, advanced books, reference books, books on specific libraries/frameworks, cookbooks, etc. "Test-Driven Web Deve8 years ago Read more -
Blog postHooray for O'Reilly, who are giving away ebooks half-price in celebration of the FSF's "Day against DRM"!
When I was first speaking to publishers about this book, I was a bit nervous. I'm very intersed in digital rights and copyright reform, and in fact I'm a reasonably active member of Pirate Party UK (or I was until this little project sucked up all my spare time!)... Could I find a publishing deal that would be compatible with my views? One of my colleagues in the German8 years ago Read more -
Blog postI can't quite believe this is actually happening, but I have not only signed a contract with O'Reilly, but i have actually written the first four chapters, or at least a first draft of the first four chapters!
For anyone new, the idea is to provide an introduction to TDD for web app development, for beginners -- whether it's people who've never done web development and Django before, or just people who've never done TDD.
I'm releasing the book as early as possible to try and g8 years ago Read more -
Blog post[update April 2012] : The book is now coming out on O'Reilly! more info here:
http://www.tdd-django-tutorial.com/blog/articles/2013/test-driven-development-web-applications-book-exis/
Thanks so much for following on this far! I'm afraid that's all there is for now, but I am about to start on the next stage -- a proper book on TDD for web apps.
If you've found the tutorial useful so far, I wonder whether I can solicit some feeback regarding a book version?
Here'8 years ago Read more -
Blog postI've decided to try and develop this tutorial into an actual book on test-driven development for web apps. Have a look at the chapter outline I've posted as part 6:
http://www.tdd-django-tutorial.com/tutorial/6/
I'd love to hear what you think! Am I completely mad?
8 years ago Read more
There's a problem loading this menu right now.
As Python continues to grow in popularity, projects are becoming larger and more complex. Many Python developers are now taking an interest in high-level software design patterns such as hexagonal/clean architecture, event-driven architecture, and the strategic patterns prescribed by domain-driven design (DDD). But translating those patterns into Python isn’t always straightforward.
With this hands-on guide, Harry Percival and Bob Gregory from MADE.com introduce proven architectural design patterns to help Python developers manage application complexity—and get the most value out of their test suites.
Each pattern is illustrated with concrete examples in beautiful, idiomatic Python, avoiding some of the verbosity of Java and C# syntax. Patterns include:
- Dependency inversion and its links to ports and adapters (hexagonal/clean architecture)
- Domain-driven design’s distinction between entities, value objects, and aggregates
- Repository and Unit of Work patterns for persistent storage
- Events, commands, and the message bus
- Command-query responsibility segregation (CQRS)
- Event-driven architecture and reactive microservices
By taking you through the development of a real web application from beginning to end, the second edition of this hands-on guide demonstrates the practical advantages of test-driven development (TDD) with Python. You’ll learn how to write and run tests before building each part of your app, and then develop the minimum amount of code required to pass those tests. The result? Clean code that works.
In the process, you’ll learn the basics of Django, Selenium, Git, jQuery, and Mock, along with current web development techniques. If you’re ready to take your Python skills to the next level, this book—updated for Python 3.6—clearly demonstrates how TDD encourages simple designs and inspires confidence.
- Dive into the TDD workflow, including the unit test/code cycle and refactoring
- Use unit tests for classes and functions, and functional tests for user interactions within the browser
- Learn when and how to use mock objects, and the pros and cons of isolated vs. integrated tests
- Test and automate your deployments with a staging server
- Apply tests to the third-party plugins you integrate into your site
- Run tests automatically by using a Continuous Integration environment
- Use TDD to build a REST API with a front-end Ajax interface
Durante o processo, você conhecerá o básico sobre Django, Selenium, Git, jQuery e Mock, junto com as técnicas atuais para desenvolvimento web. Se estiver pronto para levar suas habilidades com Python para o próximo patamar, este livro – atualizado com Python 3.6 – mostrará claramente como o TDD incentiva você a criar designs simples e pode lhe inspirar confiança.
■ mergulhe no fluxo de trabalho de TDD, incluindo o ciclo de testes de unidade/código e refatoração;
■ utilize testes de unidade para classes e funções, e testes funcionais para interações com usuários no navegador;
■ saiba quando e como usar objetos simulados e conheça os prós e contras dos testes isolados versus testes integrados;
■ teste e automatize suas implantações com um servidor de staging;
■ aplique testes nos plugins de terceiros que você integrar ao seu site;
■ execute testes automaticamente usando um ambiente de Integração Contínua;
■ utilize TDD para construir uma API REST com uma interface de frontend Ajax.