0003-tests-add-real-ones-with-fixtures-fixes-27482.patch
tests/conftest.py | ||
---|---|---|
1 |
import os |
|
2 |
import glob |
|
3 |
import json |
|
4 |
from contextlib import closing |
|
5 | ||
1 | 6 |
import pytest |
2 | 7 | |
3 | 8 |
import django_webtest |
9 | ||
10 |
import sqlparse |
|
11 | ||
12 |
import psycopg2 |
|
13 | ||
14 | ||
15 |
from django.db import connection |
|
4 | 16 |
from django.contrib.auth.models import User |
5 | 17 | |
6 | 18 | |
7 | 19 |
@pytest.fixture |
8 |
def app(request): |
|
20 |
def app(settings, request): |
|
21 |
settings.TEMPLATE_DEBUG = True |
|
22 |
settings.DEBUG = True |
|
9 | 23 |
wtm = django_webtest.WebTestMixin() |
10 | 24 |
wtm._patch_settings() |
11 | 25 |
request.addfinalizer(wtm._unpatch_settings) |
... | ... | |
29 | 43 |
u.is_staff = True |
30 | 44 |
u.save() |
31 | 45 |
return u |
46 | ||
47 |
SCHEMA_PATHS = os.path.join(os.path.dirname(__file__), 'fixtures/') |
|
48 | ||
49 | ||
50 |
def load_schema(settings, tmpdir, schema): |
|
51 |
import random |
|
52 | ||
53 |
database_name = 'db%s' % random.getrandbits(20) |
|
54 |
try: |
|
55 |
with closing(psycopg2.connect('')) as conn: |
|
56 |
conn.set_isolation_level(0) |
|
57 |
with conn.cursor() as cursor: |
|
58 |
cursor.execute('CREATE DATABASE %s' % database_name) |
|
59 | ||
60 |
schema_dir = tmpdir.mkdir('schemas') |
|
61 |
SCHEMA_DIR = os.path.join(SCHEMA_PATHS, schema) |
|
62 | ||
63 |
# copy schemas and set pg_dsn |
|
64 |
for schema_path in glob.glob(os.path.join(SCHEMA_DIR, '*.json')): |
|
65 |
with open(schema_path) as f: |
|
66 |
schema = json.load(f) |
|
67 |
schema['pg_dsn'] = 'dbname=%s' % database_name |
|
68 |
new_schema_path = schema_dir.join(os.path.basename(schema_path)) |
|
69 |
new_schema_path.write(json.dumps(schema)) |
|
70 | ||
71 |
settings.BIJOE_SCHEMAS = [str(schema_dir.join('*.json'))] |
|
72 |
with closing(psycopg2.connect(database=database_name)) as conn: |
|
73 |
conn.set_isolation_level(0) |
|
74 |
with conn.cursor() as cursor: |
|
75 |
for sql_path in sorted(glob.glob(os.path.join(SCHEMA_DIR, '*.sql'))): |
|
76 |
with open(sql_path) as sql_file: |
|
77 |
sql = sql_file.read() |
|
78 |
statements = sqlparse.split(sql) |
|
79 |
for statement in statements: |
|
80 |
if not statement.strip(';').strip(): |
|
81 |
continue |
|
82 |
cursor.execute(statement.rstrip(';')) |
|
83 |
yield |
|
84 |
finally: |
|
85 |
with closing(psycopg2.connect('')) as conn: |
|
86 |
conn.set_isolation_level(0) |
|
87 |
with conn.cursor() as cursor: |
|
88 |
cursor.execute('DROP DATABASE IF EXISTS %s' % database_name) |
|
89 | ||
90 | ||
91 |
@pytest.fixture |
|
92 |
def schema1(db, settings, tmpdir): |
|
93 |
for _ in load_schema(settings, tmpdir, 'schema1'): |
|
94 |
yield _ |
tests/fixtures/schema1/01_schema.sql | ||
---|---|---|
1 |
DROP SCHEMA IF EXISTS schema1 cascade; |
|
2 | ||
3 |
CREATE SCHEMA schema1; |
|
4 | ||
5 |
SET search_path = schema1; |
|
6 | ||
7 |
CREATE TABLE category ( |
|
8 |
id serial primary key, |
|
9 |
ord integer default(0) not null, |
|
10 |
label varchar not null); |
|
11 | ||
12 |
CREATE TABLE subcategory ( |
|
13 |
id serial primary key, |
|
14 |
category_id integer not null references schema1.category(id), |
|
15 |
ord integer default(0) not null, |
|
16 |
label varchar not null); |
|
17 | ||
18 |
CREATE TABLE facts ( |
|
19 |
id serial primary key, |
|
20 |
date date, |
|
21 |
datetime timestamp with time zone, |
|
22 |
integer integer, |
|
23 |
cnt integer default(1), |
|
24 |
innersubcategory_id integer references schema1.subcategory(id), |
|
25 |
leftsubcategory_id integer references schema1.subcategory(id), |
|
26 |
rightsubcategory_id integer references schema1.subcategory(id), |
|
27 |
outersubcategory_id integer references schema1.subcategory(id) |
|
28 |
); |
|
29 | ||
30 |
INSERT INTO category (ord, label) VALUES |
|
31 |
(1, 'caté1'), |
|
32 |
(0, 'caté2'), |
|
33 |
(0, 'caté3'); |
|
34 | ||
35 |
INSERT INTO subcategory (category_id, ord, label) VALUES |
|
36 |
(1, 1, 'subé1'), |
|
37 |
(1, 0, 'subé2'), |
|
38 |
(1, 0, 'subé3'), |
|
39 |
(2, 0, 'subé4'), |
|
40 |
(2, 0, 'subé5'), |
|
41 |
(2, 0, 'subé6'), |
|
42 |
(3, 1, 'subé7'), |
|
43 |
(3, 0, 'subé8'), |
|
44 |
(3, 0, 'subé9'); |
|
45 | ||
46 | ||
47 |
INSERT INTO facts (date, datetime, integer, cnt, innersubcategory_id, leftsubcategory_id, rightsubcategory_id, outersubcategory_id) VALUES |
|
48 |
('2017-01-01', '2017-01-01 10:00', 1, 10, 1, 1, 1, 1), |
|
49 |
('2017-01-02', '2017-01-02 10:00', 1, 10, 3, 3, 3, 3), |
|
50 |
('2017-01-03', '2017-01-03 10:00', 1, 10, NULL, NULL, NULL, NULL), |
|
51 |
('2017-01-04', '2017-01-04 10:00', 1, 10, 1, 1, 1, 1), |
|
52 |
('2017-01-05', '2017-01-05 10:00', 1, 10, 1, 1, 1, 1), |
|
53 |
('2017-01-06', '2017-01-06 10:00', 1, 10, 1, 1, 1, 1), |
|
54 |
('2017-01-07', '2017-01-07 10:00', 1, 10, 1, 1, 1, 1), |
|
55 |
('2017-01-08', '2017-01-08 10:00', 1, 10, 1, 1, 1, 1), |
|
56 |
('2017-01-09', '2017-01-09 10:00', 1, 10, 1, 1, 1, 1), |
|
57 |
('2017-01-10', '2017-01-10 10:00', 1, 10, 1, 1, 1, 1), |
|
58 |
('2017-02-01', '2017-02-01 10:00', 1, 10, 1, 1, 1, 1), |
|
59 |
('2017-03-01', '2017-03-01 10:00', 1, 10, 1, 1, 1, 1), |
|
60 |
('2017-04-01', '2017-04-01 10:00', 1, 10, 1, 1, 1, 1), |
|
61 |
('2017-05-01', '2017-05-01 10:00', 1, 10, 1, 1, 1, 1), |
|
62 |
('2017-06-01', '2017-06-01 10:00', 1, 10, 1, 1, 1, 1), |
|
63 |
('2017-07-01', '2017-07-01 10:00', 1, 10, 1, 1, 1, 1), |
|
64 |
('2017-08-01', '2017-08-01 10:00', 1, 10, 1, 1, 1, 1); |
tests/fixtures/schema1/schema.json | ||
---|---|---|
1 |
{ |
|
2 |
"name": "schema1", |
|
3 |
"label": "test schema1", |
|
4 |
"pg_dsn": "fixme", |
|
5 |
"search_path": ["schema1"], |
|
6 |
"cubes": [ |
|
7 |
{ |
|
8 |
"name": "facts1", |
|
9 |
"label": "Facts 1", |
|
10 |
"fact_table": "facts", |
|
11 |
"key": "id", |
|
12 |
"joins": [ |
|
13 |
{ |
|
14 |
"name": "innersubcategory", |
|
15 |
"table": "subcategory", |
|
16 |
"master": "innersubcategory_id", |
|
17 |
"detail": "id", |
|
18 |
"kind": "inner" |
|
19 |
}, |
|
20 |
{ |
|
21 |
"name": "leftsubcategory", |
|
22 |
"table": "subcategory", |
|
23 |
"master": "leftsubcategory_id", |
|
24 |
"detail": "id", |
|
25 |
"kind": "left" |
|
26 |
}, |
|
27 |
{ |
|
28 |
"name": "rightsubcategory", |
|
29 |
"table": "subcategory", |
|
30 |
"master": "rightsubcategory_id", |
|
31 |
"detail": "id", |
|
32 |
"kind": "right" |
|
33 |
}, |
|
34 |
{ |
|
35 |
"name": "outersubcategory", |
|
36 |
"table": "subcategory", |
|
37 |
"master": "outersubcategory_id", |
|
38 |
"detail": "id", |
|
39 |
"kind": "full" |
|
40 |
}, |
|
41 |
{ |
|
42 |
"name": "innercategory", |
|
43 |
"table": "category", |
|
44 |
"master": "innersubcategory.category_id", |
|
45 |
"detail": "id", |
|
46 |
"kind": "inner" |
|
47 |
}, |
|
48 |
{ |
|
49 |
"name": "leftcategory", |
|
50 |
"table": "category", |
|
51 |
"master": "leftsubcategory.category_id", |
|
52 |
"detail": "id", |
|
53 |
"kind": "left" |
|
54 |
}, |
|
55 |
{ |
|
56 |
"name": "rightcategory", |
|
57 |
"table": "category", |
|
58 |
"master": "rightsubcategory.category_id", |
|
59 |
"detail": "id", |
|
60 |
"kind": "right" |
|
61 |
}, |
|
62 |
{ |
|
63 |
"name": "outercategory", |
|
64 |
"table": "category", |
|
65 |
"master": "outersubcategory.category_id", |
|
66 |
"detail": "id", |
|
67 |
"kind": "full" |
|
68 |
} |
|
69 |
], |
|
70 |
"dimensions": [ |
|
71 |
{ |
|
72 |
"name": "innersubcategory", |
|
73 |
"label": "Inner SubCategory", |
|
74 |
"type": "integer", |
|
75 |
"join": ["innercategory", "innersubcategory"], |
|
76 |
"value": "innersubcategory.id", |
|
77 |
"value_label": "innersubcategory.label" |
|
78 |
}, |
|
79 |
{ |
|
80 |
"name": "leftsubcategory", |
|
81 |
"label": "Left SubCategory", |
|
82 |
"type": "integer", |
|
83 |
"join": ["leftcategory", "leftsubcategory"], |
|
84 |
"value": "leftsubcategory.id", |
|
85 |
"value_label": "leftsubcategory.label" |
|
86 |
}, |
|
87 |
{ |
|
88 |
"name": "rightsubcategory", |
|
89 |
"label": "Right SubCategory", |
|
90 |
"type": "integer", |
|
91 |
"join": ["rightcategory", "rightsubcategory"], |
|
92 |
"value": "rightsubcategory.id", |
|
93 |
"value_label": "rightsubcategory.label" |
|
94 |
}, |
|
95 |
{ |
|
96 |
"name": "outersubcategory", |
|
97 |
"label": "Outer SubCategory", |
|
98 |
"type": "integer", |
|
99 |
"join": ["outercategory", "outersubcategory"], |
|
100 |
"value": "outersubcategory.id", |
|
101 |
"value_label": "outersubcategory.label" |
|
102 |
}, |
|
103 |
{ |
|
104 |
"name": "innercategory", |
|
105 |
"label": "Inner Category", |
|
106 |
"type": "integer", |
|
107 |
"join": ["innersubcategory", "innercategory"], |
|
108 |
"value": "innercategory.id", |
|
109 |
"value_label": "innercategory.label" |
|
110 |
}, |
|
111 |
{ |
|
112 |
"name": "leftcategory", |
|
113 |
"label": "Left Category", |
|
114 |
"type": "integer", |
|
115 |
"join": ["leftsubcategory", "leftcategory"], |
|
116 |
"value": "leftcategory.id", |
|
117 |
"value_label": "leftcategory.label" |
|
118 |
}, |
|
119 |
{ |
|
120 |
"name": "rightcategory", |
|
121 |
"label": "Right Category", |
|
122 |
"type": "integer", |
|
123 |
"join": ["rightsubcategory", "rightcategory"], |
|
124 |
"value": "rightcategory.id", |
|
125 |
"value_label": "rightcategory.label" |
|
126 |
}, |
|
127 |
{ |
|
128 |
"name": "outercategory", |
|
129 |
"label": "Outer Category", |
|
130 |
"type": "integer", |
|
131 |
"join": ["outersubcategory", "outercategory"], |
|
132 |
"value": "outercategory.id", |
|
133 |
"value_label": "outercategory.label" |
|
134 |
} |
|
135 |
], |
|
136 |
"measures": [ |
|
137 |
{ |
|
138 |
"name": "simple_count", |
|
139 |
"label": "number of rows", |
|
140 |
"type": "integer", |
|
141 |
"expression": "count({fact_table}.id)" |
|
142 |
}, |
|
143 |
{ |
|
144 |
"name": "aggregated_count", |
|
145 |
"label": "sum of cnt", |
|
146 |
"type": "integer", |
|
147 |
"expression": "sum(cnt)" |
|
148 |
}, |
|
149 |
{ |
|
150 |
"name": "percent", |
|
151 |
"label": "pourcentage des demandes", |
|
152 |
"type": "percent", |
|
153 |
"expression": "case (select count({fact_table}.id) from {table_expression} where {where_conditions}) when 0 then null else count({fact_table}.id) * 100. / (select count({fact_table}.id) from {table_expression} where {where_conditions}) end" |
|
154 |
} |
|
155 |
] |
|
156 |
} |
|
157 |
] |
|
158 |
} |
tests/test_schema1.py | ||
---|---|---|
1 |
# -*- coding: utf-8 -*- |
|
2 | ||
3 |
from utils import login |
|
4 | ||
5 |
def get_table(response): |
|
6 |
table = [] |
|
7 | ||
8 |
for tr in response.pyquery('table tr'): |
|
9 |
row = [] |
|
10 |
table.append(row) |
|
11 |
for td in tr.findall('td'): |
|
12 |
row.append(td.text.strip()) |
|
13 |
return table |
|
14 | ||
15 |
def test_simple(schema1, app, admin): |
|
16 |
login(app, admin) |
|
17 |
response = app.get('/').follow() |
|
18 |
response = response.click('Facts 1') |
|
19 |
assert 'big-msg-info' in response |
|
20 |
form = response.form |
|
21 |
form.set('representation', 'table') |
|
22 |
form.set('measure', 'simple_count') |
|
23 |
form.set('drilldown_x', 'innersubcategory') |
|
24 |
response = form.submit('visualize') |
|
25 |
assert 'big-msg-info' not in response |
|
26 |
assert get_table(response) == [ |
|
27 |
[u'Inner SubCategory', u'subé1', u'subé3'], |
|
28 |
['number of rows', '15', '1'], |
|
29 |
] |
tox.ini | ||
---|---|---|
26 | 26 |
pytest-django |
27 | 27 |
WebTest |
28 | 28 |
django-webtest<1.9.3 |
29 |
sqlparse |
|
30 |
pyquery |
|
29 | 31 |
commands = |
30 | 32 |
dj111: py.test {posargs: --junitxml=test_{envname}_results.xml --cov-report xml --cov-report html --cov=bijoe --random tests/} |
31 | 33 |
dj18: py.test {posargs: --junitxml=test_{envname}_results.xml --random tests/} |
32 |
- |