Skip to content
This repository has been archived by the owner on Feb 8, 2018. It is now read-only.

Commit

Permalink
Move VCR setup further up, onto Harness class
Browse files Browse the repository at this point in the history
In #2036 we started using VCR to freeze HTTP API calls into test
fixtures. This is great! Let's do more of that! This commit moves the
VCR configuration upstream from where it began (in test_billing.py) into
the gittip.testing.Harness class. Now all tests can make expensive HTTP
API calls with impunity. In fact, this knocks out a XXX comment, because
we had one API call elsewhere in the test suite. VCR transparently took
care of it for us! I was quite pleasantly surprised to find
TestPages.yml. Yay VCR! :-)

My first motivation in doing this, however, was to be able to write a
test for regression I'm seeing with payday (#2057). Onward!
  • Loading branch information
chadwhitacre committed Feb 20, 2014
1 parent a785541 commit adee120
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 28 deletions.
28 changes: 28 additions & 0 deletions gittip/testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from os.path import join, dirname, realpath

import pytz
import vcr
from aspen import resources
from aspen.testing.client import Client
from gittip.billing.payday import Payday
Expand All @@ -21,6 +22,7 @@
SCHEMA = open(join(TOP, "schema.sql")).read()
WWW_ROOT = str(realpath(join(TOP, 'www')))
PROJECT_ROOT = str(TOP)
FIXTURES_ROOT = join(TOP, 'tests', 'fixtures')


DUMMY_GITHUB_JSON = u'{"html_url":"https://github.com/whit537","type":"User",'\
Expand Down Expand Up @@ -106,6 +108,32 @@ def setUpClass(cls):
cls.tablenames = cls.db.all("SELECT tablename FROM pg_tables "
"WHERE schemaname='public'")
cls.seq = 0
cls.setUpVCR()


@classmethod
def setUpVCR(cls):
"""Set up VCR.
We use the VCR library to freeze API calls. Frozen calls are stored in
tests/fixtures/ for your convenience (otherwise your first test run
would take fooooorrr eeeevvveeerrrr). If you find that an API call has
drifted from our frozen version of it, simply remove that fixture file
and rerun. The VCR library should recreate the fixture with the new
information, and you can commit that with your updated tests.
"""
cls.vcr = vcr.VCR(
cassette_library_dir = FIXTURES_ROOT,
record_mode = 'once',
match_on = ['url', 'method'],
)
cls.vcr_cassette = cls.vcr.use_cassette('{}.yml'.format(cls.__name__)).__enter__()


@classmethod
def tearDownClass(cls):
cls.vcr_cassette.__exit__(None, None, None)


