Showing posts with label dev diary. Show all posts
Showing posts with label dev diary. Show all posts

Replay network requests on your tests: VCR.py

Today I'm happy to present you another library to aid with testing, this time related to tests that need network conectivity: VCR.py

VCR.py, a Python version of Ruby's VCR, works by recording the HTTP requests and responses your test makes, and then replays them when the tests is run again, thus achieving network independence. As a side effect, it also makes the test much faster, which is always nice.

Using it on a typical test is very easy, you just need to import it, and then surround the test that will interact with the network with a with vcr.cassete() block:

Parse ISO 8601 dates in Python

Quick question-answer for today:

Q: How to parse an ISO 8601 date in Python?

A: Use dateutils Use the iso8601 module Use strptime:

*time.strptime(my_date,"%Y-%m-%dT%H:%M:%S")[:6]
I spent quite some time looking for an easy answer to this, but all the suggested modules I got where either buggy and not maintained anymore, or so old so that they were not even available on pip. So, this one liner was the best solution in the end.

PD: Beware of timezones! This works assuming you're using UTC.

Freezegun, time travel for Python tests

Yesterday I discovered freezegun, a Python library to run test cases at defined moments in time. It feels just like the equivalent of Ruby's timecop gem, and it saves me a lot of headaches trying to mock the datetime module.

What I was trying to test is a method named delete_expired_promises, which removes reservations for items after the expiration time has run out. The code, using freezegun came to be this simple:

with freeze_time('2013-10-30 10:00:00'):
            self.store.save('1111', '2222', reservation_id='1')
            self.store.save('3333', '4444', reservation_id='2')

with freeze_time('2013-10-30 11:00:00'):
    self.store.save('1111', '2222', reservation_id='3')

with freeze_time('2013-10-30 12:30:00'):
    self.store.delete_expired_promises()

    self.assertIsNone(self.collection.find_one({'reservation_id': '1'}) )
    self.assertIsNone(self.collection.find_one({'reservation_id': '2'}) )
    self.assertIsNotNone(self.collection.find_one({'reservation_id': '3'}) )

As you can see, I "freeze" the time at different intervals, create reservations, then run the delete_expired_promises method, and check if they have been removed correctly. It could not be more straighforward!

Modify an element of an array in MongoDB

Let's say you have a document in MongoDB like so:
{
 "apple_pie" : {
  "ingredients" : [
   "flour",
   "orange",
   "butter",
   "sugar"
  ]
 }
}

And you see that you've made a mistake there: one of the elements of the ingredients array should be changed, to apple. But how?

Turns out there's an operator called "$", which, in an update operation, identifies an element in an array, without having to know its positional value. We would use it in this case like so:
db.recipes.update(
 {"apple_pie.ingredients": "orange"},
 { "$set": {"apple_pie.ingredients.$": "apple"} }
)

Once we have selected an element on the query side of the update, we can refer to it with $. So, this update operation means: "select the array element named orange, and set it to apple". 

You can find more info about this operator on the mongoDB docs, but I hope this post helps you find your way if you google for this problem :-)

Calendars, lots of calendars

I'm happy to see that, by today, I know enough Python to be able to work on a TDD loop: write a failing test, write the code to make it green, refactor and cleanup. Protip: use py.test as the test runner, and mock all the things! No wonder the mock library got added to the Python Standard Library in Python 3: it really feels magical sometimes.

While checking how to use dates in Python, I ran into a reference to Dershowitz and Reingold’s book Calendrical Calculations. This book seems to be the reference material for working with dates in computer science, and raised my attention for two reasons: 
  1. It supplies its algorithms in Lisp, and
  2. It is detailed to the point of supplying conversion details for "Korean, Vietnamese, Aztec, and Tibetan calendars". Talk about internationalisation.
One of the two calendars used by the Aztecs has 260 days, each of them named by a combination of a number from 1 to 13 and a day sign, which is one of these 20:


Much, much cooler than our Gregorian calendar. 

See you tomorrow, 7 Ocelotl, a Jaguar day.

Dev diary, day 3: Python for Rubyists

Today was a fun day. Due to the problem I had yesterday with importing relative paths, I spent most of this morning reading about modules in Python. I also found out that there is a nice debugger for python code, called pdb, which reminds me a lot of irb when used with the -rdebug option.

Ever since I started doing Python full-time (~8 days ago!) I've had this nagging feeling that it is not as "pretty" or usable as Ruby. Talking with my colleagues about this, and other differences between the two languages, led me to this presentation, which really lifted my spirits:



There might be lots of superficial differences between the way Ruby and Python developers do their thing, but the philosophy behind both languages, and the capabilities provided by them, seem to be pretty similar. Out all of the transitions between languages that I've had (Java to Javascript, JS to Ruby, etc) this one is being the smoothest one, and that's making me happy :-)

PD: I need to start using better fonts for these posts —Arial and Courier do not match that well. Sorry about that!

Dev diary, day 2: testing

Today I learned some stuff about testing in Python. Since I've been working with Ruby for the past couple of years, and the Ruby community is pretty serious about testing, I've come to rely on it a lot to help me code with confidence.

In my current team we have a lot of tests, written with Python's unittest library, and ran with nose ("is nicer testing for python"). These two libraries remind me of Ruby's Test:Unit, and how test are run on apps using rake, like I've shown here on a previous post.

I've run into some problems while trying to load the code I want to test on my test file, using the "import". It seems that, when using Python, importing relative paths is Not a Good Idea™, as the PEP8 clearly states:

"Implicit relative imports should never be used and have been removed in Python 3."

This, together with a lot of answered questions on Stack Overflow, that state the same, has lead me to find a better solution for this. For now, no green test today :-(


One thing I found amusing about PEP8 is the title of what follows the introduction, which comes from a quote by Ralph Waldo Emerson, an American philosopher:

"A foolish consistency is the hobgoblin of little minds, adored by little statesmen and philosophers and divines."

You can read more about it on Wikipedia, and to entice you, here's a picture of a hobgoblin:



See you tomorrow!

Dev Diary: day 1

From today on, after being inspired by this blog, I am going to try to write something here every day, about my life as a coder.

I started to work full-time at Antevorte last week, coding on a Python + mongoDB stack on a Linux system. This tweet expresses how I was feeling after four days of it:

Because of that, the best part of my day today was the tutorial at try.mongodb.org. It helped me reaffirm some of the concepts about mongoDB that I learned last week, and I really felt like one week of mongo was already starting to pay off.

While following the tutorial, I found this awkward-looking sentence:



And so, after finding the GitHub repo for the tutorial, I submitted a pull request!


Also, at the end of the tutorial, there is a chance to win a mongoDB t-shirt or mug. I didn't get it, but maybe you will ;-)

More, tomorrow.