Projet

Général

Profil

0003-tests-add-real-ones-with-fixtures-fixes-27482.patch

Benjamin Dauvergne, 20 novembre 2018 15:33

Télécharger (13,5 ko)

Voir les différences:

Subject: [PATCH 3/3] tests: add real ones with fixtures (fixes #27482)

 tests/conftest.py                    |  65 ++++++++++-
 tests/fixtures/schema1/01_schema.sql |  64 +++++++++++
 tests/fixtures/schema1/schema.json   | 158 +++++++++++++++++++++++++++
 tests/test_schema1.py                |  29 +++++
 tox.ini                              |   2 +
 5 files changed, 317 insertions(+), 1 deletion(-)
 create mode 100644 tests/fixtures/schema1/01_schema.sql
 create mode 100644 tests/fixtures/schema1/schema.json
 create mode 100644 tests/test_schema1.py
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
-