Skip to content

Commit 4af2934

Browse files
Merge pull request #318 from algolia/test/pytest
tests: change nose2 for pytest
2 parents c6bc1d3 + e0c5569 commit 4af2934

File tree

14 files changed

+1459
-1735
lines changed

14 files changed

+1459
-1735
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,7 @@ pip-log.txt
2727
# IDE/OS Files
2828
.idea
2929
.DS_Store
30+
.vscode
31+
pytest.ini
32+
tags
33+
.cache

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ tox
22
wheel
33
pypandoc
44

5-
# Dev
65
requests[security]>=2.9.1
7-
nose2
86
faker
7+
pytest

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import pytest
2+
3+
from helpers import Factory
4+
from helpers import create_client, create_index, IndexWithData
5+
6+
7+
@pytest.fixture
8+
def mcm_client():
9+
return create_client('ALGOLIA_APPLICATION_ID_MCM', 'ALGOLIA_API_KEY_MCM')
10+
11+
12+
@pytest.fixture
13+
def client():
14+
return create_client()
15+
16+
17+
@pytest.fixture
18+
def index(client):
19+
idx = create_index(client)
20+
yield idx
21+
client.delete_index(idx.index_name) # Tear down
22+
23+
24+
@pytest.fixture(scope='module')
25+
def ro_index():
26+
idx = IndexWithData(create_client())
27+
yield idx
28+
idx.client.delete_index(idx.index_name) # Tear down
29+
30+
31+
@pytest.fixture
32+
def rw_index():
33+
idx = IndexWithData(create_client())
34+
yield idx
35+
idx.client.delete_index(idx.index_name) # Tear down
36+
37+
38+
@pytest.fixture
39+
def double_indexes():
40+
clt = create_client()
41+
factory = Factory()
42+
43+
index1 = IndexWithData(clt, factory=factory)
44+
index2 = IndexWithData(clt, factory=factory)
45+
46+
yield [index1, index2]
47+
48+
# Tear down
49+
index1.client.delete_index(index1.index_name)
50+
index2.client.delete_index(index2.index_name)

tests/fake_session.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from collections import namedtuple
2+
3+
4+
FakeResp = namedtuple('FakeResp', ['status_code', 'json'])
5+
6+
7+
class FakeSession:
8+
def __init__(self, exp_headers, exp_params):
9+
self.headers = exp_headers
10+
self.params = exp_params
11+
12+
def request(self, path, meth, timeout, params, data, headers):
13+
assert headers == self.headers
14+
assert params == self.params
15+
16+
return FakeResp(status_code=200, json=lambda: '{}')

tests/helpers.py

Lines changed: 109 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,125 @@
1-
# -*- coding: utf-8 -*-
2-
3-
from __future__ import unicode_literals
4-
51
import os
62
import time
73
from random import randint
84

9-
from faker import Factory
10-
from algoliasearch.client import Client
5+
from algoliasearch import algoliasearch
6+
from faker import Faker
7+
8+
9+
def check_credentials():
10+
credentials = [
11+
'ALGOLIA_APPLICATION_ID',
12+
'ALGOLIA_API_KEY',
13+
'ALGOLIA_API_KEY_SEARCH',
14+
'ALGOLIA_APPLICATION_ID_MCM',
15+
'ALGOLIA_API_KEY_MCM'
16+
]
17+
18+
for credential in credentials:
19+
if credential not in os.environ:
20+
print('environement variable {} not defined')
21+
assert False
1122

12-
from collections import namedtuple
1323

24+
def index_name():
25+
name = 'algolia-python{}'.format(randint(1, 100000))
1426

15-
class FakeData(object):
27+
if 'TRAVIS' in os.environ:
28+
name = '{}_travis-{}'.format(name, os.environ['TRAVIS_JOB_NUMBER'])
29+
30+
return name
31+
32+
33+
class Factory:
1634
def __init__(self):
17-
self._fake = Factory.create('zh_CN')
18-
self._fake.seed(4242)
19-
self._generated_id = []
35+
self._faker = Faker('zh_CN')
36+
self.last_id = 0
2037

21-
def fake_contact(self, n=1):
38+
def contacts(self, count=1):
2239
data = []
23-
for i in range(n):
40+
for _ in range(count):
2441
data.append({
25-
'name': self._fake.name(),
26-
'email': self._fake.email(),
27-
'phone': self._fake.phone_number(),
28-
'city': self._fake.city(),
29-
'country': self._fake.country()
42+
'name': self._faker.name(),
43+
'email': self._faker.email(),
44+
'phone': self._faker.phone_number(),
45+
'city': self._faker.city(),
46+
'country': self._faker.country()
3047
})
3148

