Skip to content

Commit a0a20ea

Browse files
committed
Merge pull request #2825 from m-kuhn/processingTestFiles
Add file comparison for HTML output to processing
2 parents 4c63c85 + 23802eb commit a0a20ea

File tree

7 files changed

+83
-20
lines changed

7 files changed

+83
-20
lines changed

python/plugins/processing/algs/qgis/BasicStatisticsNumbers.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,10 @@ def processAlgorithm(self, progress):
186186

187187
def createHTML(self, outputFile, algData):
188188
f = codecs.open(outputFile, 'w', encoding='utf-8')
189-
f.write('<html><head>')
189+
f.write('<html><head>\n')
190190
f.write('<meta http-equiv="Content-Type" content="text/html; \
191-
charset=utf-8" /></head><body>')
191+
charset=utf-8" /></head><body>\n')
192192
for s in algData:
193-
f.write('<p>' + unicode(s) + '</p>')
194-
f.write('</body></html>')
193+
f.write('<p>' + unicode(s) + '</p>\n')
194+
f.write('</body></html>\n')
195195
f.close()

python/plugins/processing/algs/qgis/BasicStatisticsStrings.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,10 @@ def processAlgorithm(self, progress):
145145

146146
def createHTML(self, outputFile, algData):
147147
f = codecs.open(outputFile, 'w', encoding='utf-8')
148-
f.write('<html><head>')
148+
f.write('<html><head>\n')
149149
f.write('<meta http-equiv="Content-Type" content="text/html; \
150-
charset=utf-8" /></head><body>')
150+
charset=utf-8" /></head><body>\n')
151151
for s in algData:
152-
f.write('<p>' + unicode(s) + '</p>')
152+
f.write('<p>' + unicode(s) + '</p>\n')
153153
f.write('</body></html>')
154154
f.close()

python/plugins/processing/gui/TestTools.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
OutputNumber,
4141
OutputString,
4242
OutputRaster,
43-
OutputVector
43+
OutputVector,
44+
OutputHTML
4445
)
4546

4647
from processing.core.parameters import (
@@ -156,8 +157,8 @@ def createTest(text):
156157

157158
definition['params'] = params
158159

159-
for i, out in enumerate(alg.outputs):
160-
token = tokens[i - len(alg.outputs)]
160+
for i, out in enumerate([out for out in alg.outputs if not out.hidden]):
161+
token = tokens[i - alg.getVisibleOutputsCount()]
161162

162163
if isinstance(out, (OutputNumber, OutputString)):
163164
results[out.name] = unicode(out)
@@ -179,6 +180,15 @@ def createTest(text):
179180
}
180181
if not schema:
181182
results[out.name]['location'] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]'
183+
elif isinstance(out, OutputHTML):
184+
filename = token[1:-1]
185+
schema, filepath = extractSchemaPath(filename)
186+
results[out.name] = {
187+
'type': 'file',
188+
'name': filepath
189+
}
190+
if not schema:
191+
results[out.name]['location'] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]'
182192

183193
definition['results'] = results
184194

python/plugins/processing/tests/AlgorithmsTest.py

+18-10
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,10 @@ def load_param(self, param):
137137

138138
def load_result_param(self, param):
139139
"""
140-
Lodas a result parameter. Creates a temporary destination where the result should go to and returns this location
140+
Loads a result parameter. Creates a temporary destination where the result should go to and returns this location
141141
so it can be sent to the algorithm as parameter.
142142
"""
143-
if param['type'] == 'vector':
143+
if param['type'] in ['vector', 'file']:
144144
outdir = tempfile.mkdtemp()
145145
self.cleanup_paths.append(outdir)
146146
basename = os.path.basename(param['name'])
@@ -153,14 +153,7 @@ def load_layer(self, param):
153153
"""
154154
Loads a layer which was specified as parameter.
155155
"""
156-
prefix = processingTestDataPath()
157-
try:
158-
if param['location'] == 'qgs':
159-
prefix = unitTestDataPath()
160-
except KeyError:
161-
pass
162-
163-
filepath = os.path.join(prefix, param['name'])
156+
filepath = self.filepath_from_param(param)
164157

