Repository: pywbem/pywbemtools (language: python)

Issue:
Fixes issue #1070, Sphinx fails python 2.7
Fixes an issue where Sphinx fails with python < 3.5 because of an update
to docutils to 0.18. Limited docutils for python 3.5.

We also set some of the Sphinx limits from pywbem dev_requirements.txt.


Discussion / hints:

[![Coverage Status](https://coveralls.io/builds/44278211/badge)](https://coveralls.io/builds/44278211)

Coverage remained the same at 92.929% when pulling **f031e52fd2c41051d1fe3b416963084cde8eafab on ks/#1070-fix-Sphinx-PY2** into **4e1fdf361e7b66e9eeadcceb0ef38585ad58c7dd on master**.


Fix patch:
diff --git a/docs/changes.rst b/docs/changes.rst
index 8a75d298..4751b5fb 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -62,6 +62,10 @@ Released: not yet
 
 * Remove deprecated commands ``server namespaces`` and ``server interop``.
 
+* Fixed tests that fail because XML output of classes and qualifier declarations
+  return attributes not ordered before python version 3.8. (see issue #1173).
+
+
 **Known issues:**
 
 * See `list of open issues`_.


Test patch:
diff --git a/tests/unit/pywbemcli/test_class_cmds.py b/tests/unit/pywbemcli/test_class_cmds.py
index ccd8edaa..87074277 100644
--- a/tests/unit/pywbemcli/test_class_cmds.py
+++ b/tests/unit/pywbemcli/test_class_cmds.py
@@ -46,8 +46,10 @@
 # pywbem 1.0.0 or later
 PYWBEM_1_0_0 = _PYWBEM_VERSION.release >= (1, 0, 0)
 
-# Create variable that is True if python version ge 3.6
-PYTHON_GE_36 = sys.version_info > (3, 6)
+# Create variable that is True if python ge version 3.8.  This python version
+# was the first to impose ordering on XML attributes. Without ordering
+# XML tests against XML data returned from pywbemcli can fail. See issue #1173
+PYTHON_GE_38 = sys.version_info > (3, 8)
 
 # Mock scripts with setup() function are supported
 MOCK_SETUP_SUPPORTED = sys.version_info >= (3, 5)
@@ -363,8 +365,253 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
     '   TST_Person REF member;',
     '};']
 
+# pylint: disable=line-too-long
+# This output only valid for python versin ge 3.8
+ASSOCIATORS_CLASS_XML_GE_38 = """<CLASSPATH>
+    <NAMESPACEPATH>
+        <HOST>FakedUrl:5988</HOST>
+        <LOCALNAMESPACEPATH>
+            <NAMESPACE NAME="root"/>
+            <NAMESPACE NAME="cimv2"/>
+        </LOCALNAMESPACEPATH>
+    </NAMESPACEPATH>
+    <CLASSNAME NAME="TST_Person"/>
+</CLASSPATH>
+
+<CLASS NAME="TST_Person">
+    <PROPERTY NAME="name" TYPE="string" PROPAGATED="false">
+        <QUALIFIER NAME="Key" TYPE="boolean" PROPAGATED="false" OVERRIDABLE="false" TOSUBCLASS="true">
+            <VALUE>TRUE</VALUE>
+        </QUALIFIER>
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>This is key prop</VALUE>
+        </QUALIFIER>
+    </PROPERTY>
+    <PROPERTY NAME="extraProperty" TYPE="string" PROPAGATED="false">
+        <VALUE>defaultvalue</VALUE>
+    </PROPERTY>
+    <PROPERTY NAME="gender" TYPE="uint16" PROPAGATED="false">
+        <QUALIFIER NAME="ValueMap" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true">
+            <VALUE.ARRAY>
+                <VALUE>1</VALUE>
+                <VALUE>2</VALUE>
+            </VALUE.ARRAY>
+        </QUALIFIER>
+        <QUALIFIER NAME="Values" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE.ARRAY>
+                <VALUE>female</VALUE>
+                <VALUE>male</VALUE>
+            </VALUE.ARRAY>
+        </QUALIFIER>
+    </PROPERTY>
+    <PROPERTY.ARRAY NAME="likes" TYPE="uint16" PROPAGATED="false">
+        <QUALIFIER NAME="ValueMap" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true">
+            <VALUE.ARRAY>
+                <VALUE>1</VALUE>
+                <VALUE>2</VALUE>
+            </VALUE.ARRAY>
+        </QUALIFIER>
+        <QUALIFIER NAME="Values" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE.ARRAY>
+                <VALUE>books</VALUE>
+                <VALUE>movies</VALUE>
+            </VALUE.ARRAY>
+        </QUALIFIER>
+    </PROPERTY.ARRAY>
+</CLASS>
+
+"""  # noqa: E501
+
+# This output only for python version ge 3.8. Contains qualifier output
+CIMFOO_SUB_SUB_WITH_QUALS_XML = """<CLASS NAME="CIM_Foo_sub_sub" SUPERCLASS="CIM_Foo_sub">
+    <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+        <VALUE>Subclass of CIM_Foo_sub</VALUE>
+    </QUALIFIER>
+    <PROPERTY NAME="cimfoo_sub_sub" TYPE="string" PROPAGATED="false"/>
+    <PROPERTY NAME="cimfoo_sub" TYPE="string" PROPAGATED="true"/>
+    <PROPERTY NAME="InstanceID" TYPE="string" PROPAGATED="true">
+        <QUALIFIER NAME="Key" TYPE="boolean" PROPAGATED="true" OVERRIDABLE="false" TOSUBCLASS="true">
+            <VALUE>TRUE</VALUE>
+        </QUALIFIER>
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>This is key property.</VALUE>
+        </QUALIFIER>
+    </PROPERTY>
+    <PROPERTY NAME="IntegerProp" TYPE="uint32" PROPAGATED="true">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>This is Uint32 property.</VALUE>
+        </QUALIFIER>
+    </PROPERTY>
+    <PROPERTY NAME="cimfoo_emb3" TYPE="string" PROPAGATED="true">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>Embedded instance property</VALUE>
+        </QUALIFIER>
+        <QUALIFIER NAME="EmbeddedInstance" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true">
+            <VALUE>CIM_FooEmb3</VALUE>
+        </QUALIFIER>
+    </PROPERTY>
+    <METHOD NAME="Method1" TYPE="uint32" PROPAGATED="false">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>Sample method with input and output parameters</VALUE>
+        </QUALIFIER>
+        <PARAMETER NAME="OutputParam2" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>FALSE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Response param 2</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+    </METHOD>
+    <METHOD NAME="Fuzzy" TYPE="uint32" PROPAGATED="true">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>Method with in and out parameters</VALUE>
+        </QUALIFIER>
+        <PARAMETER NAME="TestInOutParameter" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Define data to be returned in output parameter</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+        <PARAMETER.REFERENCE NAME="TestRef" REFERENCECLASS="CIM_FooRef1">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Test of ref in/out parameter</VALUE>
+            </QUALIFIER>
+        </PARAMETER.REFERENCE>
+        <PARAMETER NAME="OutputParam" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>FALSE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Rtns method name if exists on input</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+        <PARAMETER NAME="OutputRtnValue" TYPE="uint32">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Defines return value if provided.</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+    </METHOD>
+    <METHOD NAME="FuzzyStatic" TYPE="uint32" PROPAGATED="true">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>Static method with in and out parameters</VALUE>
+        </QUALIFIER>
+        <QUALIFIER NAME="Static" TYPE="boolean" PROPAGATED="true" OVERRIDABLE="false" TOSUBCLASS="true">
+            <VALUE>TRUE</VALUE>
+        </QUALIFIER>
+        <PARAMETER NAME="TestInOutParameter" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Define data to be returned in output parameter</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+        <PARAMETER.REFERENCE NAME="TestRef" REFERENCECLASS="CIM_Foo">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Test of ref in/out parameter</VALUE>
+            </QUALIFIER>
+        </PARAMETER.REFERENCE>
+        <PARAMETER NAME="OutputParam" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>FALSE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="OUT" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Rtns method name if exists on input</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+        <PARAMETER NAME="OutputRtnValue" TYPE="uint32">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Defines return value if provided.</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+        <PARAMETER NAME="cimfoo_emb1" TYPE="string">
+            <QUALIFIER NAME="IN" TYPE="boolean" OVERRIDABLE="false" TOSUBCLASS="true">
+                <VALUE>TRUE</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="Description" TYPE="string" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+                <VALUE>Embedded instance parameter</VALUE>
+            </QUALIFIER>
+            <QUALIFIER NAME="EmbeddedInstance" TYPE="string">
+                <VALUE>CIM_FooEmb1</VALUE>
+            </QUALIFIER>
+        </PARAMETER>
+    </METHOD>
+    <METHOD NAME="DeleteNothing" TYPE="string" PROPAGATED="true">
+        <QUALIFIER NAME="Description" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+            <VALUE>Method with no parameters but embedded instance return</VALUE>
+        </QUALIFIER>
+        <QUALIFIER NAME="EmbeddedInstance" TYPE="string" PROPAGATED="true" OVERRIDABLE="true" TOSUBCLASS="true">
+            <VALUE>CIM_FooEmb2</VALUE>
+        </QUALIFIER>
+    </METHOD>
+</CLASS>
+"""  # noqa: E501
 
-OK = False     # mark tests OK when they execute correctly
+CIMFOO_SUB_SUB_NO_QUALS_XML = """<CLASS NAME="CIM_Foo_sub_sub" SUPERCLASS="CIM_Foo_sub">
+    <PROPERTY NAME="cimfoo_sub_sub" TYPE="string" PROPAGATED="false"/>
+    <PROPERTY NAME="cimfoo_sub" TYPE="string" PROPAGATED="true"/>
+    <PROPERTY NAME="InstanceID" TYPE="string" PROPAGATED="true"/>
+    <PROPERTY NAME="IntegerProp" TYPE="uint32" PROPAGATED="true"/>
+    <PROPERTY NAME="cimfoo_emb3" TYPE="string" PROPAGATED="true"/>
+    <METHOD NAME="Method1" TYPE="uint32" PROPAGATED="false">
+        <PARAMETER NAME="OutputParam2" TYPE="string"/>
+    </METHOD>
+    <METHOD NAME="Fuzzy" TYPE="uint32" PROPAGATED="true">
+        <PARAMETER NAME="TestInOutParameter" TYPE="string"/>
+        <PARAMETER.REFERENCE NAME="TestRef" REFERENCECLASS="CIM_FooRef1"/>
+        <PARAMETER NAME="OutputParam" TYPE="string"/>
+        <PARAMETER NAME="OutputRtnValue" TYPE="uint32"/>
+    </METHOD>
+    <METHOD NAME="FuzzyStatic" TYPE="uint32" PROPAGATED="true">
+        <PARAMETER NAME="TestInOutParameter" TYPE="string"/>
+        <PARAMETER.REFERENCE NAME="TestRef" REFERENCECLASS="CIM_Foo"/>
+        <PARAMETER NAME="OutputParam" TYPE="string"/>
+        <PARAMETER NAME="OutputRtnValue" TYPE="uint32"/>
+        <PARAMETER NAME="cimfoo_emb1" TYPE="string"/>
+    </METHOD>
+    <METHOD NAME="DeleteNothing" TYPE="string" PROPAGATED="true"/>
+</CLASS>
+"""  # noqa E501
+# pylint: enable=line-too-long
+
+
+OK = True     # mark tests OK when they execute correctly
 RUN = True    # Mark OK = False and current test case being created RUN
 FAIL = False  # Any test currently FAILING or not tested yet
 
@@ -463,6 +710,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
 
     ['Verify class command enumerate CIM_Foo -no-qualifiers',
      ['enumerate', 'CIM_Foo_sub', '--no-qualifiers'],
+
      {'stdout': CIMFOO_SUB_SUB_NO_QUALS,
       'test': 'linesnows'},
      SIMPLE_MOCK_FILE, OK],
@@ -605,7 +853,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'lines'},
      SIMPLE_MOCK_FILE, OK],
 