32-
return data[0] if n == 1 else data
49+
return data[0] if count == 1 else data
50+
51+
def with_objectids(self, ids):
52+
if isinstance(ids, str) or isinstance(ids, int):
53+
contacts = self.contacts()
54+
contacts['objectID'] = ids
55+
return contacts
56+
57+
contacts = self.contacts(len(ids))
58+
for objid, contact in zip(ids, contacts):
59+
contact['objectID'] = objid
60+
61+
return contacts
62+
63+
def objectids(self, n=1):
64+
ids = [str(i) for i in range(self.last_id, self.last_id + n)]
65+
self.last_id += n
66+
return ids
67+
68+
69+
def create_client(
70+
app_id_env='ALGOLIA_APPLICATION_ID',
71+
api_key_env='ALGOLIA_API_KEY'
72+
):
73+
if 'APPENGINE_RUNTIME' in os.environ:
74+
from google.appengine.api import apiproxy_stub_map
75+
from google.appengine.api import urlfetch_stub
76+
77+
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
78+
apiproxy_stub_map.apiproxy.RegisterStub(
79+
'urlfetch', urlfetch_stub.URLFetchServiceStub()
80+
)
3381

34-
def generate_id(self):
35-
while True:
36-
new_id = randint(0, 100000)
37-
if new_id not in self._generated_id:
38-
self._generated_id.append(new_id)
39-
return str(new_id)
82+
check_credentials()
83+
try:
84+
return algoliasearch.Client(
85+
os.environ[app_id_env],
86+
os.environ[api_key_env]
87+
)
88+
except:
89+
raise RuntimeError(
90+
"{} and {} environement variables must be set".format(
91+
app_id_env, api_key_env
92+
)
93+
)
4094

41-
def get_rule_stub(objectID='my-rule'):
95+
96+
def create_index(clt):
97+
name = index_name()
98+
task = clt.delete_index(name)
99+
idx = clt.init_index(name)
100+
idx.wait_task(task['taskID'])
101+
102+
return idx
103+
104+
105+
class IndexWithData:
106+
def __init__(self, clt, factory=None):
107+
if factory is None:
108+
factory = Factory()
109+
110+
self.data = factory.contacts(5)
111+
self._index = create_index(clt)
112+
task = self._index.add_objects(self.data)
113+
self._index.wait_task(task['taskID'])
114+
self.ids = task['objectIDs']
115+
116+
def __getattr__(self, name):
117+
return getattr(self._index, name)
118+
119+
120+
def rule_stub(objid='my-rule'):
42121
return {
43-
'objectID': objectID,
122+
'objectID': objid,
44123
'condition': {
45124
'pattern': 'some text',
46125
'anchoring': 'is'
@@ -52,25 +131,9 @@ def get_rule_stub(objectID='my-rule'):
52131
}
53132
}
54133

55-
def get_api_client():
56-
if 'APPENGINE_RUNTIME' in os.environ:
57-
from google.appengine.api import apiproxy_stub_map
58-
from google.appengine.api import urlfetch_stub
59-
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
60-
apiproxy_stub_map.apiproxy.RegisterStub('urlfetch', urlfetch_stub.URLFetchServiceStub())
61-
return Client(os.environ['ALGOLIA_APPLICATION_ID'],
62-
os.environ['ALGOLIA_API_KEY'])
63-
64-
65-
def safe_index_name(name):
66-
if 'TRAVIS' not in os.environ:
67-
return name
68-
job = os.environ['TRAVIS_JOB_NUMBER']
69-
return '{0}_travis-{1}'.format(name, job)
70-
71134

72135
def wait_key(index, key, block=None):
73-
for i in range(60):
136+
for _ in range(60):
74137
try:
75138
k = index.get_user_key_acl(key)
76139
if block is None or block(k):
@@ -82,24 +145,10 @@ def wait_key(index, key, block=None):
82145

83146

84147
def wait_missing_key(index, key):
85-
for i in range(60):
148+
for _ in range(60):
86149
try:
87150
index.get_user_key_acl(key)
88151
time.sleep(1)
89152
except:
90-
# Not found.
153+
# Not found
91154
return
92-
93-
FakeResp = namedtuple('FakeResp', ['status_code', 'json'])
94-
95-
class FakeSession(object):
96-
def __init__(self, test_class, exp_headers, exp_params):
97-
self.test_class = test_class
98-
self.headers = exp_headers
99-
self.params = exp_params
100-
101-
def request(self, path, meth, timeout, params, data, headers):
102-
self.test_class.assertDictEqual(headers, self.headers)
103-
self.test_class.assertDictEqual(params, self.params)
104-
105-
return FakeResp(status_code=200, json=lambda: '{}')

0 commit comments

Comments
 (0)