165158
if param['type'] == 'vector':
166159
lyr = QgsVectorLayer(filepath, param['name'], 'ogr')
@@ -171,6 +164,16 @@ def load_layer(self, param):
171164
QgsMapLayerRegistry.instance().addMapLayer(lyr)
172165
return lyr
173166

167+
def filepath_from_param(self, param):
168+
"""
169+
Creates a filepath from a param
170+
"""
171+
prefix = processingTestDataPath()
172+
if 'location' in param and param['location'] == 'qgs':
173+
prefix = unitTestDataPath()
174+
175+
return os.path.join(prefix, param['name'])
176+
174177
def check_results(self, results, expected):
175178
"""
176179
Checks if result produced by an algorithm matches with the expected specification.
@@ -197,6 +200,11 @@ def check_results(self, results, expected):
197200
strhash = hashlib.sha224(dataset.ReadAsArray(0).data).hexdigest()
198201

199202
self.assertEqual(strhash, expected_result['hash'])
203+
elif 'file' == expected_result['type']:
204+
expected_filepath = self.filepath_from_param(expected_result)
205+
result_filepath = results[id]
206+
207+
self.assertFilesEqual(expected_filepath, result_filepath)
200208

201209

202210
if __name__ == '__main__':

python/plugins/processing/tests/testdata/algorithm_tests.yaml

+10
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,13 @@ tests:
6363
OUTPUT:
6464
name: expected/polys_to_lines.gml
6565
type: vector
66+
- algorithm: qgis:basicstatisticsfornumericfields
67+
name: Test (qgis:basicstatisticsfornumericfields)
68+
params:
69+
- name: multipolys.gml
70+
type: vector
71+
- 'Bfloatval'
72+
results:
73+
OUTPUT_HTML_FILE:
74+
name: expected/basic_statistics_numeric_float.html
75+
type: file
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<html><head>
2+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body>
3+
<p>Analyzed layer: multipolys.gml</p>
4+
<p>Analyzed field: Bfloatval</p>
5+
<p>Count: 3</p>
6+
<p>Unique values: 3</p>
7+
<p>Minimum value: -0.123</p>
8+
<p>Maximum value: 0.123</p>
9+
<p>Range: 0.246</p>
10+
<p>Sum: 0.0</p>
11+
<p>Mean value: 0.0</p>
12+
<p>Median value: 0.0</p>
13+
<p>Standard deviation: 0.100429079454</p>
14+
<p>Coefficient of Variation: 0</p>
15+
<p>Minority (rarest occurring value): -0.123</p>
16+
<p>Majority (most frequently occurring value): -0.123</p>
17+
<p>First quartile: -0.0615</p>
18+
<p>Third quartile: 0.0615</p>
19+
<p>NULL (missed) values: 1</p>
20+
<p>Interquartile Range (IQR): 0.123</p>
21+
</body></html>

python/testing/__init__.py

+14
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import os
2929
import sys
30+
import difflib
3031

3132
from PyQt4.QtCore import QVariant
3233
from qgis.core import QgsApplication, QgsFeatureRequest, QgsVectorLayer
@@ -140,6 +141,19 @@ def assertLayersEqual(self, layer_expected, layer_result, **kwargs):
140141
)
141142
)
142143

144+
def assertFilesEqual(self, filepath_expected, filepath_result):
145+
with open(filepath_expected, 'r') as file_expected:
146+
with open(filepath_result, 'r') as file_result:
147+
diff = difflib.unified_diff(
148+
file_expected.readlines(),
149+
file_result.readlines(),
150+
fromfile='expected',
151+
tofile='result',
152+
)
153+
diff = list(diff)
154+
self.assertEqual(0, len(diff), ''.join(diff))
155+
156+
143157
# Patch unittest
144158
unittest.TestCase = TestCase
145159

0 commit comments

Comments
 (0)