-    ['Verify class command enumerate with repr output format).',
+    ['Verify class command enumerate with xml output format).',
      {'args': ['enumerate'],
       'general': ['--output-format', 'xml']},
      {'stdout': ['<CLASS( | .+ )NAME="CIM_Foo">',
@@ -615,6 +863,21 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'regex'},
      SIMPLE_MOCK_FILE, OK],
 
+    # Test output compare of all components but only python v 3.8*
+    ['Verify class command enumerate CIM_Foo with qualifiers, xml',
+     {'args': ['enumerate', 'CIM_Foo_sub'],
+      'general': ['--output-format', 'xml']},
+     {'stdout': CIMFOO_SUB_SUB_WITH_QUALS_XML,
+      'test': 'linesnows'},
+     SIMPLE_MOCK_FILE, PYTHON_GE_38],  # issue 1173. Only good for py 3.8+
+
+    ['Verify class command enumerate CIM_Foo with --no qualifiers, xml',
+     {'args': ['enumerate', 'CIM_Foo_sub', '--no-qualifiers'],
+      'general': ['--output-format', 'xml']},
+     {'stdout': CIMFOO_SUB_SUB_NO_QUALS_XML,
+      'test': 'linesnows'},
+     SIMPLE_MOCK_FILE, PYTHON_GE_38],  # issue 1173, Property attributs ordering
+
     ['Verify class command enumerate  --di --no --namespace',
      ['enumerate', '--di', '--no', '-n', 'interop'],
      {'stdout': ['CIM_Namespace', 'CIM_ObjectManager'],
@@ -1271,7 +1534,7 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'lines'},
      SIMPLE_MOCK_FILE, OK],
 
-    ['Verify class command get with repr output format).',
+    ['Verify class command get with xml output format).',
      {'args': ['get', 'CIM_Foo'],
       'general': ['--output-format', 'xml']},
      {'stdout': ['<CLASS( | .+ )NAME="CIM_Foo">',
@@ -1997,6 +2260,13 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
       'test': 'lines'},
      SIMPLE_ASSOC_MOCK_FILE, OK],
 
+    ['Verify class command associators simple request, xml output ge py_3.8,',
+     {'args': ['associators', 'TST_Person'],
+      'general': ['--output-format', 'xml']},
+     {'stdout': ASSOCIATORS_CLASS_XML_GE_38,
+      'test': 'lines'},
+     SIMPLE_ASSOC_MOCK_FILE, PYTHON_GE_38],
+
     ['Verify class command associators simple request names only,',
      ['associators', 'TST_Person', '--names-only'],
      {'stdout': [FAKEURL_STR + '/root/cimv2:TST_Person'],
@@ -2594,8 +2864,10 @@ class CIM_FooRef2 : CIM_BaseRef {
       'test': 'innows'},
      THREE_NS_MOCK_FILE, OK],
 
+    # Test limited to python ge python v 3.8 because qualifier ordering
+    # not determinate with python version lt 3.8.  See issue #1173
     # pylint: disable=line-too-long
-    ['Verify associators from two namespaces xml output',
+    ['Verify associators from two namespaces xml output, version ge 38',
      {'args': ['associators', 'CIM_FooRef1',
                '--namespace', 'root/cimv2,root/cimv3'],
       'general': ['--output-format', 'xml']},
@@ -2637,7 +2909,45 @@ class CIM_FooRef2 : CIM_BaseRef {
 ''',  # noqa: E501
       'rc': 0,
       'test': 'innows'},
-     THREE_NS_MOCK_FILE, PYTHON_GE_36],
+     THREE_NS_MOCK_FILE, PYTHON_GE_38],
+
+    # Test all versions by not requesting qualifiers.  see issue #1173
+    # pylint: disable=line-too-long
+    ['Verify associators from two namespaces xml output, no-qualifiers',
+     {'args': ['associators', 'CIM_FooRef1', '--no-qualifiers',
+               '--namespace', 'root/cimv2,root/cimv3'],
+      'general': ['--output-format', 'xml']},
+     {'stdout': '''<!-- Namespace = root/cimv2 -->
+<CLASSPATH>
+    <NAMESPACEPATH>
+        <HOST>FakedUrl:5988</HOST>
+        <LOCALNAMESPACEPATH>
+            <NAMESPACE NAME="root"/>
+            <NAMESPACE NAME="cimv2"/>
+        </LOCALNAMESPACEPATH>
+    </NAMESPACEPATH>
+    <CLASSNAME NAME="CIM_FooRef2"/>
+</CLASSPATH>
+
+<CLASS NAME="CIM_FooRef2" SUPERCLASS="CIM_BaseRef"/>
+
+<!-- Namespace = root/cimv3 -->
+<CLASSPATH>
+    <NAMESPACEPATH>
+        <HOST>FakedUrl:5988</HOST>
+        <LOCALNAMESPACEPATH>
+            <NAMESPACE NAME="root"/>
+            <NAMESPACE NAME="cimv3"/>
+        </LOCALNAMESPACEPATH>
+    </NAMESPACEPATH>
+    <CLASSNAME NAME="CIM_FooRef2"/>
+</CLASSPATH>
+
+<CLASS NAME="CIM_FooRef2" SUPERCLASS="CIM_BaseRef"/>
+''',  # noqa: E501
+      'rc': 0,
+      'test': 'innows'},
+     THREE_NS_MOCK_FILE, OK],
 
     # pylint: enable=line-too-long
 ]
diff --git a/tests/unit/pywbemcli/test_qualdecl_cmds.py b/tests/unit/pywbemcli/test_qualdecl_cmds.py
index 92f554cf..3855b5c7 100644
--- a/tests/unit/pywbemcli/test_qualdecl_cmds.py
+++ b/tests/unit/pywbemcli/test_qualdecl_cmds.py
@@ -19,6 +19,7 @@
 from __future__ import absolute_import, print_function
 
 import os
+import sys
 import pytest
 
 from .cli_test_extensions import CLITestsBase
@@ -27,6 +28,8 @@
 
 TEST_DIR = os.path.dirname(__file__)
 
+PYTHON_GE_38 = sys.version_info > (3, 8)
+
 # A mof file that defines basic qualifier decls, classes, and instances
 # but not tied to the DMTF classes.
 SIMPLE_MOCK_FILE = 'simple_mock_model.mof'
@@ -271,6 +274,8 @@
       'test': 'in'},
      SIMPLE_MOCK_FILE, OK],
 
+    # Output test in pieces because qual decl attributes not ordered in python
+    # version lt 3.8
     ['Verify qualifier command get  Description outputformat xml',
      {'args': ['get', 'Description'],
       'general': ['--output-format', 'xml']},
@@ -300,6 +305,18 @@
       'test': 'innows'},
      SIMPLE_MOCK_FILE, OK],
 
+    # pylint: disable=line-too-long
+    ['Verify qualifier command get  Description outputformat xml',
+     {'args': ['get', 'Description'],
+      'general': ['--output-format', 'xml']},
+     {'stdout': '''<QUALIFIER.DECLARATION NAME="Description" TYPE="string" ISARRAY="false" OVERRIDABLE="true" TOSUBCLASS="true" TRANSLATABLE="true">
+<SCOPE ASSOCIATION="true" CLASS="true" INDICATION="true" METHOD="true" PARAMETER="true" PROPERTY="true" REFERENCE="true"/>
+</QUALIFIER.DECLARATION>
+''',  # noqa E501
+      'test': 'linesnows'},
+     SIMPLE_MOCK_FILE, PYTHON_GE_38],
+    # pylint: enable=line-too-long
+
     ['Verify qualifier command -o grid enumerate produces table out',
      {'args': ['enumerate'],
       'general': ['-o', 'grid']},