diff --git a/openhtf/core/test_state.py b/openhtf/core/test_state.py index ae17f54bb..627196640 100644 --- a/openhtf/core/test_state.py +++ b/openhtf/core/test_state.py @@ -24,6 +24,7 @@ invokation of an openhtf.Test instance. """ +import collections import contextlib import copy import logging @@ -338,9 +339,10 @@ def from_descriptor(cls, phase_desc, notify_cb): return cls( phase_desc.name, test_record.PhaseRecord.from_descriptor(phase_desc), - {measurement.name: - copy.deepcopy(measurement).set_notification_callback(notify_cb) - for measurement in phase_desc.measurements}, + collections.OrderedDict( + (measurement.name, + copy.deepcopy(measurement).set_notification_callback(notify_cb)) + for measurement in phase_desc.measurements), phase_desc.options) def _asdict(self): @@ -412,26 +414,15 @@ def _finalize_measurements(self): Any UNSET measurements will cause the Phase to FAIL unless conf.allow_unset_measurements is set True. """ - # Clear notification callbacks for later serialization. - for meas in self.measurements.values(): - meas.set_notification_callback(None) - - # Initialize with already-validated and UNSET measurements. - validated_measurements = { - name: measurement - for name, measurement in self.measurements.iteritems() - if measurement.outcome is not measurements.Outcome.PARTIALLY_SET - } - - # Validate multi-dimensional measurements now that we have all values. - validated_measurements.update({ - name: measurement.validate() - for name, measurement in self.measurements.iteritems() - if measurement.outcome is measurements.Outcome.PARTIALLY_SET - }) - - # Fill out final values for the PhaseRecord. - self.phase_record.measurements = validated_measurements + for measurement in self.measurements.itervalues(): + # Clear notification callbacks for later serialization. + measurement.set_notification_callback(None) + # Validate multi-dimensional measurements now that we have all values. + if measurement.outcome is measurements.Outcome.PARTIALLY_SET: + measurement.validate() + + # Set final values on the PhaseRecord. + self.phase_record.measurements = self.measurements def _measurements_pass(self): allowed_outcomes = {measurements.Outcome.PASS} diff --git a/openhtf/output/callbacks/console_summary.py b/openhtf/output/callbacks/console_summary.py index a1c08c6ba..988a5ec5f 100644 --- a/openhtf/output/callbacks/console_summary.py +++ b/openhtf/output/callbacks/console_summary.py @@ -44,22 +44,19 @@ def __call__(self, record): new_phase = True phase_time_sec = (float(phase.end_time_millis) - float(phase.start_time_millis)) / 1000.0 - measured = phase.measured_values - measurements = phase.measurements - for key in measurements: - result = measurements[key] - if result.outcome == meas_module.Outcome.FAIL: + for name, measurement in phase.measurements.iteritems(): + if measurement.outcome == meas_module.Outcome.FAIL: if new_phase: output_lines.append('failed phase: %s [ran for %.2f sec]' % (phase.name, phase_time_sec)) new_phase = False output_lines.append('%sfailed_item: %s' % - (self.indent, result.name)) + (self.indent, name)) output_lines.append('%smeasured_value: %s' % - (self.indent*2, str(measured[result.name]))) + (self.indent*2, measurement.measured_value)) output_lines.append('%svalidators:' % (self.indent*2)) - for validator in result.validators: + for validator in measurement.validators: output_lines.append('%svalidator: %s' % (self.indent*3, str(validator))) diff --git a/test/core/measurements_test.py b/test/core/measurements_test.py index c58235682..c2c7c7314 100644 --- a/test/core/measurements_test.py +++ b/test/core/measurements_test.py @@ -68,3 +68,13 @@ def test_validator_replacement(self): self.assertMeasurementPass(record, 'replaced_min_only') self.assertMeasurementFail(record, 'replaced_max_only') self.assertMeasurementFail(record, 'replaced_min_max') + + @htf_test.yields_phases + def test_measurement_order(self): + record = yield all_the_things.dimensions + self.assertEqual(record.measurements.keys(), + ['unset_dims', 'dimensions', 'lots_of_dims']) + record = yield all_the_things.measures_with_args.with_args(min=2, max=4) + self.assertEqual(record.measurements.keys(), + ['replaced_min_only', 'replaced_max_only', + 'replaced_min_max'])