def setUp(self):
Expand Down
52 changes: 52 additions & 0 deletions tests/fixtures/TestPages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
- request: !!python/object:vcr.request.Request
body: null
headers: !!python/object/apply:__builtin__.frozenset
- - !!python/tuple [Accept-Encoding, 'gzip, deflate, compress']
- !!python/tuple [Accept, '*/*']
- !!python/tuple [Authorization, 'OAuth oauth_nonce="137591929179705732001392910038",
oauth_timestamp="1392910038", oauth_version="1.0", oauth_signature_method="HMAC-SHA1",
oauth_consumer_key="QBB9vEhxO4DFiieRF68zTA", oauth_token="34175404-G6W8Hh19GWuUhIMEXK0LyZsy7N9aCMcy1bYJ9rI",
oauth_signature="rgGWI%2F9gk8cryBIMurDwLG3X3lI%3D"']
- !!python/tuple [User-Agent, python-requests/1.2.3 CPython/2.7.5 Darwin/12.5.0]
host: api.twitter.com
method: GET
path: /1.1/users/show.json?screen_name=twitter
port: 443
protocol: https
response:
body:
string: !!binary |
H4sIAAAAAAAAAOxXbW/bNhD+K4QG7AXTbL1ZsgwMW5csaFEMGJqsxVAFAiWdbSYyqZCUHS/If99R
suT3reuGDgPmfIh59xx5vHvujn6yWGFNorHvuYGN31OlpTWxWoFlW5wuANc3K6Y1SBSoXALwdCPX
vbwUOdVMcBReU06uJOU5U7mwycULVBeAhqzaIH4VtSRiOmU5oyVRuMqBTIUkHFbKJnVVUA2KUF4Q
zSpFplIsyMYHm7zi+QC3rGWJW821ribJMBnqQS6S4Yi9ma+j1c2sRgRwzTQDZU2eWnTzD5fvnz7E
+rFCB6BID6BZKWaDzcXRapEMzf2Yqkq63mAPIQhgvGC5ceW9Y3ve7fPt80FQet9un1FVSaEh14DJ
mdJSgW1NRVmKFUiV5qLm2pp44zgcOeEYVZIBL3qF67uYD6bQuhON/ZGLQswdNVKqTU5rIFeQEc8h
bjDxR5NRQL528IMSJ0KXp3SJmWGYif7IEMOu8xRTpwDX33jjsePYlmYLSH8T3FDiZ5ozTCy5QRn5
8pdr8jm5oJwW9CvccgYiBU6z0lxMyxrvtQSJ+O1aaaprtT3TjTwPr0P5DDcHbnUIE7G9+7yDormP
6xHPnzjjSTDq79Nw2TA98P3Ij4Mo9vwocMLIc3ZYf6xEKw2PZvc3N+T7DQOvKyG1mpB38IUEUivG
Z+Qt40C0IGpOUWbofS3yOSPwmGMAF8jEAXkpVqQQRM+h8YjMsIYUYVxVDG3Wov6OXM8R09AeypLg
cXPyWbORMRgk3JBQTZLac7zQRKKpHPQuqR3HzymZS5h+m1gbGJKVZqLW+2xFahV1rhWSfgWgC8jv
E4tIKNGQi5ZmSbsj3BjEpUE0B+B+rdzERdY8p7sMZTyVUJXrVIu0zVFqQs7rsjyjbON+DMD8yzO2
G9U5y7321KqRc93XXAhZMG6aSyfCqs1hq+dasqzWQvYACU2YoEj/nHdujFWJ1DvJu3Dsx6Hrx67n
O3EU7vPuQLnl3b9Hsr4rvg7u3t5x55V2/qfcp6Rc1wEDJ26bsenFfSuOR/sDbk7VXNNZO9025Omz
ujeAXMezXdfMIEznepGJduzYp4bjWR6cmI4tdokkbeDLZPhT9INe3M3i8vXqaEaex+14io8S148a
T5ssGI7jtGzH5DYoW0L01dpLKqEUyzBVCrjCaC2hV22HyvOHBd356JB7Ll7E/S+E3I9tN3BOhvzp
4PW3Nw+PHoukl5uy8rGGYyTt7rztZXse+LYbte+jfzK9u3W2fYJ0bUSlGh+sqqSoPiXFABwZYVOb
shLSjOb3M4kEMa+t0thbLy4uf7w0TfwEhi3oDA7flFWmTMdczPp+edIMG2g4ipzYcUIvGZZu/QDr
kVqPPRmzu/k9uGxQ4Z3/+Ny0Ic4egT7B8RrX3ROvU/+VUHQOeN44cKMgGo2RxuFIUBZNH3kQPSxj
jg/mx5QLuaDlgSMfcfm/d2BGOcfiOazUs4E2aDys/d2VDF0/wBfoyPeinT1Lxu97inleGMbxjlax
AjIq0wznDZ7c4a6azwkcLsotKjR/OyjTzXqt33x2tNgYjsjRJbeAKa1LnW6wfbkcyDujvV83zBTs
ngTH7EMNSpvy1r2OC21+Y9BNY2qkz78DAAD//wMAZp5YTcsOAAA=
headers: ["cache-control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0\r\n",
"content-encoding: gzip\r\n", "content-length: 1235\r\n", "content-type: application/json;charset=utf-8\r\n",
"date: Thu, 20 Feb 2014 15:27:18 GMT\r\n", "expires: Tue, 31 Mar 1981 05:00:00
GMT\r\n", "last-modified: Thu, 20 Feb 2014 15:27:18 GMT\r\n", "pragma: no-cache\r\n",
"server: tfe\r\n", "set-cookie: lang=en\r\n", "set-cookie: guest_id=v1%3A139291003823273009;
Domain=.twitter.com; Path=/; Expires=Sat, 20-Feb-2016 15:27:18 UTC\r\n", "status:
200 OK\r\n", "strict-transport-security: max-age=631138519\r\n", "x-access-level:
read\r\n", "x-content-type-options: nosniff\r\n", "x-frame-options: SAMEORIGIN\r\n",
"x-rate-limit-limit: 180\r\n", "x-rate-limit-remaining: 177\r\n", "x-rate-limit-reset:
1392910100\r\n", "x-transaction: d7a88e315048b4b4\r\n", "x-xss-protection:
1; mode=block\r\n"]
status: {code: 200, message: OK}
27 changes: 0 additions & 27 deletions tests/test_billing.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
from __future__ import unicode_literals

import os

import balanced
import mock
import vcr

from gittip import billing
from gittip.security import authentication
Expand All @@ -13,12 +10,6 @@


def setUp_balanced(o):
o.vcr = vcr.VCR(
cassette_library_dir = os.path.dirname(os.path.realpath(__file__)) + '/fixtures/',
record_mode = 'once',
match_on = ['url', 'method'],
)
o.vcr_cassette = o.vcr.use_cassette('{}.yml'.format(o.__name__)).__enter__()
o.balanced_api_key = balanced.APIKey().save().secret
balanced.configure(o.balanced_api_key)
mp = balanced.Marketplace.my_marketplace
Expand Down Expand Up @@ -53,22 +44,13 @@ def setUp_balanced_resources(o):
).save().href)


def tearDown_balanced(o):
o.vcr_cassette.__exit__(None, None, None)


class TestBillingBase(Harness):

@classmethod
def setUpClass(cls):
super(TestBillingBase, cls).setUpClass()
setUp_balanced(cls)

@classmethod
def tearDownClass(cls):
tearDown_balanced(cls)
super(TestBillingBase, cls).tearDownClass()

def setUp(self):
Harness.setUp(self)
setUp_balanced_resources(self)
Expand All @@ -86,10 +68,6 @@ def setUp(self):
Harness.setUp(self)
setUp_balanced_resources(self)

@classmethod
def tearDownClass(cls):
tearDown_balanced(cls)
super(TestBalancedCard, cls).tearDownClass()

def test_balanced_card_basically_works(self):
balanced.Card.fetch(self.card_href) \
Expand Down Expand Up @@ -197,11 +175,6 @@ def setUp(self):
Harness.setUp(self)
setUp_balanced_resources(self)

@classmethod
def tearDownClass(cls):
tearDown_balanced(cls)
super(TestBalancedBankAccount, cls).tearDownClass()


def test_balanced_bank_account(self):
balanced.BankAccount.fetch(self.bank_account_href)\
Expand Down
1 change: 0 additions & 1 deletion tests/test_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ def test_github_proxy(self, requests):
actual = self.client.GET('/on/github/lgtest/').body.decode('utf8')
assert expected in actual

# This hits the network. XXX add a knob to skip this
def test_twitter_proxy(self):
expected = "Twitter has not joined"
actual = self.client.GET('/on/twitter/twitter/').body.decode('utf8')
Expand Down

0 comments on commit adee120

Please sign in to comment.