Skip to content

Commit f83b903

Browse files
author
NyanKiyoshi
authored
Merge pull request #26 from NyanKiyoshi/feature/backup-results
Implement the backup command
2 parents f09b430 + 609f205 commit f83b903

File tree

9 files changed

+188
-13
lines changed

9 files changed

+188
-13
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
venv/
33
*.pyc
44
*.egg-info/
5+
*wheel*
56
.pytest*
67
.coverage
78
*cov/

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ You will find the [full documentation here](https://pytest-django-queries.readth
6161

6262
## Integrating with GitHub
6363

64+
TBA.
65+
6466
## Testing locally
6567
Simply install `pytest-django-queries` through pip and run your
6668
tests using `pytest`. A report should have been generated in your
@@ -106,6 +108,13 @@ django-queries html > results.html
106108

107109
## Comparing results
108110

111+
When running pytest, pass the `--django-backup-queries` (can take a path, optionally)
112+
then you can run `django-queries diff` to generate results looking like this:
113+
114+
<a href='./docs/_static/diff_results.png'>
115+
<img src='./docs/_static/diff_results.png' alt='screenshot' width='500px' />
116+
</a>
117+
109118
## Development
110119
First of all, clone the project locally. Then, install it using the below command.
111120

docs/diff.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,11 @@
22

33
The Diff Command
44
----------------
5+
6+
The plugin can backup the test results for you if you pass the ``--django-backup-queries [BACKUP_PATH]`` parameter to it. It will create a backup to ``.pytest-query.old`` by default if previous results were found.
7+
8+
.. warning::
9+
10+
Bear in mind that it will override any existing backup file in the provided or default path.
11+
12+
After running ``pytest --django-backup-queries``, you can run ``django-queries diff`` to show the changes. Make sure you actually had previous results, otherwise it will have nothing to compare.

docs/index.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ Quick Start
2929
def test_another_query_performances(count_queries):
3030
Model.objects.all()
3131
32-
3. Then use ``django-queries show`` to show the results directly into your console:
32+
3. Run ``pytest``;
33+
4. Then use ``django-queries show`` to show the results directly into your console:
3334

3435
.. code-block:: text
3536
@@ -53,13 +54,13 @@ Quick Start
5354
| module3 | |
5455
+---------+-------------------------+
5556
56-
4. Or for a nicer presentation, use ``django-queries html > results.html`` to export the results as HTML. See `this example <./html_export_results.html>`_ for a demo!
57+
5. Or for a nicer presentation, use ``django-queries html > results.html`` to export the results as HTML. See `this example <./html_export_results.html>`_ for a demo!
5758

5859
.. image:: _static/html_export_results.png
5960
:width: 500 px
6061
:align: center
6162

62-
5. By running it twice with the option described :ref:`here <diff_usage>` and by running ``django-queries diff`` you will get something like this:
63+
6. By running it twice with the option described :ref:`here <diff_usage>` and by running ``django-queries diff`` you will get something like this:
6364

6465
.. image:: _static/diff_results.png
6566
:width: 500 px

docs/usage.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
Plugin Usage
2+
============
3+
4+
The plugin supports some optional parameters that are defined below.
5+
6+
Customizing the Save Path
7+
+++++++++++++++++++++++++
8+
9+
.. code-block:: text
10+
11+
--django-db-bench=PATH
12+
Output file for storing the results. Default: .pytest-queries
13+
14+
15+
Backing Up Results
16+
++++++++++++++++++
17+
18+
You can pass the ``--django-backup-queries`` parameter to backup previous results to `.pytest-django.old``.
19+
20+
Or pass a custom path.
21+
22+
.. code-block:: text
23+
24+
--django-backup-queries=[PATH]
25+
Whether the old results should be backed up or not before overriding.
26+
27+
128
CLI Usage
229
=========
330

pytest_django_queries/plugin.py

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import json
2+
import shutil
3+
from os.path import isfile
24

35
import pytest
46
from django.test.utils import CaptureQueriesContext
@@ -17,16 +19,31 @@ def _get_session(request):
1719
return request.config.pytest_django_queries_session
1820

1921

22+
def _create_backup(save_path, backup_path):
23+
shutil.copy(save_path, backup_path)
24+
25+
2026
class _Session(object):
21-
def __init__(self, save_path):
27+
def __init__(self, save_path, backup_path):
28+
"""
29+
:param save_path:
30+
:type save_path: str
31+
32+
:param backup_path:
33+
:type backup_path: bool
34+
"""
2235
self.save_path = save_path
36+
self.backup_path = backup_path
2337
self._data = {}
2438

2539
def add_entry(self, module_name, test_name, query_count):
2640
module_data = self._data.setdefault(module_name, {})
2741
module_data[test_name] = {"query-count": query_count}
2842

2943
def save_json(self):
44+
if self.backup_path and isfile(self.save_path):
45+
_create_backup(self.save_path, self.backup_path)
46+
3047
with open(self.save_path, "w") as fp:
3148
json.dump(self._data, fp, indent=2)
3249

@@ -49,6 +66,15 @@ def pytest_addoption(parser):
4966
metavar="PATH",
5067
help="Output file for storing the results. Default: .pytest-queries",
5168
)
69+
group.addoption(
70+
"--django-backup-queries",
71+
dest="queries_backup_results",
72+
action="store",
73+
default=None,
74+
metavar="PATH",
75+
help="Whether the old results should be backed up or not before overriding",
76+
nargs="?",
77+
)
5278

5379

5480
@pytest.mark.tryfirst
@@ -63,10 +89,21 @@ def pytest_configure(config):
6389

6490
@pytest.mark.tryfirst
6591
def pytest_load_initial_conftests(early_config, parser, args):
66-
_set_session(
67-
early_config,
68-
_Session(early_config.known_args_namespace.queries_results_save_path),
69-
)
92+
"""
93+
:param early_config:
94+
:param parser:
95+
:param args:
96+
:type args: tuple|list
97+
:return:
98+
"""
99+
save_path = early_config.known_args_namespace.queries_results_save_path
100+
backup_path = early_config.known_args_namespace.queries_backup_results
101+
102+
# Set default value if the flag was provided without value in arguments
103+
if backup_path is None and "--django-backup-queries" in args:
104+
backup_path = DEFAULT_OLD_RESULT_FILENAME
105+
106+
_set_session(early_config, _Session(save_path, backup_path))
70107

71108

72109
@pytest.hookimpl(hookwrapper=True)

requirements_dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ lxml
33
sphinx
44
sphinx_rtd_theme
55
pre-commit
6+
mock

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,4 @@ include_trailing_comma: True
5858

5959
line_length = 88
6060
known_first_party = pytest_django_queries
61-
known_third_party =beautifultable,bs4,click,django,jinja2,pytest,setuptools
61+
known_third_party =beautifultable,bs4,click,django,jinja2,mock,pytest,setuptools

tests/test_plugin.py

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import json
22

3+
import mock
4+
35
DUMMY_TEST_QUERY = """
46
import pytest
57
@@ -25,7 +27,7 @@ def test_fixture_is_invoked_when_marked(testdir):
2527

2628
# Run a dummy test that performs queries
2729
# and triggers a counting of the query number
28-
testdir.makepyfile(DUMMY_TEST_QUERY)
30+
testdir.makepyfile(test_file=DUMMY_TEST_QUERY)
2931
results = testdir.runpytest("--django-db-bench", results_path)
3032

3133
# Ensure the tests have passed
@@ -34,9 +36,7 @@ def test_fixture_is_invoked_when_marked(testdir):
3436
# Ensure the results file was created
3537
assert results_path.check()
3638
assert json.load(results_path) == {
37-
"test_fixture_is_invoked_when_marked": {
38-
"test_count_db_query_number": {"query-count": 2}
39-
}
39+
"test_file": {"test_count_db_query_number": {"query-count": 2}}
4040
}
4141

4242

@@ -94,6 +94,94 @@ def test_failure():
9494
}
9595

9696

97+
def test_fixture_is_backing_up_old_results(testdir):
98+
"""Ensure marking a test is backing up old results if asked to."""
99+
results_path = testdir.tmpdir.join("results.json")
100+
old_results_path = testdir.tmpdir.join("results.old.json")
101+
102+
# Run a dummy test that performs queries
103+
# and triggers a counting of the query number
104+
testdir.makepyfile(test_file=DUMMY_TEST_QUERY)
105+
106+
results = testdir.runpytest(
107+
"--django-db-bench", results_path, "--django-backup-queries", old_results_path
108+
)
109+
110+
# Ensure the tests have passed
111+
results.assert_outcomes(1, 0, 0)
112+
113+
# Ensure the results file was created
114+
assert results_path.check()
115+
assert (
116+
not old_results_path.check()
117+
), "Nothing should have been backed up--there was nothing to back up"
118+
119+
# Create another test to generate more results,
120+
# to ensure the backup results were actually the previous ones
121+
testdir.makepyfile(test_otherfile=DUMMY_TEST_QUERY)
122+
123+
# Run again the tests
124+
results = testdir.runpytest(
125+
"--django-db-bench", results_path, "--django-backup-queries", old_results_path
126+
)
127+
128+
# Ensure the tests have passed
129+
results.assert_outcomes(2, 0, 0)
130+
131+
# Ensure the results file was created
132+
assert results_path.check()
133+
assert old_results_path.check(), "The backup file should have been created"
134+
135+
# Check contents
136+
assert json.load(results_path) == {
137+
"test_file": {"test_count_db_query_number": {"query-count": 2}},
138+
"test_otherfile": {"test_count_db_query_number": {"query-count": 2}},
139+
}
140+
assert json.load(old_results_path) == {
141+
"test_file": {"test_count_db_query_number": {"query-count": 2}}
142+
}
143+
144+
145+
def test_fixture_is_not_backing_up_if_not_asked_to(testdir):
146+
"""Ensure marking a test is backing up old results if asked to."""
147+
results_path = testdir.tmpdir.join("results.json")
148+
results_path.ensure(file=True) # 'touch' the file
149+
150+
# Run a dummy test that performs queries
151+
# and triggers a counting of the query number
152+
testdir.makepyfile(test_file=DUMMY_TEST_QUERY)
153+
154+
with mock.patch("pytest_django_queries.plugin._create_backup") as mocked_backup:
155+
results = testdir.runpytest("--django-db-bench", results_path)
156+
assert mocked_backup.call_count == 0
157+
158+
# Ensure the tests have passed
159+
results.assert_outcomes(1, 0, 0)
160+
assert results_path.check()
161+
162+
163+
def test_fixture_is_backing_up_old_results_to_default_path_if_no_path_provided(testdir):
164+
"""Ensure marking a test is backing up old results if asked to."""
165+
results_path = testdir.tmpdir.join("results.json")
166+
results_path.ensure(file=True) # 'touch' the file
167+
168+
# Run a dummy test that performs queries
169+
# and triggers a counting of the query number
170+
testdir.makepyfile(test_file=DUMMY_TEST_QUERY)
171+
172+
with mock.patch("pytest_django_queries.plugin._create_backup") as mocked_backup:
173+
from pytest_django_queries.plugin import DEFAULT_OLD_RESULT_FILENAME
174+
175+
results = testdir.runpytest(
176+
"--django-db-bench", results_path, "--django-backup-queries"
177+
)
178+
mocked_backup.assert_called_with(str(results_path), DEFAULT_OLD_RESULT_FILENAME)
179+
180+
# Ensure the tests have passed
181+
results.assert_outcomes(1, 0, 0)
182+
assert results_path.check()
183+
184+
97185
def test_marker_message(testdir):
98186
"""Ensure the custom markers configuration is added to pytest."""
99187
result = testdir.runpytest("--markers")
@@ -114,5 +202,8 @@ def test_implements_custom_options(testdir):
114202
"*--django-db-bench=PATH",
115203
"*Output file for storing the results. Default: .pytest-",
116204
"*queries",
205+
"*--django-backup-queries=[[]PATH[]]",
206+
"*Whether the old results should be backed up or not",
207+
"*before overriding",
117208
]
118209
)

0 commit comments

Comments
 (0)