This story begings one day with a large amount of hubris when I was thinking I could write MagicMock in a more satisfactory way. I didn’t like the following things about magic mock.
- Templating wasn’t a default behavior
- Attributes where hard. Magic Mock likes to treat everytihng like as a callable.
- We can now track method calls on each instance.
- even knowing number of instances seem like it will be really useful.
- we can track the differences between methods called on the class and methods called on the instance.
- how hard can it be? We’ll call this exercise a ‘learning experence’
The exersise started as ‘a well maybe we can just implement the mocking object to record things a little different’ while still using the patch decorators to do the heavy lifting of patching the correct objects. But things like class methods proved to be a problem. the object the patch decorator supplies as the first argument really replaces the class object. It is nessary to implement patch to record class level interactions.
It was a interesting exersice showing why certion problem exsist. Remaking patch helped me discover parts of unit testing that would have been easy to gloss over or disregard as unimportant.
What follows is my path recreating patch and the birth of yet another mocking library.
Your culture is shown through your actions. Your actions are an effect of your values. Values are kind of like defaults. You can say you value craftsmanship, testing, quick feedback, or trust only when you refactor, test, gather feedback, or trust people more often than not. If these things are less likely to occur its hard to consider them defaults.
The good news is that your actions also effect your culture. You can start creating a culture of any of the things simply by doing them. Want to have culture of testing? Start testing. Actions also have an opportunity cost. Doing one thing means you can’t do something else at the same moment. But this is how we show what we value. Through choice.
So the title is kinda a lie. You can screw up one management methodology just as thoroughly as another, but Agile at its very core has some things I look for everywhere. Its principles suggest and even sometimes even explicitly express some of these things outright. Trust, Love, Respect and Understanding.
They are hard to talk about separately. One tends to require the others.
Love people for being people. We are complex, messy, freethinking, vastly different, individuals that have so much in common. Lets celebrate it. Our differences and the conversations that surround them are an incredible opportunity to learn something about ourselves as well as each other. Love the things that make us so similar. Love the differences.
Understanding that people just are. Our journeys are all different, but weirdly similar. As a group we have very similar abilities (mostly marginal in type / aptitude). We all have the ability to learn and make decisions as individuals. Understanding means realizing we get things wrong. This is no excuse, but a fact. We may be able to change one instance of ‘wrongness’, but not the existence of the collection that will appear in our lives.
Respect that people have the right and responsibility to make up their own damn minds. Our decisions are based on our past experiences. Respect our differences, because of our commonalities as people.
Trust the decisions your peers make. Trust implies that we take our hubris out of the equation and give our teammates, friends, and family members the benefit of the doubt. I love the retrospective prime directive here:
Regardless of what we discover, we understand and truly believe that everyone did
the best job they could, given what they knew at the time, their skills and abilities, the
resources available, and the situation at hand.
Trust that people at their cores aren’t malevolent, but are simply trying to do their best with their own complicated and conflicting requirements.
Agile, its manifesto and practices not only exemplify these things but require them at a deep level. Radiators that make information public don’t do much good if either side reduces or questions their validity. Pairing requires an understanding/respect/love for your pair. Constantly questioning or de-knoting(rands) the other person is a deep, cognitively intensive exercise. Surrendering to the task and trusting this unknown being sitting next to you requires a level of trust that has to be constantly practiced and is never completely perfected. The list of Agile practices goes on.
But I think this is simpler than just a list of practices that relates to these four words. Working with people is hard. Building this thing that is OUR collective project requires this stuff. It means surrendering part of oneself to others and the project. We can’t build all of it ourselves. Effective communication and cooperation requires Love, Trust, Respect, and Understanding.
These are my favorite things. I adopt practices that exemplify them and help me walk a path that is as close to these ideals as I can manage. Call the practices Agile, Lean or whatever you like. I’ll keep the ideals of Trust, Love, Respect and Understanding.
Let’s assume ‘wrong’ consolidates somewhere near a normal distribution. Any topic what we consider wrong consolidates around a norm, but differs at it edges. Outliers exist. This is a huge and philosophical topic, so that’s as far as I’m going to go here.
That’s It !!,
So let’s start with a premise…
A constraint will reduce the total pool of possible solutions.
Constraints are important because they help narrow our focus. They standardize our processes, technology, and reduce the amount of stuff we think about while trying to achieve our goal.
Constraints come in many flavours and varieties. Constraints are assigned to our code. Constraints are assigned to our organizations. Constraints are assigned to our processes.
Constraints are effectively a filter operation on a larger population(list of all solutions). Therefore every constraint has an effect, be that large or small. I’m here to ask you to think about the effects your constraints impose. Are you filtering out the right stuff?
That’s it !!
Where I wanted to end up
My goals for this endeavor was to end up with two commands in my most recent Django project, one that ran all my unit tests…
$ python manage.py test
and another than ran all the cucumber-like BDD lettuce tests…
$ python manage.py harvest -d
I wanted unit tests to take a minimal amount of time. I was able to reduce the unit test from 20 seconds to half of a second.
A few things where getting in my way…
- Django ‘s mange.py test command attempts to discover unit tests for every app specified under INSTALLED_APP. Django’s contrib and authentication modules that come with django also come with 300+ unit tests that run every time in this configuration
- mange.py test doesn’t normally run tests outside a app.
- You can run test in two ways through django manage.py test command; one app or everything
- django’s manage.py test doesn’t normally run tests outside an app
- lettuce – migrate messes up while you are also using south
- django – lettuce doesn’t automatically create and use a test database the way django unit tests do
So I needed to quickly setup integration testing for recent a flask app. I needed to hit a few end points, check the response body and return codes. I ended up using the following combination of unittest, os.fork, and requests. For now…
There are a few problems that have great recursive solutions. Depth first searching of nested data structure is one of these. Here we have a data structure constructed from a python dictionary. Keys ether point to a ‘normal’ value or another dictionary.
A simple pattern to getting stuff done.
It’s a two step process…
- Decide what the next thing to do is. The next thing has to have specifically defined finish criteria
- Totally dedicate your effort to accomplishing the next thing.
During the past year I’ve come to a conclusion about many IT professionals that make up their departments. I’ve begun calling this archetype: five button guys.