Merge "Add skip flags for block level live migration"
diff --git a/.zuul.yaml b/.zuul.yaml
index dfa9add..9c53ba9 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -180,6 +180,7 @@
         USE_PYTHON3: true
         FORCE_CONFIG_DRIVE: true
         ENABLE_VOLUME_MULTIATTACH: true
+        GLANCE_USE_IMPORT_WORKFLOW: True
       devstack_services:
         s-account: false
         s-container: false
@@ -270,6 +271,7 @@
         USE_PYTHON3: true
         FORCE_CONFIG_DRIVE: true
         ENABLE_VOLUME_MULTIATTACH: true
+        GLANCE_USE_IMPORT_WORKFLOW: True
 
 - job:
     name: tempest-integrated-object-storage
@@ -725,13 +727,11 @@
             irrelevant-files: *tempest-irrelevant-files
         - tempest-all:
             irrelevant-files: *tempest-irrelevant-files
-        - legacy-tempest-dsvm-neutron-dvr-multinode-full:
-            irrelevant-files: *tempest-irrelevant-files
         - neutron-tempest-dvr-ha-multinode-full:
             irrelevant-files: *tempest-irrelevant-files
         - nova-tempest-v2-api:
             irrelevant-files: *tempest-irrelevant-files
-        - legacy-tempest-dsvm-lvm-multibackend:
+        - cinder-tempest-lvm-multibackend:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-pg-full:
             irrelevant-files: *tempest-irrelevant-files
diff --git a/doc/source/conf.py b/doc/source/conf.py
index dd7c544..2a3edf4 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -112,7 +112,7 @@
 show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
 
 # A list of ignored prefixes for module index sorting.
 modindex_common_prefix = ['tempest.']
@@ -204,6 +204,3 @@
     ('index', 'doc-tempest.tex', u'Tempest Testing Project',
      u'OpenStack Foundation', 'manual'),
 ]
-
-# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664
-latex_use_xindy = False
diff --git a/doc/source/index.rst b/doc/source/index.rst
index f878888..d4dc166 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -80,6 +80,7 @@
    microversion_testing
    test_removal
    write_tests
+   requirement_upper_constraint_for_tempest
 
 Plugins
 -------
diff --git a/doc/source/plugins/plugin.rst b/doc/source/plugins/plugin.rst
index a9e2059..ab1b0b1 100644
--- a/doc/source/plugins/plugin.rst
+++ b/doc/source/plugins/plugin.rst
@@ -43,7 +43,7 @@
 In order to create the basic structure with base classes and test directories
 you can use the tempest-plugin-cookiecutter project::
 
-  > pip install -U cookiecutter && cookiecutter https://opendev.org/openstack/tempest-plugin-cookiecutter
+  > pip install -U cookiecutter && cookiecutter https://opendev.org/openstack/tempest-plugin-cookiecutter.git
 
   Cloning into 'tempest-plugin-cookiecutter'...
   remote: Counting objects: 17, done.
diff --git a/doc/source/requirement_upper_constraint_for_tempest.rst b/doc/source/requirement_upper_constraint_for_tempest.rst
new file mode 100644
index 0000000..2eebdda
--- /dev/null
+++ b/doc/source/requirement_upper_constraint_for_tempest.rst
@@ -0,0 +1,56 @@
+Requirements Upper Constraint for Tempest
+=========================================
+
+Tempest is branchless and supported stable branches use Tempest
+master and all EM stable branches use old compatible Tempest version
+for their testing. This means the OpenStack installed upper-constraints
+might not be compatible with Tempest used for stable branch testing.
+For example, if Tempest master is used for testing the stable/stein
+then stable/stein constraint might not be compatible with Tempest master so
+we need to use master upper-constraints there. That is why we use virtual
+env for Tempest installation and running tests so that we can control Tempest
+required constraint from system wide installed constraints.
+
+Devstack takes care of using the master upper-constraints when Tempest master
+is used. But when old Tempest is used then devstack alone cannot handle the
+compatible constraints because Tempest in-tree tox.ini also set the
+upper-constraints which are master constraints so if devstack set the different
+constraints than what we have in tox.ini we end up re-creation of venv which
+flush all previously installed tempest plugins in that venv. More details are
+on `this ML thread <http://lists.openstack.org/pipermail/openstack-discuss/2020-April/014388.html>`_
+
+To solve that problem we have two ways:
+
+#. Set UPPER_CONSTRAINTS_FILE to compatible constraint path
+   This option is not easy as it requires to set this env var everywhere
+   Tempest tox env is used like in devstack, grenade, projects side, zuulv3 roles etc.
+
+#. Pin upper-constraints in tox.ini
+   If we can pin the upper-constraints in tox.ini on every release with the branch
+   constraint at the time of release then we can solve it in an easy way because tox
+   can use the compatible constraint at the time of venv creation itself. But this can
+   again mismatch with the devstack set constraint so we need to follow the below process
+   to make it work.
+
+How to pin upper-constraints in tox.ini
+---------------------------------------
+
+This has to be done exactly before we cut the Tempest new major version bump
+release for the cycle.
+
+Step1: Add the pin constraint proposal in `QA office hour <https://wiki.openstack.org/wiki/Meetings/QATeamMeeting#Agenda_for_next_Office_hours>`_.
+       Pin constraint proposal includes:
+
+       - pin constraint patch. `Example patch 720578 <https://review.opendev.org/#/c/720578/>`_
+       - revert of pin constraint patch. `Example patch 721724 <https://review.opendev.org/#/c/721724/>`_
+
+Step2: Approve pin constraint and its revert patch together.
+       During office hour we need to check that there are no open patches for
+       Tempest release and accordingly we fast approve the 'pin constraint' and its
+       revert patch during office hour itself. Remember 'pin constraint patch' has to be
+       the last commit to include in Tempest release.
+
+Step3: Use 'pin constraint patch' hash for the Tempest new release.
+       By using the 'pin constraint patch' hash we make sure tox.ini in Tempest
+       released tag has the compatible stable constraint not the master one.
+       For Example `Tempest 24.0.0 <https://opendev.org/openstack/tempest/src/tag/24.0.0/tox.ini#L14>`_
diff --git a/releasenotes/notes/Fix-KeyError-bug-in-v3-volumes_client-ff5d9b894f2257c8.yaml b/releasenotes/notes/Fix-KeyError-bug-in-v3-volumes_client-ff5d9b894f2257c8.yaml
new file mode 100644
index 0000000..bbb1901
--- /dev/null
+++ b/releasenotes/notes/Fix-KeyError-bug-in-v3-volumes_client-ff5d9b894f2257c8.yaml
@@ -0,0 +1,10 @@
+---
+fixes:
+  - |
+    is_resource_deleted method of v3 volumes_client might have returned
+    a KeyError exception due to an incorrect accessing of a volume id
+    in the case the volume was in error_deleting state.
+    incorrect code - volume['id']
+    correct code - volume['volume']['id']
+    More details about the issue can be found at
+    https://bugs.launchpad.net/tempest/+bug/1887980
diff --git a/releasenotes/notes/image_import_testing_support-22ba4bcb9f2fb848.yaml b/releasenotes/notes/image_import_testing_support-22ba4bcb9f2fb848.yaml
new file mode 100644
index 0000000..b0180cc
--- /dev/null
+++ b/releasenotes/notes/image_import_testing_support-22ba4bcb9f2fb848.yaml
@@ -0,0 +1,17 @@
+---
+features:
+  - |
+    Add glance image import APIs function to v2
+    images_client library.
+
+    * stage_image_file
+    * info_import
+    * info_stores
+    * image_import
+other:
+  - |
+    New configuration options
+    ``CONF.glance.image_feature_enabled.image_import`` has been introduced
+    to enable the image import tests. If your glance deployement support
+    image import functionality then you can enable the image import tests
+    via this flag. Default value of this new config option is false.
diff --git a/releasenotes/notes/network-swap-to-project_id-a1d7fdf6c5e1cf44.yaml b/releasenotes/notes/network-swap-to-project_id-a1d7fdf6c5e1cf44.yaml
new file mode 100644
index 0000000..4cf0c76
--- /dev/null
+++ b/releasenotes/notes/network-swap-to-project_id-a1d7fdf6c5e1cf44.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    [`blueprint blueprint adopt-oslo-versioned-objects-for-db <https://blueprints.launchpad.net/neutron/+spec/adopt-oslo-versioned-objects-for-db>`_]
+    Any reference to "tenant_id" in Network objects is replaced with
+    "project_id".
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 71df749..9a9de43 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -98,7 +98,7 @@
 # show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'native'
 
 # A list of ignored prefixes for module index sorting.
 # modindex_common_prefix = []
diff --git a/requirements.txt b/requirements.txt
index bf38fae..d8738f0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -3,7 +3,7 @@
 # process, which may cause wedges in the gate later.
 pbr!=2.1.0,>=2.0.0 # Apache-2.0
 cliff!=2.9.0,>=2.8.0 # Apache-2.0
-jsonschema>=2.6.0 # MIT
+jsonschema>=3.2.0 # MIT
 testtools>=2.2.0 # MIT
 paramiko>=2.0.0 # LGPLv2.1+
 netaddr>=0.7.18 # BSD
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index d5adfed..7b115ce 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -49,7 +49,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
     def test_aggregate_create_as_user(self):
-        # Regular user is not allowed to create an aggregate.
+        """Regular user is not allowed to create an aggregate"""
         aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
         self.assertRaises(lib_exc.Forbidden,
                           self.aggregates_client.create_aggregate,
@@ -58,7 +58,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
     def test_aggregate_create_aggregate_name_length_less_than_1(self):
-        # the length of aggregate name should >= 1 and <=255
+        """The length of aggregate name should >=1"""
         self.assertRaises(lib_exc.BadRequest,
                           self.client.create_aggregate,
                           name='')
@@ -66,7 +66,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
     def test_aggregate_create_aggregate_name_length_exceeds_255(self):
-        # the length of aggregate name should >= 1 and <=255
+        """The length of aggregate name should <=255"""
         aggregate_name = 'a' * 256
         self.assertRaises(lib_exc.BadRequest,
                           self.client.create_aggregate,
@@ -75,7 +75,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
     def test_aggregate_create_with_existent_aggregate_name(self):
-        # creating an aggregate with existent aggregate name is forbidden
+        """Creating an aggregate with existent aggregate name is forbidden"""
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Conflict,
                           self.client.create_aggregate,
@@ -84,7 +84,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
     def test_aggregate_delete_as_user(self):
-        # Regular user is not allowed to delete an aggregate.
+        """Regular user is not allowed to delete an aggregate"""
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
                           self.aggregates_client.delete_aggregate,
@@ -93,14 +93,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
     def test_aggregate_list_as_user(self):
-        # Regular user is not allowed to list aggregates.
+        """Regular user is not allowed to list aggregates"""
         self.assertRaises(lib_exc.Forbidden,
                           self.aggregates_client.list_aggregates)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
     def test_aggregate_get_details_as_user(self):
-        # Regular user is not allowed to get aggregate details.
+        """Regular user is not allowed to get aggregate details"""
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
                           self.aggregates_client.show_aggregate,
@@ -109,21 +109,21 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
     def test_aggregate_delete_with_invalid_id(self):
-        # Delete an aggregate with invalid id should raise exceptions.
+        """Delete an aggregate with invalid id should raise exceptions"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.delete_aggregate, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
     def test_aggregate_get_details_with_invalid_id(self):
-        # Get aggregate details with invalid id should raise exceptions.
+        """Get aggregate details with invalid id should raise exceptions"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.show_aggregate, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
     def test_aggregate_add_non_exist_host(self):
-        # Adding a non-exist host to an aggregate should raise exceptions.
+        """Adding a non-exist host to an aggregate should fail"""
         while True:
             non_exist_host = data_utils.rand_name('nonexist_host')
             if non_exist_host not in self.hosts:
@@ -135,7 +135,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
     def test_aggregate_add_host_as_user(self):
-        # Regular user is not allowed to add a host to an aggregate.
+        """Regular user is not allowed to add a host to an aggregate"""
         aggregate = self._create_test_aggregate()
         self.assertRaises(lib_exc.Forbidden,
                           self.aggregates_client.add_host,
@@ -144,7 +144,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
     def test_aggregate_add_existent_host(self):
-        # Adding already existing host to aggregate should fail.
+        """Adding already existing host to aggregate should fail"""
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate = self._create_test_aggregate()
 
@@ -158,7 +158,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
     def test_aggregate_remove_host_as_user(self):
-        # Regular user is not allowed to remove a host from an aggregate.
+        """Regular user is not allowed to remove a host from an aggregate"""
         self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate = self._create_test_aggregate()
 
@@ -173,7 +173,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
     def test_aggregate_remove_nonexistent_host(self):
-        # Removing not existing host from aggregate should fail.
+        """Removing not existing host from aggregate should fail"""
         aggregate = self._create_test_aggregate()
 
         self.assertRaises(lib_exc.NotFound, self.client.remove_host,
diff --git a/tempest/api/compute/admin/test_create_server.py b/tempest/api/compute/admin/test_create_server.py
index 711b441..c4a8bf5 100644
--- a/tempest/api/compute/admin/test_create_server.py
+++ b/tempest/api/compute/admin/test_create_server.py
@@ -27,6 +27,8 @@
 
 
 class ServersWithSpecificFlavorTestJSON(base.BaseV2ComputeAdminTest):
+    """Test creating servers with specific flavor"""
+
     @classmethod
     def setup_credentials(cls):
         cls.prepare_instance_network()
@@ -41,7 +43,7 @@
     @testtools.skipUnless(CONF.validation.run_validation,
                           'Instance validation tests are disabled.')
     def test_verify_created_server_ephemeral_disk(self):
-        # Verify that the ephemeral disk is created when creating server
+        """Verify that the ephemeral disk is created when creating server"""
         flavor_base = self.flavors_client.show_flavor(
             self.flavor_ref)['flavor']
 
diff --git a/tempest/api/compute/admin/test_delete_server.py b/tempest/api/compute/admin/test_delete_server.py
index 58cac57..c625939 100644
--- a/tempest/api/compute/admin/test_delete_server.py
+++ b/tempest/api/compute/admin/test_delete_server.py
@@ -19,6 +19,8 @@
 
 
 class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
+    """Test deletion of servers"""
+
     # NOTE: Server creations of each test class should be under 10
     # for preventing "Quota exceeded for instances".
 
@@ -30,7 +32,7 @@
 
     @decorators.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
     def test_delete_server_while_in_error_state(self):
-        # Delete a server while it's VM state is error
+        """Delete a server while it's VM state is error"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.admin_client.reset_state(server['id'], state='error')
         # Verify server's state
@@ -43,7 +45,7 @@
 
     @decorators.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
     def test_admin_delete_servers_of_others(self):
-        # Administrator can delete servers of others
+        """Administrator can delete servers of others"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.admin_client.delete_server(server['id'])
         waiters.wait_for_server_termination(self.servers_client, server['id'])
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index 2d7e1a7..786c7f0 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -63,7 +63,7 @@
     @decorators.idempotent_id('2c8f145f-8012-4cb8-ac7e-95a587f0e4ab')
     @utils.services('network')
     def test_create_list_delete_floating_ips_bulk(self):
-        # Create, List  and delete the Floating IPs Bulk
+        """Creating, listing and deleting the Floating IPs Bulk"""
         pool = 'test_pool'
         # NOTE(GMann): Reserving the IP range but those are not attached
         # anywhere. Using the below mentioned interface which is not ever
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 31fe2b5..30f3388 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -18,7 +18,7 @@
 
 
 class HostsAdminTestJSON(base.BaseV2ComputeAdminTest):
-    """Tests hosts API using admin privileges."""
+    """Tests nova hosts API using admin privileges."""
 
     max_microversion = '2.42'
 
@@ -29,13 +29,13 @@
 
     @decorators.idempotent_id('9bfaf98d-e2cb-44b0-a07e-2558b2821e4f')
     def test_list_hosts(self):
-        # Listing hosts.
+        """Listing nova hosts"""
         hosts = self.client.list_hosts()['hosts']
         self.assertGreaterEqual(len(hosts), 2, str(hosts))
 
     @decorators.idempotent_id('5dc06f5b-d887-47a2-bb2a-67762ef3c6de')
     def test_list_hosts_with_zone(self):
-        # Listing hosts with specified availability zone
+        """Listing nova hosts with specified availability zone"""
         self.useFixture(fixtures.LockFixture('availability_zone'))
         hosts = self.client.list_hosts()['hosts']
         host = hosts[0]
@@ -45,23 +45,27 @@
 
     @decorators.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
     def test_list_hosts_with_a_blank_zone(self):
-        # Listing hosts with blank availability zone.
-        # If send the request with a blank zone, the request will be successful
-        # and it will return all the hosts list
+        """Listing nova hosts with blank availability zone
+
+        If send the request with a blank zone, the request will be successful
+        and it will return all the hosts list
+        """
         hosts = self.client.list_hosts(zone='')['hosts']
         self.assertNotEmpty(hosts)
 
     @decorators.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
     def test_list_hosts_with_nonexistent_zone(self):
-        # Listing hosts with not existing availability zone.
-        # If send the request with a nonexistent zone, the request will be
-        # successful and no hosts will be returned
+        """Listing nova hosts with not existing availability zone.
+
+        If send the request with a nonexistent zone, the request will be
+        successful and no hosts will be returned
+        """
         hosts = self.client.list_hosts(zone='xxx')['hosts']
         self.assertEmpty(hosts)
 
     @decorators.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
     def test_show_host_detail(self):
-        # Showing host details.
+        """Showing nova host details"""
         hosts = self.client.list_hosts()['hosts']
 
         hosts = [host for host in hosts if host['service'] == 'compute']
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index e8733c8..e9436bc 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -39,21 +39,21 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('dd032027-0210-4d9c-860e-69b1b8deed5f')
     def test_list_hosts_with_non_admin_user(self):
-        # Non admin user is not allowed to list hosts.
+        """Non admin user is not allowed to list hosts"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.list_hosts)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e75b0a1a-041f-47a1-8b4a-b72a6ff36d3f')
     def test_show_host_detail_with_nonexistent_hostname(self):
-        # Showing host detail with not existing hostname should fail.
+        """Showing host detail with not existing hostname should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.show_host, 'nonexistent_hostname')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('19ebe09c-bfd4-4b7c-81a2-e2e0710f59cc')
     def test_show_host_detail_with_non_admin_user(self):
-        # Non admin user is not allowed to show host details.
+        """Non admin user is not allowed to show host details"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.show_host,
                           self.hostname)
@@ -61,7 +61,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e40c72b1-0239-4ed6-ba21-81a184df1f7c')
     def test_update_host_with_non_admin_user(self):
-        # Non admin user is not allowed to update host.
+        """Non admin user is not allowed to update host"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.update_host,
                           self.hostname,
@@ -71,8 +71,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
     def test_update_host_with_invalid_status(self):
-        # Updating host to invalid status should fail,
-        # 'status' can only be 'enable' or 'disable'.
+        """Updating host to invalid status should fail
+
+        'status' can only be 'enable' or 'disable'.
+        """
         self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           self.hostname,
@@ -82,8 +84,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ab1e230e-5e22-41a9-8699-82b9947915d4')
     def test_update_host_with_invalid_maintenance_mode(self):
-        # Updating host to invalid maintenance mode should fail,
-        # 'maintenance_mode' can only be 'enable' or 'disable'.
+        """Updating host to invalid maintenance mode should fail
+
+        'maintenance_mode' can only be 'enable' or 'disable'.
+        """
         self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           self.hostname,
@@ -93,8 +97,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0cd85f75-6992-4a4a-b1bd-d11e37fd0eee')
     def test_update_host_without_param(self):
-        # Updating host without param should fail,
-        # 'status' or 'maintenance_mode' is needed for host update.
+        """Updating host without param should fail
+
+        'status' or 'maintenance_mode' is needed for host update
+        """
         self.assertRaises(lib_exc.BadRequest,
                           self.client.update_host,
                           self.hostname)
@@ -102,7 +108,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('23c92146-2100-4d68-b2d6-c7ade970c9c1')
     def test_update_nonexistent_host(self):
-        # Updating not existing host should fail.
+        """Updating not existing host should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.update_host,
                           'nonexistent_hostname',
@@ -112,7 +118,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0d981ac3-4320-4898-b674-82b61fbb60e4')
     def test_startup_nonexistent_host(self):
-        # Starting up not existing host should fail.
+        """Starting up not existing host should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.startup_host,
                           'nonexistent_hostname')
@@ -120,7 +126,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9f4ebb7e-b2ae-4e5b-a38f-0fd1bb0ddfca')
     def test_startup_host_with_non_admin_user(self):
-        # Non admin user is not allowed to startup host.
+        """Non admin user is not allowed to startup host"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.startup_host,
                           self.hostname)
@@ -128,7 +134,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9e637444-29cf-4244-88c8-831ae82c31b6')
     def test_shutdown_nonexistent_host(self):
-        # Shutting down not existing host should fail.
+        """Shutting down not existing host should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.shutdown_host,
                           'nonexistent_hostname')
@@ -136,7 +142,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a803529c-7e3f-4d3c-a7d6-8e1c203d27f6')
     def test_shutdown_host_with_non_admin_user(self):
-        # Non admin user is not allowed to shutdown host.
+        """Non admin user is not allowed to shutdown host"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.shutdown_host,
                           self.hostname)
@@ -144,7 +150,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f86bfd7b-0b13-4849-ae29-0322e83ee58b')
     def test_reboot_nonexistent_host(self):
-        # Rebooting not existing host should fail.
+        """Rebooting not existing host should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.reboot_host,
                           'nonexistent_hostname')
@@ -152,7 +158,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('02d79bb9-eb57-4612-abf6-2cb38897d2f8')
     def test_reboot_host_with_non_admin_user(self):
-        # Non admin user is not allowed to reboot host.
+        """Non admin user is not allowed to reboot host"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_client.reboot_host,
                           self.hostname)
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index e45aac5..347193d 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -36,19 +36,19 @@
 
     @decorators.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
     def test_get_hypervisor_list(self):
-        # List of hypervisor and available hypervisors hostname
+        """List of hypervisor and available hypervisors hostname"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers, "No hypervisors found.")
 
     @decorators.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
     def test_get_hypervisor_list_details(self):
-        # Display the details of the all hypervisor
+        """Display the details of the all hypervisor"""
         hypers = self.client.list_hypervisors(detail=True)['hypervisors']
         self.assertNotEmpty(hypers, "No hypervisors found.")
 
     @decorators.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
     def test_get_hypervisor_show_details(self):
-        # Display the details of the specified hypervisor
+        """Display the details of the specified hypervisor"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers, "No hypervisors found.")
 
@@ -59,14 +59,14 @@
 
     @decorators.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
     def test_get_hypervisor_stats(self):
-        # Verify the stats of the all hypervisor
+        """Verify the stats of the all hypervisor"""
         stats = (self.client.show_hypervisor_statistics()
                  ['hypervisor_statistics'])
         self.assertNotEmpty(stats)
 
     @decorators.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
     def test_get_hypervisor_uptime(self):
-        # Verify that GET shows the specified hypervisor uptime
+        """Verify that GET shows the specified hypervisor uptime"""
         hypers = self._list_hypervisors()
 
         # Ironic will register each baremetal node as a 'hypervisor',
@@ -106,10 +106,13 @@
 
 
 class HypervisorAdminV228Test(HypervisorAdminTestBase):
+    """Tests Hypervisors API higher than 2.27 that require admin privileges"""
+
     min_microversion = '2.28'
 
     @decorators.idempotent_id('d46bab64-0fbe-4eb8-9133-e6ee56188cc5')
     def test_get_list_hypervisor_details(self):
+        """Test listing and showing hypervisor details"""
         # NOTE(zhufl): This test tests the hypervisor APIs response schema
         # for 2.28 microversion. No specific assert or behaviour verification
         # is needed.
@@ -119,11 +122,13 @@
 
 
 class HypervisorAdminUnderV252Test(HypervisorAdminTestBase):
+    """Tests Hypervisors API below 2.53 that require admin privileges"""
+
     max_microversion = '2.52'
 
     @decorators.idempotent_id('e81bba3f-6215-4e39-a286-d52d2f906862')
     def test_get_hypervisor_show_servers(self):
-        # Show instances about the specific hypervisors
+        """Test showing instances about the specific hypervisors"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers, "No hypervisors found.")
 
@@ -134,7 +139,7 @@
 
     @decorators.idempotent_id('d7e1805b-3b14-4a3b-b6fd-50ec6d9f361f')
     def test_search_hypervisor(self):
-        # Searching for hypervisors by its name.
+        """Test searching for hypervisors by its name"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers, "No hypervisors found.")
         hypers = self.client.search_hypervisor(
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index 723b93c..9aaffd9 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -40,8 +40,9 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c136086a-0f67-4b2b-bc61-8482bd68989f')
     def test_show_nonexistent_hypervisor(self):
-        # Showing not existing hypervisor should fail.
+        """Test showing non existent hypervisor should fail"""
         nonexistent_hypervisor_id = data_utils.rand_uuid()
+
         self.assertRaises(
             lib_exc.NotFound,
             self.client.show_hypervisor,
@@ -50,7 +51,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
     def test_show_hypervisor_with_non_admin_user(self):
-        # Non admin user is not allowed to show hypervisor.
+        """Test showing hypervisor by non admin user should fail"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers)
 
@@ -62,7 +63,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e2b061bb-13f9-40d8-9d6e-d5bf17595849')
     def test_get_hypervisor_stats_with_non_admin_user(self):
-        # Non admin user is not allowed to get hypervisor stats.
+        """Test getting hypervisor stats by non admin user should fail"""
         self.assertRaises(
             lib_exc.Forbidden,
             self.non_adm_client.show_hypervisor_statistics)
@@ -70,7 +71,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f60aa680-9a3a-4c7d-90e1-fae3a4891303')
     def test_get_nonexistent_hypervisor_uptime(self):
-        # Getting uptime of not existing hypervisor should fail.
+        """Test showing uptime of non existent hypervisor should fail"""
         nonexistent_hypervisor_id = data_utils.rand_uuid()
 
         self.assertRaises(
@@ -81,7 +82,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
     def test_get_hypervisor_uptime_with_non_admin_user(self):
-        # Non admin user is not allowed to get hypervisor uptime.
+        """Test showing uptime of hypervisor by non admin user should fail"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers)
 
@@ -93,7 +94,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('51b3d536-9b14-409c-9bce-c6f7c794994e')
     def test_get_hypervisor_list_with_non_admin_user(self):
-        # List of hypervisor and available services with non admin user
+        """Test listing hypervisors by non admin user should fail"""
         self.assertRaises(
             lib_exc.Forbidden,
             self.non_adm_client.list_hypervisors)
@@ -101,19 +102,21 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('dc02db05-e801-4c5f-bc8e-d915290ab345')
     def test_get_hypervisor_list_details_with_non_admin_user(self):
-        # Non admin user is not allowed to list hypervisor details.
+        """Test listing hypervisor details by non admin user should fail"""
         self.assertRaises(
             lib_exc.Forbidden,
             self.non_adm_client.list_hypervisors, detail=True)
 
 
 class HypervisorAdminNegativeUnderV252Test(HypervisorAdminNegativeTestBase):
+    """Tests Hypervisors API below ver 2.53 that require admin privileges"""
+
     max_microversion = '2.52'
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
     def test_show_servers_with_non_admin_user(self):
-        # Non admin user is not allowed to show servers on hypervisor.
+        """Test showing hypervisor servers by non admin user should fail"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers)
 
@@ -125,7 +128,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('02463d69-0ace-4d33-a4a8-93d7883a2bba')
     def test_show_servers_with_nonexistent_hypervisor(self):
-        # Showing servers on not existing hypervisor should fail.
+        """Test showing servers on non existent hypervisor should fail"""
         nonexistent_hypervisor_id = data_utils.rand_uuid()
 
         self.assertRaises(
@@ -136,7 +139,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
     def test_search_hypervisor_with_non_admin_user(self):
-        # Non admin user is not allowed to search hypervisor.
+        """Test searching hypervisor by non admin user should fail"""
         hypers = self._list_hypervisors()
         self.assertNotEmpty(hypers)
 
@@ -148,7 +151,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('19a45cc1-1000-4055-b6d2-28e8b2ec4faa')
     def test_search_nonexistent_hypervisor(self):
-        # Searching not existing hypervisor should fail.
+        """Test searching non existent hypervisor should fail"""
         self.assertRaises(
             lib_exc.NotFound,
             self.client.search_hypervisor,
diff --git a/tempest/api/compute/admin/test_keypairs_v210.py b/tempest/api/compute/admin/test_keypairs_v210.py
index 40ed532..3068127 100644
--- a/tempest/api/compute/admin/test_keypairs_v210.py
+++ b/tempest/api/compute/admin/test_keypairs_v210.py
@@ -19,6 +19,8 @@
 
 
 class KeyPairsV210TestJSON(base.BaseKeypairTest):
+    """Tests KeyPairs API with microversion higher than 2.9"""
+
     credentials = ['primary', 'admin']
     min_microversion = '2.10'
 
@@ -48,6 +50,13 @@
 
     @decorators.idempotent_id('3c8484af-cfb3-48f6-b8ba-d5d58bbf3eac')
     def test_admin_manage_keypairs_for_other_users(self):
+        """Test admin managing keypairs for other users
+
+        First admin creates a keypair for an other user, then admin lists
+        keypairs filtered by that user, and keypairs created for that user
+        should appear in the result and keypairs not created for that user
+        should not appear in the result.
+        """
         user_id = self.non_admin_client.user_id
         key_list = self._create_and_check_keypairs(user_id)
         first_keyname = key_list[0]['name']
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index f90ff92..04dbc2d 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -53,10 +53,12 @@
 
 
 class QuotasAdminNegativeTest(QuotasAdminNegativeTestBase):
+    """Negative tests of nova quotas"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('733abfe8-166e-47bb-8363-23dbd7ff3476')
     def test_update_quota_normal_user(self):
+        """Test updating nova quota by normal user should fail"""
         self.assertRaises(lib_exc.Forbidden,
                           self.client.update_quota_set,
                           self.demo_tenant_id,
@@ -67,7 +69,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
     def test_create_server_when_cpu_quota_is_full(self):
-        # Disallow server creation when tenant's vcpu quota is full
+        """Disallow server creation when tenant's vcpu quota is full"""
         self._update_quota('cores', 0)
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
                           self.create_test_server)
@@ -75,7 +77,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
     def test_create_server_when_memory_quota_is_full(self):
-        # Disallow server creation when tenant's memory quota is full
+        """Disallow server creation when tenant's memory quota is full"""
         self._update_quota('ram', 0)
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
                           self.create_test_server)
@@ -83,13 +85,15 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
     def test_create_server_when_instances_quota_is_full(self):
-        # Once instances quota limit is reached, disallow server creation
+        """Once instances quota limit is reached, disallow server creation"""
         self._update_quota('instances', 0)
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
                           self.create_test_server)
 
 
 class QuotasSecurityGroupAdminNegativeTest(QuotasAdminNegativeTestBase):
+    """Negative tests of nova security group quota"""
+
     max_microversion = '2.35'
 
     @decorators.skip_because(bug="1186354",
@@ -98,7 +102,7 @@
     @decorators.idempotent_id('7c6c8f3b-2bf6-4918-b240-57b136a66aa0')
     @utils.services('network')
     def test_security_groups_exceed_limit(self):
-        # Negative test: Creation Security Groups over limit should FAIL
+        """Negative test: Creation Security Groups over limit should FAIL"""
         # Set the quota to number of used security groups
         sg_quota = self.limits_client.show_limits()['limits']['absolute'][
             'totalSecurityGroupsUsed']
@@ -117,7 +121,7 @@
     @decorators.idempotent_id('6e9f436d-f1ed-4f8e-a493-7275dfaa4b4d')
     @utils.services('network')
     def test_security_groups_rules_exceed_limit(self):
-        # Negative test: Creation of Security Group Rules should FAIL
+        """Negative test: Creation of Security Group Rules should FAIL"""
         # when we reach limit maxSecurityGroupRules
         self._update_quota('security_group_rules', 0)
 
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index bf846e5..24518a8 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -19,7 +19,10 @@
 
 
 class ServicesAdminTestJSON(base.BaseV2ComputeAdminTest):
-    """Tests Services API. List and Enable/Disable require admin privileges."""
+    """Tests Nova Services API.
+
+    List and Enable/Disable require admin privileges.
+    """
 
     @classmethod
     def setup_clients(cls):
@@ -28,13 +31,13 @@
 
     @decorators.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
     def test_list_services(self):
-        # Listing nova services
+        """Listing nova services"""
         services = self.client.list_services()['services']
         self.assertNotEmpty(services)
 
     @decorators.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
     def test_get_service_by_service_binary_name(self):
-        # Listing nova services by binary name.
+        """Listing nova services by binary name"""
         binary_name = 'nova-compute'
         services = self.client.list_services(binary=binary_name)['services']
         self.assertNotEmpty(services)
@@ -43,7 +46,7 @@
 
     @decorators.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
     def test_get_service_by_host_name(self):
-        # Listing nova services by host name.
+        """Listing nova services by host name"""
         services = self.client.list_services()['services']
         host_name = services[0]['host']
         services_on_host = [service for service in services if
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 20294e9..58861a1 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -18,11 +18,12 @@
 
 
 class FlavorsV2TestJSON(base.BaseV2ComputeTest):
+    """Tests Flavors"""
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')
     def test_list_flavors(self):
-        # List of all flavors should contain the expected flavor
+        """List of all flavors should contain the expected flavor"""
         flavors = self.flavors_client.list_flavors()['flavors']
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_min_detail = {'id': flavor['id'], 'links': flavor['links'],
@@ -31,7 +32,7 @@
 
     @decorators.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
     def test_list_flavors_with_detail(self):
-        # Detailed list of all flavors should contain the expected flavor
+        """Detailed list of all flavors should contain the expected flavor"""
         flavors = self.flavors_client.list_flavors(detail=True)['flavors']
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         self.assertIn(flavor, flavors)
@@ -39,20 +40,20 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
     def test_get_flavor(self):
-        # The expected flavor details should be returned
+        """The expected flavor details should be returned"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         self.assertEqual(self.flavor_ref, flavor['id'])
 
     @decorators.idempotent_id('8d7691b3-6ed4-411a-abc9-2839a765adab')
     def test_list_flavors_limit_results(self):
-        # Only the expected number of flavors should be returned
+        """Only the expected number of flavors should be returned"""
         params = {'limit': 1}
         flavors = self.flavors_client.list_flavors(**params)['flavors']
         self.assertEqual(1, len(flavors))
 
     @decorators.idempotent_id('b26f6327-2886-467a-82be-cef7a27709cb')
     def test_list_flavors_detailed_limit_results(self):
-        # Only the expected number of flavors (detailed) should be returned
+        """Only the expected number of flavors(detailed) should be returned"""
         params = {'limit': 1}
         flavors = self.flavors_client.list_flavors(detail=True,
                                                    **params)['flavors']
@@ -60,7 +61,7 @@
 
     @decorators.idempotent_id('e800f879-9828-4bd0-8eae-4f17189951fb')
     def test_list_flavors_using_marker(self):
-        # The list of flavors should start from the provided marker
+        """The list of flavors should start from the provided marker"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
@@ -71,7 +72,7 @@
 
     @decorators.idempotent_id('6db2f0c0-ddee-4162-9c84-0703d3dd1107')
     def test_list_flavors_detailed_using_marker(self):
-        # The list of flavors should start from the provided marker
+        """The list of flavors should start from the provided marker"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
@@ -83,7 +84,7 @@
 
     @decorators.idempotent_id('3df2743e-3034-4e57-a4cb-b6527f6eac79')
     def test_list_flavors_detailed_filter_by_min_disk(self):
-        # The detailed list of flavors should be filtered by disk space
+        """The detailed list of flavors should be filtered by disk space"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
@@ -94,7 +95,7 @@
 
     @decorators.idempotent_id('09fe7509-b4ee-4b34-bf8b-39532dc47292')
     def test_list_flavors_detailed_filter_by_min_ram(self):
-        # The detailed list of flavors should be filtered by RAM
+        """The detailed list of flavors should be filtered by RAM"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
@@ -105,7 +106,7 @@
 
     @decorators.idempotent_id('10645a4d-96f5-443f-831b-730711e11dd4')
     def test_list_flavors_filter_by_min_disk(self):
-        # The list of flavors should be filtered by disk space
+        """The list of flavors should be filtered by disk space"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
@@ -115,7 +116,7 @@
 
     @decorators.idempotent_id('935cf550-e7c8-4da6-8002-00f92d5edfaa')
     def test_list_flavors_filter_by_min_ram(self):
-        # The list of flavors should be filtered by RAM
+        """The list of flavors should be filtered by RAM"""
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         flavor_id = flavor['id']
 
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index ef33685..91ce1f9 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -25,6 +25,8 @@
 
 
 class ImagesTestJSON(base.BaseV2ComputeTest):
+    """Test server images"""
+
     create_default_network = True
 
     @classmethod
@@ -48,6 +50,7 @@
 
     @decorators.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
     def test_delete_saving_image(self):
+        """Test deleting server image while it is in 'SAVING' state"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.servers_client.delete_server, server['id'])
         # wait for server active to avoid conflict when deleting server
@@ -74,6 +77,7 @@
 
     @decorators.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
     def test_create_image_from_stopped_server(self):
+        """Test creating server image from stopped server"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.stop_server(server['id'])
         waiters.wait_for_server_status(self.servers_client,
@@ -91,6 +95,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     def test_create_image_from_paused_server(self):
+        """Test creating server image from paused server"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.pause_server(server['id'])
         waiters.wait_for_server_status(self.servers_client,
@@ -109,6 +114,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     def test_create_image_from_suspended_server(self):
+        """Test creating server image from suspended server"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.servers_client.suspend_server(server['id'])
         waiters.wait_for_server_status(self.servers_client,
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 2400348..5ff2a6a 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -42,11 +42,12 @@
 
 
 class ImagesNegativeTestJSON(ImagesNegativeTestBase):
+    """Negative tests of server image"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6cd5a89d-5b47-46a7-93bc-3916f0d84973')
     def test_create_image_from_deleted_server(self):
-        # An image should not be created if the server instance is removed
+        """Check server image should not be created if the server is removed"""
         server = self.create_test_server(wait_until='ACTIVE')
 
         # Delete server before trying to create image
@@ -61,7 +62,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('82c5b0c4-9dbd-463c-872b-20c4755aae7f')
     def test_create_image_from_invalid_server(self):
-        # An image should not be created with invalid server id
+        """Check server image should not be created with invalid server id"""
         # Create a new image with invalid server id
         meta = {'image_type': 'test'}
         self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
@@ -70,7 +71,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
     def test_create_image_specify_uuid_35_characters_or_less(self):
-        # Return an error if Image ID passed is 35 characters or less
+        """Check server image should not be created for invalid server id
+
+        Return an error if server id passed is 35 characters or less
+        """
         snapshot_name = data_utils.rand_name('test-snap')
         test_uuid = ('a' * 35)
         self.assertRaises(lib_exc.NotFound, self.client.create_image,
@@ -79,7 +83,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
     def test_create_image_specify_uuid_37_characters_or_more(self):
-        # Return an error if Image ID passed is 37 characters or more
+        """Check server image should not be created for invalid server id
+
+        Return an error if sever id passed is 37 characters or more
+        """
         snapshot_name = data_utils.rand_name('test-snap')
         test_uuid = ('a' * 37)
         self.assertRaises(lib_exc.NotFound, self.client.create_image,
@@ -87,20 +94,23 @@
 
 
 class ImagesDeleteNegativeTestJSON(ImagesNegativeTestBase):
+    """Negative tests of server image
+
+    Negative tests of server image with compute microversion less than 2.36.
+    """
     max_microversion = '2.35'
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
     def test_delete_image_with_invalid_image_id(self):
-        # An image should not be deleted with invalid image id
+        """Check an image should not be deleted with invalid image id"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           data_utils.rand_name('invalid'))
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
     def test_delete_non_existent_image(self):
-        # Return an error while trying to delete a non-existent image
-
+        """Check trying to delete a non-existent image should fail"""
         non_existent_image_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           non_existent_image_id)
@@ -108,13 +118,13 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e6e41425-af5c-4fe6-a4b5-7b7b963ffda5')
     def test_delete_image_blank_id(self):
-        # Return an error while trying to delete an image with blank Id
+        """Check trying to delete an image with blank id should fail"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('924540c3-f1f1-444c-8f58-718958b6724e')
     def test_delete_image_non_hex_string_id(self):
-        # Return an error while trying to delete an image with non hex id
+        """Check trying to delete an image with non hex id should fail"""
         invalid_image_id = data_utils.rand_uuid()[:-1] + "j"
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           invalid_image_id)
@@ -122,13 +132,13 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('68e2c175-bd26-4407-ac0f-4ea9ce2139ea')
     def test_delete_image_negative_image_id(self):
-        # Return an error while trying to delete an image with negative id
+        """Check trying to delete an image with negative id should fail"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b340030d-82cd-4066-a314-c72fb7c59277')
     def test_delete_image_with_id_over_character_limit(self):
-        # Return an error while trying to delete image with id over limit
+        """Check trying to delete image with id over limit should fail"""
         invalid_image_id = data_utils.rand_uuid() + "1"
         self.assertRaises(lib_exc.NotFound, self.client.delete_image,
                           invalid_image_id)
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index cbb65bb..4dc23a7 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -21,6 +21,8 @@
 
 
 class ListImagesTestJSON(base.BaseV2ComputeTest):
+    """Test listing server images with compute microversion less than 2.36"""
+
     max_microversion = '2.35'
 
     @classmethod
@@ -37,20 +39,26 @@
 
     @decorators.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
     def test_get_image(self):
-        # Returns the correct details for a single image
+        """Test getting the correct details for a single server image"""
         image = self.client.show_image(self.image_ref)['image']
         self.assertEqual(self.image_ref, image['id'])
 
     @decorators.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
     def test_list_images(self):
-        # The list of all images should contain the image
+        """Test listing server images
+
+        The list of all images should contain the image
+        """
         images = self.client.list_images()['images']
         found = [i for i in images if i['id'] == self.image_ref]
         self.assertNotEmpty(found)
 
     @decorators.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
     def test_list_images_with_detail(self):
-        # Detailed list of all images should contain the expected images
+        """Test listing server images with detail
+
+        Detailed list of all images should contain the expected images
+        """
         images = self.client.list_images(detail=True)['images']
         found = [i for i in images if i['id'] == self.image_ref]
         self.assertNotEmpty(found)
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 8c2202e..c729069 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -18,6 +18,11 @@
 
 
 class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
+    """Test compute absolute limits
+
+    Test compute absolute limits with compute microversion less than 2.57
+    """
+
     max_microversion = '2.56'
 
     @classmethod
@@ -27,12 +32,17 @@
 
     @decorators.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
     def test_absLimits_get(self):
+        """Test getting nova absolute limits"""
         # To check if all limits are present in the response (will be checked
         # by schema)
         self.client.show_limits()
 
 
 class AbsoluteLimitsV257TestJSON(base.BaseV2ComputeTest):
+    """Test compute absolute limits
+
+    Test compute absolute limits with compute microversion greater than 2.56
+    """
     min_microversion = '2.57'
     max_microversion = 'latest'
 
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index 500638a..de6a9b9 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -20,6 +20,7 @@
 
 
 class AbsoluteLimitsNegativeTestJSON(base.BaseV2ComputeTest):
+    """Negative tests of nova absolute limits"""
 
     def setUp(self):
         # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
@@ -34,7 +35,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
     def test_max_metadata_exceed_limit(self):
-        # We should not create vm with metadata over maxServerMeta limit
+        """Test creating server with metadata over limit should fail
+
+        We should not create server with metadata over maxServerMeta limit
+        """
         # Get max limit value
         limits = self.client.show_limits()['limits']
         max_meta = limits['absolute']['maxServerMeta']
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 36828d6..d239149 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -27,6 +27,6 @@
 
     @decorators.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
     def test_get_availability_zone_list_with_non_admin_user(self):
-        # List of availability zone with non-administrator user
+        """List of availability zone with non-administrator user"""
         availability_zone = self.client.list_availability_zones()
         self.assertNotEmpty(availability_zone['availabilityZoneInfo'])
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 4f0dbad..48f32a8 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -27,6 +27,11 @@
 
 
 class ServersTestJSON(base.BaseV2ComputeTest):
+    """Test creating server and verifying the server attributes
+
+    This is to create server booted from image and with disk_config 'AUTO'
+    """
+
     disk_config = 'AUTO'
     volume_backed = False
 
@@ -62,13 +67,12 @@
             disk_config=disk_config,
             adminPass=cls.password,
             volume_backed=cls.volume_backed)
-        cls.server = (cls.client.show_server(server_initial['id'])
-                      ['server'])
+        cls.server = cls.client.show_server(server_initial['id'])['server']
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
     def test_verify_server_details(self):
-        # Verify the specified server attributes are set correctly
+        """Verify the specified server attributes are set correctly"""
         self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
         # NOTE(maurosr): See http://tools.ietf.org/html/rfc5952 (section 4)
         # Here we compare directly with the canonicalized format.
@@ -86,7 +90,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
     def test_list_servers(self):
-        # The created server should be in the list of all servers
+        """The created server should be in the list of all servers"""
         body = self.client.list_servers()
         servers = body['servers']
         found = [i for i in servers if i['id'] == self.server['id']]
@@ -94,7 +98,7 @@
 
     @decorators.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
     def test_list_servers_with_detail(self):
-        # The created server should be in the detailed list of all servers
+        """The created server should be in the detailed list of all servers"""
         body = self.client.list_servers(detail=True)
         servers = body['servers']
         found = [i for i in servers if i['id'] == self.server['id']]
@@ -104,8 +108,11 @@
     @testtools.skipUnless(CONF.validation.run_validation,
                           'Instance validation tests are disabled.')
     def test_verify_created_server_vcpus(self):
-        # Verify that the number of vcpus reported by the instance matches
-        # the amount stated by the flavor
+        """The created server should have the same specification as the flavor
+
+        Verify that the number of vcpus reported by the instance matches
+        the amount stated by the flavor
+        """
         flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
         validation_resources = self.get_class_validation_resources(
             self.os_primary)
@@ -123,7 +130,7 @@
     @testtools.skipUnless(CONF.validation.run_validation,
                           'Instance validation tests are disabled.')
     def test_host_name_is_same_as_server_name(self):
-        # Verify the instance host name is the same as the server name
+        """Verify the instance host name is the same as the server name"""
         validation_resources = self.get_class_validation_resources(
             self.os_primary)
         linux_client = remote_client.RemoteClient(
@@ -145,6 +152,10 @@
 
 
 class ServersTestManualDisk(ServersTestJSON):
+    """Test creating server and verifying the server attributes
+
+    This is to create server booted from image and with disk_config 'MANUAL'
+    """
     disk_config = 'MANUAL'
 
     @classmethod
@@ -156,7 +167,11 @@
 
 
 class ServersTestBootFromVolume(ServersTestJSON):
-    """Run the `ServersTestJSON` tests with a volume backed VM"""
+    """Test creating server and verifying the server attributes
+
+    This is to create server booted from volume and with disk_config 'AUTO'
+    """
+    # Run the `ServersTestJSON` tests with a volume backed VM
     volume_backed = True
 
     @classmethod
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index a7db88a..ee25a22 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -26,6 +26,7 @@
 
 
 class DeleteServersTestJSON(base.BaseV2ComputeTest):
+    """Test deleting servers in various states"""
     create_default_network = True
 
     # NOTE: Server creations of each test class should be under 10
@@ -38,21 +39,21 @@
 
     @decorators.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
     def test_delete_server_while_in_building_state(self):
-        # Delete a server while it's VM state is Building
+        """Test deleting a server while it's VM state is Building"""
         server = self.create_test_server(wait_until='BUILD')
         self.client.delete_server(server['id'])
         waiters.wait_for_server_termination(self.client, server['id'])
 
     @decorators.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
     def test_delete_active_server(self):
-        # Delete a server while it's VM state is Active
+        """Test deleting a server while it's VM state is Active"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.client.delete_server(server['id'])
         waiters.wait_for_server_termination(self.client, server['id'])
 
     @decorators.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
     def test_delete_server_while_in_shutoff_state(self):
-        # Delete a server while it's VM state is Shutoff
+        """Test deleting a server while it's VM state is Shutoff"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.client.stop_server(server['id'])
         waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
@@ -63,7 +64,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
                           'Pause is not available.')
     def test_delete_server_while_in_pause_state(self):
-        # Delete a server while it's VM state is Pause
+        """Test deleting a server while it's VM state is Pause"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.client.pause_server(server['id'])
         waiters.wait_for_server_status(self.client, server['id'], 'PAUSED')
@@ -74,7 +75,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     def test_delete_server_while_in_suspended_state(self):
-        # Delete a server while it's VM state is Suspended
+        """Test deleting a server while it's VM state is Suspended"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.client.suspend_server(server['id'])
         waiters.wait_for_server_status(self.client, server['id'], 'SUSPENDED')
@@ -85,7 +86,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
                           'Shelve is not available.')
     def test_delete_server_while_in_shelved_state(self):
-        # Delete a server while it's VM state is Shelved
+        """Test deleting a server while it's VM state is Shelved"""
         server = self.create_test_server(wait_until='ACTIVE')
         compute.shelve_server(self.client, server['id'])
 
@@ -96,7 +97,7 @@
     @testtools.skipIf(not CONF.compute_feature_enabled.resize,
                       'Resize not available.')
     def test_delete_server_while_in_verify_resize_state(self):
-        # Delete a server while it's VM state is VERIFY_RESIZE
+        """Test deleting a server while it's VM state is VERIFY_RESIZE"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.client.resize_server(server['id'], self.flavor_ref_alt)
         waiters.wait_for_server_status(self.client, server['id'],
@@ -107,7 +108,7 @@
     @decorators.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
     @utils.services('volume')
     def test_delete_server_while_in_attached_volume(self):
-        # Delete a server while a volume is attached to it
+        """Test deleting a server while a volume is attached to it"""
         server = self.create_test_server(wait_until='ACTIVE')
 
         volume = self.create_volume()
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 5b8e7ab..e5e051a 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -24,6 +24,8 @@
 
 
 class ServerDiskConfigTestJSON(base.BaseV2ComputeTest):
+    """Test disk config option of server"""
+
     create_default_network = True
 
     @classmethod
@@ -49,7 +51,7 @@
 
     @decorators.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
     def test_rebuild_server_with_manual_disk_config(self):
-        # A server should be rebuilt using the manual disk config option
+        """A server should be rebuilt using the manual disk config option"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
@@ -68,7 +70,7 @@
 
     @decorators.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
     def test_rebuild_server_with_auto_disk_config(self):
-        # A server should be rebuilt using the auto disk config option
+        """A server should be rebuilt using the auto disk config option"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
@@ -89,7 +91,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     def test_resize_server_from_manual_to_auto(self):
-        # A server should be resized from manual to auto disk config
+        """A server should be resized from manual to auto disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
@@ -105,7 +107,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     def test_resize_server_from_auto_to_manual(self):
-        # A server should be resized from auto to manual disk config
+        """A server should be resized from auto to manual disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
@@ -119,7 +121,7 @@
 
     @decorators.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
     def test_update_server_from_auto_to_manual(self):
-        # A server should be updated from auto to manual disk config
+        """A server should be updated from auto to manual disk config"""
         server = self.create_test_server(wait_until='ACTIVE')
         self.addCleanup(self.client.delete_server, server['id'])
         self._update_server_with_disk_config(server['id'],
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 3dffd01..7f62c64 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -26,6 +26,7 @@
 
 
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
+    """Test listing servers filtered by specified attribute"""
 
     @classmethod
     def setup_credentials(cls):
@@ -71,7 +72,7 @@
     @testtools.skipUnless(CONF.compute.image_ref != CONF.compute.image_ref_alt,
                           "Need distinct images to run this test")
     def test_list_servers_filter_by_image(self):
-        # Filter the list of servers by image
+        """Filter the list of servers by image"""
         params = {'image': self.image_ref}
         body = self.client.list_servers(**params)
         servers = body['servers']
@@ -82,7 +83,7 @@
 
     @decorators.idempotent_id('573637f5-7325-47bb-9144-3476d0416908')
     def test_list_servers_filter_by_flavor(self):
-        # Filter the list of servers by flavor
+        """Filter the list of servers by flavor"""
         params = {'flavor': self.flavor_ref_alt}
         body = self.client.list_servers(**params)
         servers = body['servers']
@@ -93,7 +94,7 @@
 
     @decorators.idempotent_id('9b067a7b-7fee-4f6a-b29c-be43fe18fc5a')
     def test_list_servers_filter_by_server_name(self):
-        # Filter the list of servers by server name
+        """Filter the list of servers by server name"""
         params = {'name': self.s1_name}
         body = self.client.list_servers(**params)
         servers = body['servers']
@@ -104,7 +105,7 @@
 
     @decorators.idempotent_id('ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e')
     def test_list_servers_filter_by_active_status(self):
-        # Filter the list of servers by server active status
+        """Filter the list of servers by server active status"""
         params = {'status': 'active'}
         body = self.client.list_servers(**params)
         servers = body['servers']
@@ -115,7 +116,7 @@
 
     @decorators.idempotent_id('451dbbb2-f330-4a9f-b0e1-5f5d2cb0f34c')
     def test_list_servers_filter_by_shutoff_status(self):
-        # Filter the list of servers by server shutoff status
+        """Filter the list of servers by server shutoff status"""
         params = {'status': 'shutoff'}
         self.client.stop_server(self.s1['id'])
         waiters.wait_for_server_status(self.client, self.s1['id'],
@@ -132,21 +133,30 @@
 
     @decorators.idempotent_id('614cdfc1-d557-4bac-915b-3e67b48eee76')
     def test_list_servers_filter_by_limit(self):
-        # Verify only the expected number of servers are returned
+        """Filter the list of servers by limit 1
+
+        Verify only the expected number of servers are returned (one server)
+        """
         params = {'limit': 1}
         servers = self.client.list_servers(**params)
         self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
 
     @decorators.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
     def test_list_servers_filter_by_zero_limit(self):
-        # Verify only the expected number of servers are returned
+        """Filter the list of servers by limit 0
+
+        Verify only the expected number of servers are returned (no server)
+        """
         params = {'limit': 0}
         servers = self.client.list_servers(**params)
         self.assertEmpty(servers['servers'])
 
     @decorators.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
     def test_list_servers_filter_by_exceed_limit(self):
-        # Verify only the expected number of servers are returned
+        """Filter the list of servers by exceeded limit
+
+        Verify only the expected number of servers are returned (all servers)
+        """
         params = {'limit': 100000}
         servers = self.client.list_servers(**params)
         all_servers = self.client.list_servers()
@@ -157,7 +167,7 @@
     @testtools.skipUnless(CONF.compute.image_ref != CONF.compute.image_ref_alt,
                           "Need distinct images to run this test")
     def test_list_servers_detailed_filter_by_image(self):
-        # Filter the detailed list of servers by image
+        """"Filter the detailed list of servers by image"""
         params = {'image': self.image_ref}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
@@ -168,7 +178,7 @@
 
     @decorators.idempotent_id('80c574cc-0925-44ba-8602-299028357dd9')
     def test_list_servers_detailed_filter_by_flavor(self):
-        # Filter the detailed list of servers by flavor
+        """Filter the detailed list of servers by flavor"""
         params = {'flavor': self.flavor_ref_alt}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
@@ -179,7 +189,7 @@
 
     @decorators.idempotent_id('f9eb2b70-735f-416c-b260-9914ac6181e4')
     def test_list_servers_detailed_filter_by_server_name(self):
-        # Filter the detailed list of servers by server name
+        """Filter the detailed list of servers by server name"""
         params = {'name': self.s1_name}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
@@ -190,7 +200,7 @@
 
     @decorators.idempotent_id('de2612ab-b7dd-4044-b0b1-d2539601911f')
     def test_list_servers_detailed_filter_by_server_status(self):
-        # Filter the detailed list of servers by server status
+        """Filter the detailed list of servers by server status"""
         params = {'status': 'active'}
         body = self.client.list_servers(detail=True, **params)
         servers = body['servers']
@@ -204,6 +214,7 @@
 
     @decorators.idempotent_id('e9f624ee-92af-4562-8bec-437945a18dcb')
     def test_list_servers_filtered_by_name_wildcard(self):
+        """Filter the list of servers by part of server name"""
         # List all servers that contains '-instance' in name
         params = {'name': '-instance'}
         body = self.client.list_servers(**params)
@@ -226,6 +237,7 @@
 
     @decorators.idempotent_id('24a89b0c-0d55-4a28-847f-45075f19b27b')
     def test_list_servers_filtered_by_name_regex(self):
+        """Filter the list of servers by server name regular expression"""
         # list of regex that should match s1, s2 and s3
         regexes = [r'^.*\-instance\-[0-9]+$', r'^.*\-instance\-.*$']
         for regex in regexes:
@@ -250,7 +262,7 @@
 
     @decorators.idempotent_id('43a1242e-7b31-48d1-88f2-3f72aa9f2077')
     def test_list_servers_filtered_by_ip(self):
-        # Filter servers by ip
+        """Filter the list of servers by server ip address"""
         # Here should be listed 1 server
         if not self.fixed_network_name:
             msg = 'fixed_network_name needs to be configured to run this test'
@@ -287,8 +299,7 @@
     @decorators.skip_because(bug="1540645")
     @decorators.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
     def test_list_servers_filtered_by_ip_regex(self):
-        # Filter servers by regex ip
-        # List all servers filtered by part of ip address.
+        """Filter the list of servers by part of server ip address"""
         # Here should be listed all servers
         if not self.fixed_network_name:
             msg = 'fixed_network_name needs to be configured to run this test'
@@ -317,7 +328,10 @@
 
     @decorators.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
     def test_list_servers_detailed_limit_results(self):
-        # Verify only the expected number of detailed results are returned
+        """Filter the detailed list of servers by limit 1
+
+        Verify only the expected number of servers are returned (one server)
+        """
         params = {'limit': 1}
         servers = self.client.list_servers(detail=True, **params)
         self.assertEqual(1, len(servers['servers']))
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index 68e09e7..7931ca9 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -33,6 +33,8 @@
 
 
 class NoVNCConsoleTestJSON(base.BaseV2ComputeTest):
+    """Test novnc console"""
+
     create_default_network = True
 
     @classmethod
@@ -181,6 +183,7 @@
 
     @decorators.idempotent_id('c640fdff-8ab4-45a4-a5d8-7e6146cbd0dc')
     def test_novnc(self):
+        """Test accessing novnc console of server"""
         if self.use_get_remote_console:
             body = self.client.get_remote_console(
                 self.server['id'], console_type='novnc',
@@ -200,6 +203,11 @@
 
     @decorators.idempotent_id('f9c79937-addc-4aaa-9e0e-841eef02aeb7')
     def test_novnc_bad_token(self):
+        """Test accessing novnc console with bad token
+
+        Do the WebSockify HTTP Request to novnc proxy with a bad token,
+        the novnc proxy should reject the connection and closed it.
+        """
         if self.use_get_remote_console:
             body = self.client.get_remote_console(
                 self.server['id'], console_type='novnc',
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index f33c6d9..e7444d2 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -20,6 +20,7 @@
 
 
 class ServerAddressesNegativeTestJSON(base.BaseV2ComputeTest):
+    """Negative tests of listing server addresses"""
     create_default_network = True
 
     @classmethod
@@ -36,7 +37,7 @@
     @decorators.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
     @utils.services('network')
     def test_list_server_addresses_invalid_server_id(self):
-        # List addresses request should fail if server id not in system
+        """List addresses request should fail if server id not in system"""
         self.assertRaises(lib_exc.NotFound, self.client.list_addresses,
                           '999')
 
@@ -44,7 +45,7 @@
     @decorators.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
     @utils.services('network')
     def test_list_server_addresses_by_network_neg(self):
-        # List addresses by network should fail if network name not valid
+        """List addresses by network should fail if network name not valid"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.list_addresses_by_network,
                           self.server['id'], 'invalid')
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index 4b5efaa..4c0d021 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -82,18 +82,18 @@
 
     @decorators.idempotent_id('5dc57eda-35b7-4af7-9e5f-3c2be3d2d68b')
     def test_create_delete_server_group_with_affinity_policy(self):
-        # Create and Delete the server-group with affinity policy
+        """Test Create/Delete the server-group with affinity policy"""
         self._create_delete_server_group(self.policy)
 
     @decorators.idempotent_id('3645a102-372f-4140-afad-13698d850d23')
     def test_create_delete_server_group_with_anti_affinity_policy(self):
-        # Create and Delete the server-group with anti-affinity policy
+        """Test Create/Delete the server-group with anti-affinity policy"""
         policy = ['anti-affinity']
         self._create_delete_server_group(policy)
 
     @decorators.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
     def test_create_delete_multiple_server_groups_with_same_name_policy(self):
-        # Create and Delete the server-groups with same name and same policy
+        """Test Create/Delete the server-groups with same name and policy"""
         server_groups = []
         server_group_name = data_utils.rand_name('server-group')
         for _ in range(0, 2):
@@ -108,14 +108,14 @@
 
     @decorators.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
     def test_show_server_group(self):
-        # Get the server-group
+        """Test getting the server-group detail"""
         body = self.client.show_server_group(
             self.created_server_group['id'])['server_group']
         self.assertEqual(self.created_server_group, body)
 
     @decorators.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
     def test_list_server_groups(self):
-        # List the server-group
+        """Test listing the server-groups"""
         body = self.client.list_server_groups()['server_groups']
         self.assertIn(self.created_server_group, body)
 
@@ -124,7 +124,7 @@
         compute.is_scheduler_filter_enabled("ServerGroupAffinityFilter"),
         'ServerGroupAffinityFilter is not available.')
     def test_create_server_with_scheduler_hint_group(self):
-        # Create a server with the scheduler hint "group".
+        """Test creating a server with the scheduler hint 'group'"""
         hints = {'group': self.created_server_group['id']}
         server = self.create_test_server(scheduler_hints=hints,
                                          wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index 4f484e2..ba2adbb 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -28,6 +28,7 @@
 
 
 class ServerPersonalityTestJSON(base.BaseV2ComputeTest):
+    """Test servers with injected files"""
 
     @classmethod
     def setup_credentials(cls):
@@ -51,6 +52,7 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('3cfe87fd-115b-4a02-b942-7dc36a337fdf')
     def test_create_server_with_personality(self):
+        """Test creating server with file injection"""
         file_contents = 'This is a test file.'
         file_path = '/test.txt'
         personality = [{'path': file_path,
@@ -85,6 +87,7 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('128966d8-71fc-443c-8cab-08e24114ecc9')
     def test_rebuild_server_with_personality(self):
+        """Test injecting file when rebuilding server"""
         validation_resources = self.get_test_validation_resources(
             self.os_primary)
         server = self.create_test_server(
@@ -107,8 +110,11 @@
 
     @decorators.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
     def test_personality_files_exceed_limit(self):
-        # Server creation should fail if greater than the maximum allowed
-        # number of files are injected into the server.
+        """Test creating server with injected files over limitation
+
+        Server creation should fail if greater than the maximum allowed
+        number of files are injected into the server.
+        """
         file_contents = 'This is a test file.'
         personality = []
         limits = self.limits_client.show_limits()['limits']
@@ -131,8 +137,11 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('52f12ee8-5180-40cc-b417-31572ea3d555')
     def test_can_create_server_with_max_number_personality_files(self):
-        # Server should be created successfully if maximum allowed number of
-        # files is injected into the server during creation.
+        """Test creating server with maximum allowed number of injected files
+
+        Server should be created successfully if maximum allowed number of
+        files is injected into the server during creation.
+        """
         file_contents = 'This is a test file.'
         limits = self.limits_client.show_limits()['limits']
         max_file_limit = limits['absolute']['maxPersonality']
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index caceb64..9bcf062 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -27,6 +27,7 @@
 
 
 class ServerRescueNegativeTestJSON(base.BaseV2ComputeTest):
+    """Negative tests of server rescue"""
 
     @classmethod
     def skip_checks(cls):
@@ -75,7 +76,7 @@
                           'Pause is not available.')
     @decorators.attr(type=['negative'])
     def test_rescue_paused_instance(self):
-        # Rescue a paused server
+        """Test rescuing a paused server should fail"""
         self.servers_client.pause_server(self.server_id)
         self.addCleanup(self._unpause, self.server_id)
         waiters.wait_for_server_status(self.servers_client,
@@ -87,13 +88,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
     def test_rescued_vm_reboot(self):
+        """Test rebooing a rescued server should fail"""
         self.assertRaises(lib_exc.Conflict, self.servers_client.reboot_server,
                           self.rescue_id, type='HARD')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6dfc0a55-3a77-4564-a144-1587b7971dde')
     def test_rescue_non_existent_server(self):
-        # Rescue a non-existing server
+        """Test rescuing a non-existing server should fail"""
         non_existent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.servers_client.rescue_server,
@@ -102,6 +104,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
     def test_rescued_vm_rebuild(self):
+        """Test rebuilding a rescued server should fail"""
         self.assertRaises(lib_exc.Conflict,
                           self.servers_client.rebuild_server,
                           self.rescue_id,
@@ -111,6 +114,7 @@
     @utils.services('volume')
     @decorators.attr(type=['negative'])
     def test_rescued_vm_attach_volume(self):
+        """Test attaching volume to a rescued server should fail"""
         volume = self.create_volume()
 
         # Rescue the server
@@ -130,6 +134,7 @@
     @utils.services('volume')
     @decorators.attr(type=['negative'])
     def test_rescued_vm_detach_volume(self):
+        """Test detaching volume from a rescued server should fail"""
         volume = self.create_volume()
 
         # Attach the volume to the server
diff --git a/tempest/api/compute/servers/test_server_tags.py b/tempest/api/compute/servers/test_server_tags.py
index 3893b01..619f480 100644
--- a/tempest/api/compute/servers/test_server_tags.py
+++ b/tempest/api/compute/servers/test_server_tags.py
@@ -22,6 +22,7 @@
 
 
 class ServerTagsTestJSON(base.BaseV2ComputeTest):
+    """Test server tags with compute microversion greater than 2.25"""
 
     min_microversion = '2.26'
     max_microversion = 'latest'
@@ -54,6 +55,7 @@
 
     @decorators.idempotent_id('8d95abe2-c658-4c42-9a44-c0258500306b')
     def test_create_delete_tag(self):
+        """Test creating and deleting server tag"""
         # Check that no tags exist.
         fetched_tags = self.client.list_tags(self.server['id'])['tags']
         self.assertEmpty(fetched_tags)
@@ -73,6 +75,7 @@
 
     @decorators.idempotent_id('a2c1af8c-127d-417d-974b-8115f7e3d831')
     def test_update_all_tags(self):
+        """Test updating all server tags"""
         # Add server tags to the server.
         tags = [data_utils.rand_name('tag'), data_utils.rand_name('tag')]
         self._update_server_tags(self.server['id'], tags)
@@ -89,6 +92,7 @@
 
     @decorators.idempotent_id('a63b2a74-e918-4b7c-bcab-10c855f3a57e')
     def test_delete_all_tags(self):
+        """Test deleting all server tags"""
         # Add server tags to the server.
         assigned_tags = [data_utils.rand_name('tag'),
                          data_utils.rand_name('tag')]
@@ -101,6 +105,7 @@
 
     @decorators.idempotent_id('81279a66-61c3-4759-b830-a2dbe64cbe08')
     def test_check_tag_existence(self):
+        """Test checking server tag existence"""
         # Add server tag to the server.
         assigned_tag = data_utils.rand_name('tag')
         self._update_server_tags(self.server['id'], assigned_tag)
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 7fa30b0..6676358 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -30,6 +30,8 @@
 
 
 class ServersNegativeTestJSON(base.BaseV2ComputeTest):
+    """Negative tests of servers"""
+
     create_default_network = True
 
     def setUp(self):
@@ -66,8 +68,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf')
     def test_server_name_blank(self):
-        # Create a server with name parameter empty
-
+        """Creating a server with name parameter empty should fail"""
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           name='')
@@ -77,8 +78,7 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.personality,
                           'Nova personality feature disabled')
     def test_personality_file_contents_not_encoded(self):
-        # Use an unencoded file when creating a server with personality
-
+        """Using an unencoded injected file to create server should fail"""
         file_contents = 'This is a test file.'
         person = [{'path': '/etc/testfile.txt',
                    'contents': file_contents}]
@@ -90,8 +90,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('fcba1052-0a50-4cf3-b1ac-fae241edf02f')
     def test_create_with_invalid_image(self):
-        # Create a server with an unknown image
-
+        """Creating a server with an unknown image should fail"""
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           image_id=-1)
@@ -99,8 +98,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('18f5227f-d155-4429-807c-ccb103887537')
     def test_create_with_invalid_flavor(self):
-        # Create a server with an unknown flavor
-
+        """Creating a server with an unknown flavor should fail"""
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           flavor=-1,)
@@ -108,8 +106,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7f70a4d1-608f-4794-9e56-cb182765972c')
     def test_invalid_access_ip_v4_address(self):
-        # An access IPv4 address must match a valid address pattern
+        """Creating a server with invalid ipv4 ip address should fail
 
+        An access IPv4 address must match a valid address pattern
+        """
         IPv4 = '1.1.1.1.1.1'
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server, accessIPv4=IPv4)
@@ -117,8 +117,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0')
     def test_invalid_ip_v6_address(self):
-        # An access IPv6 address must match a valid address pattern
+        """Creating a server with invalid ipv6 ip address should fail
 
+        An access IPv6 address must match a valid address pattern
+        """
         IPv6 = 'notvalid'
 
         self.assertRaises(lib_exc.BadRequest,
@@ -129,7 +131,7 @@
                           'Resize not available.')
     @decorators.attr(type=['negative'])
     def test_resize_nonexistent_server(self):
-        # Resize a non-existent server
+        """Resizing a non-existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.client.resize_server,
@@ -140,7 +142,7 @@
                           'Resize not available.')
     @decorators.attr(type=['negative'])
     def test_resize_server_with_non_existent_flavor(self):
-        # Resize a server with non-existent flavor
+        """Resizing a server with non existent flavor should fail"""
         nonexistent_flavor = data_utils.rand_uuid()
         self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
                           self.server_id, flavor_ref=nonexistent_flavor)
@@ -150,14 +152,14 @@
                           'Resize not available.')
     @decorators.attr(type=['negative'])
     def test_resize_server_with_null_flavor(self):
-        # Resize a server with null flavor
+        """Resizing a server with null flavor should fail"""
         self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
                           self.server_id, flavor_ref="")
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')
     def test_reboot_non_existent_server(self):
-        # Reboot a non existent server
+        """Rebooting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
                           nonexistent_server, type='SOFT')
@@ -167,7 +169,7 @@
                           'Pause is not available.')
     @decorators.attr(type=['negative'])
     def test_pause_paused_server(self):
-        # Pause a paused server.
+        """Pausing a paused server should fail"""
         self.client.pause_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id, 'PAUSED')
         self.assertRaises(lib_exc.Conflict,
@@ -178,7 +180,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
     def test_rebuild_deleted_server(self):
-        # Rebuild a deleted server
+        """Rebuilding a deleted server should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.client.rebuild_server,
                           self.deleted_server_id, self.image_ref)
@@ -187,14 +189,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('581a397d-5eab-486f-9cf9-1014bbd4c984')
     def test_reboot_deleted_server(self):
-        # Reboot a deleted server
+        """Rebooting a deleted server should fail"""
         self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
                           self.deleted_server_id, type='SOFT')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d86141a7-906e-4731-b187-d64a2ea61422')
     def test_rebuild_non_existent_server(self):
-        # Rebuild a non existent server
+        """Rebuilding a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.client.rebuild_server,
@@ -204,6 +206,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('fd57f159-68d6-4c2a-902b-03070828a87e')
     def test_create_numeric_server_name(self):
+        """Creating a server with numeric server name should fail"""
         server_name = 12345
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
@@ -212,8 +215,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c3e0fb12-07fc-4d76-a22e-37409887afe8')
     def test_create_server_name_length_exceeds_256(self):
-        # Create a server with name length exceeding 255 characters
+        """Creating a server with name length exceeding limit should fail
 
+        Create a server with name length exceeding 255 characters, an error is
+        returned.
+        """
         server_name = 'a' * 256
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
@@ -224,6 +230,11 @@
     @utils.services('volume')
     @decorators.idempotent_id('12146ac1-d7df-4928-ad25-b1f99e5286cd')
     def test_create_server_invalid_bdm_in_2nd_dict(self):
+        """Creating a server with invalid block_device_mapping_v2 should fail
+
+        Create a server with invalid block_device_mapping_v2, an error is
+        returned.
+        """
         volume = self.create_volume()
         bdm_1st = {"source_type": "image",
                    "delete_on_termination": True,
@@ -243,10 +254,9 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4e72dc2d-44c5-4336-9667-f7972e95c402')
     def test_create_with_invalid_network_uuid(self):
+        """Creating a server with invalid network uuid should fail"""
         # Pass invalid network uuid while creating a server
-
         networks = [{'fixed_ip': '10.0.1.1', 'uuid': 'a-b-c-d-e-f-g-h-i-j'}]
-
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
                           networks=networks)
@@ -254,8 +264,8 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7a2efc39-530c-47de-b875-2dd01c8d39bd')
     def test_create_with_non_existent_keypair(self):
+        """Creating a server with non-existent keypair should fail"""
         # Pass a non-existent keypair while creating a server
-
         key_name = data_utils.rand_name('key')
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
@@ -264,8 +274,8 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7fc74810-0bd2-4cd7-8244-4f33a9db865a')
     def test_create_server_metadata_exceeds_length_limit(self):
+        """Creating a server with metadata longer than limit should fail """
         # Pass really long metadata while creating a server
-
         metadata = {'a': 'b' * 260}
         self.assertRaises((lib_exc.BadRequest, lib_exc.OverLimit),
                           self.create_test_server,
@@ -274,8 +284,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
     def test_update_name_of_non_existent_server(self):
-        # Update name of a non-existent server
-
+        """Updating name of a non-existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         new_name = data_utils.rand_name(
             self.__class__.__name__ + '-server') + '_updated'
@@ -286,18 +295,19 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
     def test_update_server_set_empty_name(self):
-        # Update name of the server to an empty string
-
+        """Updating name of the server to an empty string should fail"""
         new_name = ''
-
         self.assertRaises(lib_exc.BadRequest, self.client.update_server,
                           self.server_id, name=new_name)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
     def test_update_server_name_length_exceeds_256(self):
-        # Update name of server exceed the name length limit
+        """Updating name of server exceeding the name length limit should fail
 
+        Update name of server exceeding the name length limit, an error is
+        returned.
+        """
         new_name = 'a' * 256
         self.assertRaises(lib_exc.BadRequest,
                           self.client.update_server,
@@ -307,8 +317,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('1041b4e6-514b-4855-96a5-e974b60870a3')
     def test_delete_non_existent_server(self):
-        # Delete a non existent server
-
+        """Deleting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.delete_server,
                           nonexistent_server)
@@ -316,23 +325,24 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
     def test_delete_server_pass_negative_id(self):
-        # Pass an invalid string parameter to delete server
-
+        """Passing an invalid string parameter to delete server should fail"""
         self.assertRaises(lib_exc.NotFound, self.client.delete_server, -1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
     def test_delete_server_pass_id_exceeding_length_limit(self):
-        # Pass a server ID that exceeds length limit to delete server
+        """Deleting server with a server ID exceeding length limit should fail
 
+        Pass a server ID that exceeds length limit to delete server, an error
+        is returned.
+        """
         self.assertRaises(lib_exc.NotFound, self.client.delete_server,
                           sys.maxsize + 1)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
     def test_create_with_nonexistent_security_group(self):
-        # Create a server with a nonexistent security group
-
+        """Creating a server with a nonexistent security group should fail"""
         security_groups = [{'name': 'does_not_exist'}]
         self.assertRaises(lib_exc.BadRequest,
                           self.create_test_server,
@@ -341,7 +351,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('3436b02f-1b1e-4f03-881e-c6a602327439')
     def test_get_non_existent_server(self):
-        # Get a non existent server details
+        """Getting a non existent server details should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.show_server,
                           nonexistent_server)
@@ -349,7 +359,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a31460a9-49e1-42aa-82ee-06e0bb7c2d03')
     def test_stop_non_existent_server(self):
-        # Stop a non existent server
+        """Stopping a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.servers_client.stop_server,
                           nonexistent_server)
@@ -359,7 +369,7 @@
                           'Pause is not available.')
     @decorators.attr(type=['negative'])
     def test_pause_non_existent_server(self):
-        # pause a non existent server
+        """Pausing a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.pause_server,
                           nonexistent_server)
@@ -369,7 +379,7 @@
                           'Pause is not available.')
     @decorators.attr(type=['negative'])
     def test_unpause_non_existent_server(self):
-        # unpause a non existent server
+        """Unpausing a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.unpause_server,
                           nonexistent_server)
@@ -379,7 +389,7 @@
                           'Pause is not available.')
     @decorators.attr(type=['negative'])
     def test_unpause_server_invalid_state(self):
-        # unpause an active server.
+        """Unpausing an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
                           self.client.unpause_server,
                           self.server_id)
@@ -389,7 +399,7 @@
                           'Suspend is not available.')
     @decorators.attr(type=['negative'])
     def test_suspend_non_existent_server(self):
-        # suspend a non existent server
+        """Suspending a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.suspend_server,
                           nonexistent_server)
@@ -399,7 +409,7 @@
                           'Suspend is not available.')
     @decorators.attr(type=['negative'])
     def test_suspend_server_invalid_state(self):
-        # suspend a suspended server.
+        """Suspending a suspended server should fail"""
         self.client.suspend_server(self.server_id)
         waiters.wait_for_server_status(self.client, self.server_id,
                                        'SUSPENDED')
@@ -413,7 +423,7 @@
                           'Suspend is not available.')
     @decorators.attr(type=['negative'])
     def test_resume_non_existent_server(self):
-        # resume a non existent server
+        """Resuming a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.resume_server,
                           nonexistent_server)
@@ -423,7 +433,7 @@
                           'Suspend is not available.')
     @decorators.attr(type=['negative'])
     def test_resume_server_invalid_state(self):
-        # resume an active server.
+        """Resuming an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
                           self.client.resume_server,
                           self.server_id)
@@ -431,7 +441,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7dd919e7-413f-4198-bebb-35e2a01b13e9')
     def test_get_console_output_of_non_existent_server(self):
-        # get the console output for a non existent server
+        """Getting the console output for a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.client.get_console_output,
@@ -440,7 +450,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6f47992b-5144-4250-9f8b-f00aa33950f3')
     def test_force_delete_nonexistent_server_id(self):
-        # force-delete a non existent server
+        """Force-deleting a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.client.force_delete_server,
@@ -449,7 +459,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9c6d38cc-fcfb-437a-85b9-7b788af8bf01')
     def test_restore_nonexistent_server_id(self):
-        # restore-delete a non existent server
+        """Restore-deleting a non existent server should fail
+
+        We can restore a soft deleted server, but can't restore a non
+        existent server.
+        """
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.client.restore_soft_deleted_server,
@@ -458,7 +472,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7fcadfab-bd6a-4753-8db7-4a51e51aade9')
     def test_restore_server_invalid_state(self):
-        # we can only restore-delete a server in 'soft-delete' state
+        """Restore-deleting a server not in 'soft-delete' state should fail
+
+        We can restore a soft deleted server, but can't restore a server that
+        is not in 'soft-delete' state.
+        """
         self.assertRaises(lib_exc.Conflict,
                           self.client.restore_soft_deleted_server,
                           self.server_id)
@@ -468,7 +486,7 @@
                           'Shelve is not available.')
     @decorators.attr(type=['negative'])
     def test_shelve_non_existent_server(self):
-        # shelve a non existent server
+        """Shelving a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.shelve_server,
                           nonexistent_server)
@@ -478,7 +496,7 @@
                           'Shelve is not available.')
     @decorators.attr(type=['negative'])
     def test_shelve_shelved_server(self):
-        # shelve a shelved server.
+        """Shelving a shelved server should fail"""
         compute.shelve_server(self.client, self.server_id)
 
         def _unshelve_server():
@@ -508,7 +526,7 @@
                           'Shelve is not available.')
     @decorators.attr(type=['negative'])
     def test_unshelve_non_existent_server(self):
-        # unshelve a non existent server
+        """Unshelving a non existent server should fail"""
         nonexistent_server = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.client.unshelve_server,
                           nonexistent_server)
@@ -518,7 +536,7 @@
                           'Shelve is not available.')
     @decorators.attr(type=['negative'])
     def test_unshelve_server_invalid_state(self):
-        # unshelve an active server.
+        """Unshelving an active server should fail"""
         self.assertRaises(lib_exc.Conflict,
                           self.client.unshelve_server,
                           self.server_id)
@@ -527,7 +545,7 @@
     @decorators.idempotent_id('74085be3-a370-4ca2-bc51-2d0e10e0f573')
     @utils.services('volume', 'image')
     def test_create_server_from_non_bootable_volume(self):
-        # Create a volume
+        """Creating a server from a non bootable volume should fail"""
         volume = self.create_volume()
 
         # Update volume bootable status to false
@@ -555,6 +573,8 @@
 
 
 class ServersNegativeTestMultiTenantJSON(base.BaseV2ComputeTest):
+    """Negative tests of servers for multiple projects"""
+
     create_default_network = True
 
     credentials = ['primary', 'alt']
@@ -581,8 +601,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
     def test_update_server_of_another_tenant(self):
-        # Update name of a server that belongs to another tenant
+        """Updating server that belongs to another project should fail
 
+        Update name of a server that belongs to another project, an error is
+        returned.
+        """
         new_name = self.server_id + '_new'
         self.assertRaises(lib_exc.NotFound,
                           self.alt_client.update_server, self.server_id,
@@ -591,7 +614,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
     def test_delete_a_server_of_another_tenant(self):
-        # Delete a server that belongs to another tenant
+        """Deleting a server that belongs to another project should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.alt_client.delete_server,
                           self.server_id)
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 97813a5..d85e4f7 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -59,13 +59,17 @@
 
 
 class AttachVolumeTestJSON(BaseAttachVolumeTest):
+    """Test attaching volume to server"""
 
     @decorators.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
     # This test is conditionally marked slow if SSH validation is enabled.
     @decorators.attr(type='slow', condition=CONF.validation.run_validation)
     def test_attach_detach_volume(self):
-        # Stop and Start a server with an attached volume, ensuring that
-        # the volume remains attached.
+        """Test attaching and detaching volume from server
+
+        Stop and Start a server with an attached volume, ensuring that
+        the volume remains attached.
+        """
         server, validation_resources = self._create_server()
 
         # NOTE(andreaf) Create one remote client used throughout the test.
@@ -125,6 +129,13 @@
 
     @decorators.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
+        """Test listing and getting volume attachments
+
+        First we attach one volume to the server, check listing and getting
+        the volume attachment of the server. Then we attach another volume to
+        the server, check listing and getting the volume attachments of the
+        server. Finally we detach the volumes from the server one by one.
+        """
         # List volume attachment of the server
         server, validation_resources = self._create_server()
         volume_1st = self.create_volume()
@@ -244,8 +255,12 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
     def test_attach_volume_shelved_or_offload_server(self):
-        # Create server, count number of volumes on it, shelve
-        # server and attach pre-created volume to shelved server
+        """Test attaching volume to shelved server
+
+        Create server, count number of volumes on it, shelve
+        server and attach pre-created volume to shelved server, then
+        unshelve the server and check that attached volume exists.
+        """
         server, validation_resources = self._create_server()
         volume = self.create_volume()
         num_vol = self._count_volumes(server, validation_resources)
@@ -271,8 +286,12 @@
     @decorators.attr(type='slow')
     @decorators.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
     def test_detach_volume_shelved_or_offload_server(self):
-        # Count number of volumes on instance, shelve
-        # server and attach pre-created volume to shelved server
+        """Test detaching volume from shelved server
+
+        Count number of volumes on server, shelve server and attach
+        pre-created volume to shelved server, then detach the volume, unshelve
+        the instance and check that we have the expected number of volume(s).
+        """
         server, validation_resources = self._create_server()
         volume = self.create_volume()
         num_vol = self._count_volumes(server, validation_resources)
@@ -291,6 +310,12 @@
 
 
 class AttachVolumeMultiAttachTest(BaseAttachVolumeTest):
+    """Test attaching one volume to multiple servers
+
+    Test attaching one volume to multiple servers with compute
+    microversion greater than 2.59.
+    """
+
     min_microversion = '2.60'
     max_microversion = 'latest'
 
@@ -367,6 +392,12 @@
 
     @decorators.idempotent_id('8d5853f7-56e7-4988-9b0c-48cea3c7049a')
     def test_list_get_volume_attachments_multiattach(self):
+        """Test listing and getting multiattached volume attachments
+
+        Attach a single volume to two servers, list attachments from the
+        volume and make sure the server uuids are in the list, then detach
+        the volume from servers one by one.
+        """
         # Attach a single volume to two servers.
         servers, volume, attachments = self._create_and_multiattach()
 
@@ -448,7 +479,10 @@
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
     def test_resize_server_with_multiattached_volume(self):
-        # Attach a single volume to multiple servers, then resize the servers
+        """Test resizing servers with multiattached volume
+
+        Attach a single volume to multiple servers, then resize the servers
+        """
         servers, volume, _ = self._create_and_multiattach()
 
         for server in servers:
diff --git a/tempest/api/identity/admin/v2/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
index f3b7494..3c71ba9 100644
--- a/tempest/api/identity/admin/v2/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -20,6 +20,7 @@
 
 
 class RolesNegativeTestJSON(base.BaseIdentityV2AdminTest):
+    """Negative tests of keystone roles via v2 API"""
 
     def _get_role_params(self):
         user = self.setup_test_user()
@@ -30,14 +31,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d5d5f1df-f8ca-4de0-b2ef-259c1cc67025')
     def test_list_roles_by_unauthorized_user(self):
-        # Non-administrator user should not be able to list roles
+        """Test Non-admin user should not be able to list roles via v2 API"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_roles_client.list_roles)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('11a3c7da-df6c-40c2-abc2-badd682edf9f')
     def test_list_roles_request_without_token(self):
-        # Request to list roles without a valid token should fail
+        """Test listing roles without a valid token via v2 API should fail"""
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
         self.assertRaises(lib_exc.Unauthorized, self.roles_client.list_roles)
@@ -46,14 +47,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c0b89e56-accc-4c73-85f8-9c0f866104c1')
     def test_role_create_blank_name(self):
-        # Should not be able to create a role with a blank name
+        """Test creating a role with a blank name via v2 API is not allowed"""
         self.assertRaises(lib_exc.BadRequest, self.roles_client.create_role,
                           name='')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('585c8998-a8a4-4641-a5dd-abef7a8ced00')
     def test_create_role_by_unauthorized_user(self):
-        # Non-administrator user should not be able to create role
+        """Test non-admin user should not be able to create role via v2 API"""
         role_name = data_utils.rand_name(name='role')
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_roles_client.create_role,
@@ -62,7 +63,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a7edd17a-e34a-4aab-8bb7-fa6f498645b8')
     def test_create_role_request_without_token(self):
-        # Request to create role without a valid token should fail
+        """Test creating role without a valid token via v2 API should fail"""
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
         role_name = data_utils.rand_name(name='role')
@@ -73,7 +74,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c0cde2c8-81c1-4bb0-8fe2-cf615a3547a8')
     def test_role_create_duplicate(self):
-        # Role names should be unique
+        """Test role names should be unique via v2 API"""
         role_name = data_utils.rand_name(name='role-dup')
         body = self.roles_client.create_role(name=role_name)['role']
         role1_id = body.get('id')
@@ -84,7 +85,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('15347635-b5b1-4a87-a280-deb2bd6d865e')
     def test_delete_role_by_unauthorized_user(self):
-        # Non-administrator user should not be able to delete role
+        """Test non-admin user should not be able to delete role via v2 API"""
         role_name = data_utils.rand_name(name='role')
         body = self.roles_client.create_role(name=role_name)['role']
         self.addCleanup(self.roles_client.delete_role, body['id'])
@@ -95,7 +96,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('44b60b20-70de-4dac-beaf-a3fc2650a16b')
     def test_delete_role_request_without_token(self):
-        # Request to delete role without a valid token should fail
+        """Test deleting role without a valid token via v2 API should fail"""
         role_name = data_utils.rand_name(name='role')
         body = self.roles_client.create_role(name=role_name)['role']
         self.addCleanup(self.roles_client.delete_role, body['id'])
@@ -110,7 +111,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('38373691-8551-453a-b074-4260ad8298ef')
     def test_delete_role_non_existent(self):
-        # Attempt to delete a non existent role should fail
+        """Test deleting a non existent role via v2 API should fail"""
         non_existent_role = data_utils.rand_uuid_hex()
         self.assertRaises(lib_exc.NotFound, self.roles_client.delete_role,
                           non_existent_role)
@@ -118,8 +119,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('391df5cf-3ec3-46c9-bbe5-5cb58dd4dc41')
     def test_assign_user_role_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to
-        # assign a role to user
+        """Test non-admin user assigning a role to user via v2 API
+
+        Non-admin user should not be authorized to assign a role to user via
+        v2 API.
+        """
         (user, tenant, role) = self._get_role_params()
         self.assertRaises(
             lib_exc.Forbidden,
@@ -129,7 +133,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f0d2683c-5603-4aee-95d7-21420e87cfd8')
     def test_assign_user_role_request_without_token(self):
-        # Request to assign a role to a user without a valid token
+        """Test assigning a role to a user without a valid token via v2 API
+
+        Assigning a role to a user without a valid token via v2 API should
+        fail.
+        """
         (user, tenant, role) = self._get_role_params()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
@@ -142,7 +150,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('99b297f6-2b5d-47c7-97a9-8b6bb4f91042')
     def test_assign_user_role_for_non_existent_role(self):
-        # Attempt to assign a non existent role to user should fail
+        """Test assigning a non existent role to user via v2 API
+
+        Assigning a non existent role to user via v2 API should fail.
+        """
         (user, tenant, _) = self._get_role_params()
         non_existent_role = data_utils.rand_uuid_hex()
         self.assertRaises(lib_exc.NotFound,
@@ -152,7 +163,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b2285aaa-9e76-4704-93a9-7a8acd0a6c8f')
     def test_assign_user_role_for_non_existent_tenant(self):
-        # Attempt to assign a role on a non existent tenant should fail
+        """Test assigning a role on a non existent tenant via v2 API
+
+        Assigning a role on a non existent tenant via v2 API should fail.
+        """
         (user, _, role) = self._get_role_params()
         non_existent_tenant = data_utils.rand_uuid_hex()
         self.assertRaises(lib_exc.NotFound,
@@ -162,7 +176,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5c3132cd-c4c8-4402-b5ea-71eb44e97793')
     def test_assign_duplicate_user_role(self):
-        # Duplicate user role should not get assigned
+        """Test duplicate user role should not get assigned via v2 API"""
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -174,8 +188,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d0537987-0977-448f-a435-904c15de7298')
     def test_remove_user_role_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to
-        # remove a user's role
+        """Test non-admin user removing a user's role via v2 API
+
+        Non-admin user should not be authorized to remove a user's role via
+        v2 API
+        """
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -188,7 +205,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('cac81cf4-c1d2-47dc-90d3-f2b7eb572286')
     def test_remove_user_role_request_without_token(self):
-        # Request to remove a user's role without a valid token
+        """Test removing a user's role without a valid token via v2 API
+
+        Removing a user's role without a valid token via v2 API should fail.
+        """
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -203,7 +223,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ab32d759-cd16-41f1-a86e-44405fa9f6d2')
     def test_remove_user_role_non_existent_role(self):
-        # Attempt to delete a non existent role from a user should fail
+        """Test deleting a non existent role from a user via v2 API
+
+        Deleting a non existent role from a user via v2 API should fail.
+        """
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -216,7 +239,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('67a679ec-03dd-4551-bbfc-d1c93284f023')
     def test_remove_user_role_non_existent_tenant(self):
-        # Attempt to remove a role from a non existent tenant should fail
+        """Test removing a role from a non existent tenant via v2 API
+
+        Removing a role from a non existent tenant via v2 API should fail.
+        """
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -229,8 +255,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7391ab4c-06f3-477a-a64a-c8e55ce89837')
     def test_list_user_roles_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to list
-        # a user's roles
+        """Test non-admin user listing a user's roles via v2 API
+
+        Non-admin user should not be authorized to list a user's roles via v2
+        API.
+        """
         (user, tenant, role) = self._get_role_params()
         self.roles_client.create_user_role_on_project(tenant['id'],
                                                       user['id'],
@@ -243,7 +272,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('682adfb2-fd5f-4b0a-a9ca-322e9bebb907')
     def test_list_user_roles_request_without_token(self):
-        # Request to list user's roles without a valid token should fail
+        """Test listing user's roles without a valid token via v2 API
+
+        Listing user's roles without a valid token via v2 API should fail
+        """
         (user, tenant, _) = self._get_role_params()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index 03543ac..182b24c 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -20,6 +20,7 @@
 
 
 class ServicesTestJSON(base.BaseIdentityV2AdminTest):
+    """Test identity services via v2 API"""
 
     def _del_service(self, service_id):
         # Deleting the service created in this method
@@ -30,6 +31,7 @@
 
     @decorators.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
     def test_create_get_delete_service(self):
+        """Test verifies the identity service create/get/delete via v2 API"""
         # GET Service
         # Creating a Service
         name = data_utils.rand_name('service')
@@ -64,7 +66,10 @@
 
     @decorators.idempotent_id('5d3252c8-e555-494b-a6c8-e11d7335da42')
     def test_create_service_without_description(self):
-        # Create a service only with name and type
+        """Test creating identity service without description via v2 API
+
+        Create a service only with name and type.
+        """
         name = data_utils.rand_name('service')
         s_type = data_utils.rand_name('type')
         service = self.services_client.create_service(
@@ -79,7 +84,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('34ea6489-012d-4a86-9038-1287cadd5eca')
     def test_list_services(self):
-        # Create, List, Verify and Delete Services
+        """Test Create/List/Verify/Delete of identity service via v2 API"""
         services = []
         for _ in range(3):
             name = data_utils.rand_name('service')
diff --git a/tempest/api/identity/admin/v2/test_tenant_negative.py b/tempest/api/identity/admin/v2/test_tenant_negative.py
index 49bb949..792dad9 100644
--- a/tempest/api/identity/admin/v2/test_tenant_negative.py
+++ b/tempest/api/identity/admin/v2/test_tenant_negative.py
@@ -20,18 +20,22 @@
 
 
 class TenantsNegativeTestJSON(base.BaseIdentityV2AdminTest):
+    """Negative tests of keystone tenants via v2 API"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ca9bb202-63dd-4240-8a07-8ef9c19c04bb')
     def test_list_tenants_by_unauthorized_user(self):
-        # Non-administrator user should not be able to list tenants
+        """Test Non-admin should not be able to list tenants via v2 API"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_tenants_client.list_tenants)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('df33926c-1c96-4d8d-a762-79cc6b0c3cf4')
     def test_list_tenant_request_without_token(self):
-        # Request to list tenants without a valid token should fail
+        """Test listing tenants without a valid token via v2 API
+
+        Listing tenants without a valid token via v2 API should fail.
+        """
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
         self.assertRaises(lib_exc.Unauthorized,
@@ -41,7 +45,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('162ba316-f18b-4987-8c0c-fd9140cd63ed')
     def test_tenant_delete_by_unauthorized_user(self):
-        # Non-administrator user should not be able to delete a tenant
+        """Test non-admin should not be able to delete a tenant via v2 API"""
         tenant = self.setup_test_tenant()
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_tenants_client.delete_tenant,
@@ -50,7 +54,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e450db62-2e9d-418f-893a-54772d6386b1')
     def test_tenant_delete_request_without_token(self):
-        # Request to delete a tenant without a valid token should fail
+        """Test deleting a tenant without a valid token via v2 API
+
+        Deleting a tenant without a valid token via v2 API should fail.
+        """
         tenant = self.setup_test_tenant()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
@@ -62,14 +69,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9c9a2aed-6e3c-467a-8f5c-89da9d1b516b')
     def test_delete_non_existent_tenant(self):
-        # Attempt to delete a non existent tenant should fail
+        """Test deleting a non existent tenant via v2 API should fail"""
         self.assertRaises(lib_exc.NotFound, self.tenants_client.delete_tenant,
                           data_utils.rand_uuid_hex())
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('af16f44b-a849-46cb-9f13-a751c388f739')
     def test_tenant_create_duplicate(self):
-        # Tenant names should be unique
+        """Test tenant names should be unique via v2 API"""
         tenant_name = data_utils.rand_name(name='tenant')
         self.setup_test_tenant(name=tenant_name)
         self.assertRaises(lib_exc.Conflict, self.tenants_client.create_tenant,
@@ -78,7 +85,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d26b278a-6389-4702-8d6e-5980d80137e0')
     def test_create_tenant_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to create a tenant
+        """Test non-admin user creating a tenant via v2 API
+
+        Non-admin user should not be authorized to create a tenant via v2 API.
+        """
         tenant_name = data_utils.rand_name(name='tenant')
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_tenants_client.create_tenant,
@@ -87,7 +97,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a3ee9d7e-6920-4dd5-9321-d4b2b7f0a638')
     def test_create_tenant_request_without_token(self):
-        # Create tenant request without a token should not be authorized
+        """Test creating tenant without a token via v2 API is not allowed"""
         tenant_name = data_utils.rand_name(name='tenant')
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
@@ -99,7 +109,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5a2e4ca9-b0c0-486c-9c48-64a94fba2395')
     def test_create_tenant_with_empty_name(self):
-        # Tenant name should not be empty
+        """Test tenant name should not be empty via v2 API"""
         self.assertRaises(lib_exc.BadRequest,
                           self.tenants_client.create_tenant,
                           name='')
@@ -107,7 +117,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('2ff18d1e-dfe3-4359-9dc3-abf582c196b9')
     def test_create_tenants_name_length_over_64(self):
-        # Tenant name length should not be greater than 64 characters
+        """Test tenant name length should not exceed 64 via v2 API"""
         tenant_name = 'a' * 65
         self.assertRaises(lib_exc.BadRequest,
                           self.tenants_client.create_tenant,
@@ -116,14 +126,17 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('bd20dc2a-9557-4db7-b755-f48d952ad706')
     def test_update_non_existent_tenant(self):
-        # Attempt to update a non existent tenant should fail
+        """Test updating a non existent tenant via v2 API should fail"""
         self.assertRaises(lib_exc.NotFound, self.tenants_client.update_tenant,
                           data_utils.rand_uuid_hex())
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('41704dc5-c5f7-4f79-abfa-76e6fedc570b')
     def test_tenant_update_by_unauthorized_user(self):
-        # Non-administrator user should not be able to update a tenant
+        """Test non-admin user updating a tenant via v2 API
+
+        Non-admin user should not be able to update a tenant via v2 API
+        """
         tenant = self.setup_test_tenant()
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_tenants_client.update_tenant,
@@ -132,7 +145,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7a421573-72c7-4c22-a98e-ce539219c657')
     def test_tenant_update_request_without_token(self):
-        # Request to update a tenant without a valid token should fail
+        """Test updating a tenant without a valid token via v2 API
+
+        Updating a tenant without a valid token via v2 API should fail
+        """
         tenant = self.setup_test_tenant()
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
diff --git a/tempest/api/identity/admin/v2/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
index f68754e..5f73e1c 100644
--- a/tempest/api/identity/admin/v2/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -19,10 +19,14 @@
 
 
 class TenantsTestJSON(base.BaseIdentityV2AdminTest):
+    """Test identity tenants via v2 API"""
 
     @decorators.idempotent_id('16c6e05c-6112-4b0e-b83f-5e43f221b6b0')
     def test_tenant_list_delete(self):
-        # Create several tenants and delete them
+        """Test listing and deleting tenants via v2 API
+
+        Create several tenants and delete them
+        """
         tenants = []
         for _ in range(3):
             tenant = self.setup_test_tenant()
@@ -41,7 +45,7 @@
 
     @decorators.idempotent_id('d25e9f24-1310-4d29-b61b-d91299c21d6d')
     def test_tenant_create_with_description(self):
-        # Create tenant with a description
+        """Test creating tenant with a description via v2 API"""
         tenant_desc = data_utils.rand_name(name='desc')
         tenant = self.setup_test_tenant(description=tenant_desc)
         tenant_id = tenant['id']
@@ -56,7 +60,7 @@
 
     @decorators.idempotent_id('670bdddc-1cd7-41c7-b8e2-751cfb67df50')
     def test_tenant_create_enabled(self):
-        # Create a tenant that is enabled
+        """Test creating a tenant that is enabled via v2 API"""
         tenant = self.setup_test_tenant(enabled=True)
         tenant_id = tenant['id']
         self.assertTrue(tenant['enabled'], 'Enable should be True in response')
@@ -66,7 +70,7 @@
 
     @decorators.idempotent_id('3be22093-b30f-499d-b772-38340e5e16fb')
     def test_tenant_create_not_enabled(self):
-        # Create a tenant that is not enabled
+        """Test creating a tenant that is not enabled via v2 API"""
         tenant = self.setup_test_tenant(enabled=False)
         tenant_id = tenant['id']
         self.assertFalse(tenant['enabled'],
@@ -78,7 +82,7 @@
 
     @decorators.idempotent_id('781f2266-d128-47f3-8bdb-f70970add238')
     def test_tenant_update_name(self):
-        # Update name attribute of a tenant
+        """Test updating name attribute of a tenant via v2 API"""
         t_name1 = data_utils.rand_name(name='tenant')
         tenant = self.setup_test_tenant(name=t_name1)
         t_id = tenant['id']
@@ -100,7 +104,7 @@
 
     @decorators.idempotent_id('859fcfe1-3a03-41ef-86f9-b19a47d1cd87')
     def test_tenant_update_desc(self):
-        # Update description attribute of a tenant
+        """Test updating description attribute of a tenant via v2 API"""
         t_desc = data_utils.rand_name(name='desc')
         tenant = self.setup_test_tenant(description=t_desc)
         t_id = tenant['id']
@@ -123,7 +127,7 @@
 
     @decorators.idempotent_id('8fc8981f-f12d-4c66-9972-2bdcf2bc2e1a')
     def test_tenant_update_enable(self):
-        # Update the enabled attribute of a tenant
+        """Test updating the enabled attribute of a tenant via v2 API"""
         t_en = False
         tenant = self.setup_test_tenant(enabled=t_en)
         t_id = tenant['id']
diff --git a/tempest/api/identity/admin/v2/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
index 6ce1a8b..5d89f9d 100644
--- a/tempest/api/identity/admin/v2/test_tokens.py
+++ b/tempest/api/identity/admin/v2/test_tokens.py
@@ -23,9 +23,11 @@
 
 
 class TokensTestJSON(base.BaseIdentityV2AdminTest):
+    """Test keystone tokens via v2 API"""
 
     @decorators.idempotent_id('453ad4d5-e486-4b2f-be72-cffc8149e586')
     def test_create_check_get_delete_token(self):
+        """Test getting create/check/get/delete token for user via v2 API"""
         # get a token by username and password
         user_name = data_utils.rand_name(name='user')
         user_password = data_utils.rand_password()
@@ -59,7 +61,7 @@
 
     @decorators.idempotent_id('25ba82ee-8a32-4ceb-8f50-8b8c71e8765e')
     def test_rescope_token(self):
-        """An unscoped token can be requested
+        """Test an unscoped token can be requested via v2 API
 
         That token can be used to request a scoped token.
         """
@@ -112,6 +114,7 @@
 
     @decorators.idempotent_id('ca3ea6f7-ed08-4a61-adbd-96906456ad31')
     def test_list_endpoints_for_token(self):
+        """Test listing endpoints for token via v2 API"""
         tempest_services = ['keystone', 'nova', 'neutron', 'swift', 'cinder',
                             'neutron']
         # get a token for the user
diff --git a/tempest/api/identity/admin/v2/test_tokens_negative.py b/tempest/api/identity/admin/v2/test_tokens_negative.py
index eb3e365..f2e41ff 100644
--- a/tempest/api/identity/admin/v2/test_tokens_negative.py
+++ b/tempest/api/identity/admin/v2/test_tokens_negative.py
@@ -19,12 +19,17 @@
 
 
 class TokensAdminTestNegative(base.BaseIdentityV2AdminTest):
+    """Negative tests of keystone tokens via v2 API"""
 
     credentials = ['primary', 'admin', 'alt']
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a0a0a600-4292-4364-99c5-922c834fdf05')
     def test_check_token_existence_negative(self):
+        """Test checking other tenant's token existence via v2 API
+
+        Checking other tenant's token existence via v2 API should fail.
+        """
         creds = self.os_primary.credentials
         creds_alt = self.os_alt.credentials
         username = creds.username
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 0d98af5..57a321a 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -23,6 +23,7 @@
 
 
 class UsersTestJSON(base.BaseIdentityV2AdminTest):
+    """Test keystone users via v2 API"""
 
     @classmethod
     def resource_setup(cls):
@@ -33,14 +34,14 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('2d55a71e-da1d-4b43-9c03-d269fd93d905')
     def test_create_user(self):
-        # Create a user
+        """Test creating a user via v2 API"""
         tenant = self.setup_test_tenant()
         user = self.create_test_user(name=self.alt_user, tenantId=tenant['id'])
         self.assertEqual(self.alt_user, user['name'])
 
     @decorators.idempotent_id('89d9fdb8-15c2-4304-a429-48715d0af33d')
     def test_create_user_with_enabled(self):
-        # Create a user with enabled : False
+        """Test creating a user with enabled : False via v2 API"""
         tenant = self.setup_test_tenant()
         name = data_utils.rand_name('test_user')
         user = self.create_test_user(name=name,
@@ -53,7 +54,7 @@
 
     @decorators.idempotent_id('39d05857-e8a5-4ed4-ba83-0b52d3ab97ee')
     def test_update_user(self):
-        # Test case to check if updating of user attributes is successful.
+        """Test updating user attributes via v2 API"""
         tenant = self.setup_test_tenant()
         user = self.create_test_user(tenantId=tenant['id'])
 
@@ -75,14 +76,14 @@
 
     @decorators.idempotent_id('29ed26f4-a74e-4425-9a85-fdb49fa269d2')
     def test_delete_user(self):
-        # Delete a user
+        """Test deleting a user via v2 API"""
         tenant = self.setup_test_tenant()
         user = self.create_test_user(tenantId=tenant['id'])
         self.users_client.delete_user(user['id'])
 
     @decorators.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
     def test_user_authentication(self):
-        # Valid user's token is authenticated
+        """Test that valid user's token is authenticated via v2 API"""
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
@@ -97,6 +98,7 @@
 
     @decorators.idempotent_id('5d1fa498-4c2d-4732-a8fe-2b054598cfdd')
     def test_authentication_request_without_token(self):
+        """Test authentication request without token via v2 API"""
         # Request for token authentication with a valid token in header
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
@@ -116,7 +118,10 @@
 
     @decorators.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
     def test_get_users(self):
-        # Get a list of users and find the test user
+        """Test getting users via v2 API
+
+        Get a list of users and find the test user
+        """
         user = self.setup_test_user()
         users = self.users_client.list_users()['users']
         self.assertThat([u['name'] for u in users],
@@ -125,7 +130,7 @@
 
     @decorators.idempotent_id('6e317209-383a-4bed-9f10-075b7c82c79a')
     def test_list_users_for_tenant(self):
-        # Return a list of all users for a tenant
+        """Test returning a list of all users for a tenant via v2 API"""
         tenant = self.setup_test_tenant()
         user_ids = list()
         fetched_user_ids = list()
@@ -147,7 +152,7 @@
 
     @decorators.idempotent_id('a8b54974-40e1-41c0-b812-50fc90827971')
     def test_list_users_with_roles_for_tenant(self):
-        # Return list of users on tenant when roles are assigned to users
+        """Test listing users on tenant with roles assigned via v2 API"""
         user = self.setup_test_user()
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
         role = self.setup_test_role()
@@ -175,7 +180,7 @@
 
     @decorators.idempotent_id('1aeb25ac-6ec5-4d8b-97cb-7ac3567a989f')
     def test_update_user_password(self):
-        # Test case to check if updating of user password is successful.
+        """Test updating of user password via v2 API"""
         user = self.setup_test_user()
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
         # Updating the user with new password
diff --git a/tempest/api/identity/admin/v2/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
index 4f47e41..eda1fdd 100644
--- a/tempest/api/identity/admin/v2/test_users_negative.py
+++ b/tempest/api/identity/admin/v2/test_users_negative.py
@@ -20,6 +20,7 @@
 
 
 class UsersNegativeTestJSON(base.BaseIdentityV2AdminTest):
+    """Negative tests of identity users via v2 API"""
 
     @classmethod
     def resource_setup(cls):
@@ -31,7 +32,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('60a1f5fa-5744-4cdf-82bf-60b7de2d29a4')
     def test_create_user_by_unauthorized_user(self):
-        # Non-administrator should not be authorized to create a user
+        """Non-admin should not be authorized to create a user via v2 API"""
         tenant = self.setup_test_tenant()
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_users_client.create_user,
@@ -42,7 +43,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d80d0c2f-4514-4d1e-806d-0930dfc5a187')
     def test_create_user_with_empty_name(self):
-        # User with an empty name should not be created
+        """User with an empty name should not be created via v2 API"""
         tenant = self.setup_test_tenant()
         self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
                           name='', password=self.alt_password,
@@ -52,7 +53,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7704b4f3-3b75-4b82-87cc-931d41c8f780')
     def test_create_user_with_name_length_over_255(self):
-        # Length of user name filed should be restricted to 255 characters
+        """Length of user name should not exceed 255 via v2 API"""
         tenant = self.setup_test_tenant()
         self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
                           name='a' * 256, password=self.alt_password,
@@ -62,7 +63,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('57ae8558-120c-4723-9308-3751474e7ecf')
     def test_create_user_with_duplicate_name(self):
-        # Duplicate user should not be created
+        """Duplicate user should not be created via v2 API"""
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
@@ -75,7 +76,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0132cc22-7c4f-42e1-9e50-ac6aad31d59a')
     def test_create_user_for_non_existent_tenant(self):
-        # Attempt to create a user in a non-existent tenant should fail
+        """Creating a user in a non-existent tenant via v2 API should fail"""
         self.assertRaises(lib_exc.NotFound, self.users_client.create_user,
                           name=self.alt_user,
                           password=self.alt_password,
@@ -85,7 +86,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('55bbb103-d1ae-437b-989b-bcdf8175c1f4')
     def test_create_user_request_without_a_token(self):
-        # Request to create a user without a valid token should fail
+        """Creating a user without a valid token via v2 API should fail"""
         tenant = self.setup_test_tenant()
         # Get the token of the current client
         token = self.client.auth_provider.get_token()
@@ -103,7 +104,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('23a2f3da-4a1a-41da-abdd-632328a861ad')
     def test_create_user_with_enabled_non_bool(self):
-        # Attempt to create a user with valid enabled para should fail
+        """Creating a user with invalid enabled para via v2 API should fail"""
         tenant = self.setup_test_tenant()
         name = data_utils.rand_name('test_user')
         self.assertRaises(lib_exc.BadRequest, self.users_client.create_user,
@@ -114,7 +115,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('3d07e294-27a0-4144-b780-a2a1bf6fee19')
     def test_update_user_for_non_existent_user(self):
-        # Attempt to update a user non-existent user should fail
+        """Updating a non-existent user via v2 API should fail"""
         user_name = data_utils.rand_name('user')
         non_existent_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.users_client.update_user,
@@ -123,7 +124,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('3cc2a64b-83aa-4b02-88f0-d6ab737c4466')
     def test_update_user_request_without_a_token(self):
-        # Request to update a user without a valid token should fail
+        """Updating a user without a valid token via v2 API should fail"""
 
         # Get the token of the current client
         token = self.client.auth_provider.get_token()
@@ -139,7 +140,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('424868d5-18a7-43e1-8903-a64f95ee3aac')
     def test_update_user_by_unauthorized_user(self):
-        # Non-administrator should not be authorized to update user
+        """Non-admin should not be authorized to update user via v2 API"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_users_client.update_user,
                           self.alt_user)
@@ -147,7 +148,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d45195d5-33ed-41b9-a452-7d0d6a00f6e9')
     def test_delete_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to delete a user
+        """Non-admin should not be authorized to delete a user via v2 API"""
         user = self.setup_test_user()
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_users_client.delete_user,
@@ -156,14 +157,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7cc82f7e-9998-4f89-abae-23df36495867')
     def test_delete_non_existent_user(self):
-        # Attempt to delete a non-existent user should fail
+        """Attempt to delete a non-existent user via v2 API should fail"""
         self.assertRaises(lib_exc.NotFound, self.users_client.delete_user,
                           'junk12345123')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('57fe1df8-0aa7-46c0-ae9f-c2e785c7504a')
     def test_delete_user_request_without_a_token(self):
-        # Request to delete a user without a valid token should fail
+        """Deleting a user without a valid token via v2 API should fail"""
 
         # Get the token of the current client
         token = self.client.auth_provider.get_token()
@@ -179,7 +180,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('593a4981-f6d4-460a-99a1-57a78bf20829')
     def test_authentication_for_disabled_user(self):
-        # Disabled user's token should not get authenticated
+        """Disabled user's token should not get authenticated via v2 API"""
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
@@ -192,7 +193,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('440a7a8d-9328-4b7b-83e0-d717010495e4')
     def test_authentication_when_tenant_is_disabled(self):
-        # User's token for a disabled tenant should not be authenticated
+        """Test User's token for a disabled tenant via v2 API
+
+        User's token for a disabled tenant should not be authenticated via
+        v2 API.
+        """
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
@@ -205,7 +210,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('921f1ad6-7907-40b8-853f-637e7ee52178')
     def test_authentication_with_invalid_tenant(self):
-        # User's token for an invalid tenant should not be authenticated
+        """Test User's token for an invalid tenant via v2 API
+
+        User's token for an invalid tenant should not be authenticated via V2
+        API.
+        """
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
@@ -216,7 +225,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('bde9aecd-3b1c-4079-858f-beb5deaa5b5e')
     def test_authentication_with_invalid_username(self):
-        # Non-existent user's token should not get authenticated
+        """Non-existent user's token should not get authorized via v2 API"""
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
@@ -226,7 +235,11 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d5308b33-3574-43c3-8d87-1c090c5e1eca')
     def test_authentication_with_invalid_password(self):
-        # User's token with invalid password should not be authenticated
+        """Test User's token with invalid password via v2 API
+
+        User's token with invalid password should not be authenticated via V2
+        API.
+        """
         user = self.setup_test_user()
         tenant = self.tenants_client.show_tenant(user['tenantId'])['tenant']
         self.assertRaises(lib_exc.Unauthorized, self.token_client.auth,
@@ -235,14 +248,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('284192ce-fb7c-4909-a63b-9a502e0ddd11')
     def test_get_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to get user list
+        """Non-admin should not be authorized to get user list via v2 API"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_users_client.list_users)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a73591ec-1903-4ffe-be42-282b39fefc9d')
     def test_get_users_request_without_token(self):
-        # Request to get list of users without a valid token should fail
+        """Listing users without a valid token via v2 API should fail"""
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
 
@@ -254,8 +267,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('f5d39046-fc5f-425c-b29e-bac2632da28e')
     def test_list_users_with_invalid_tenant(self):
-        # Should not be able to return a list of all
-        # users for a non-existent tenant
+        """Listing users for a non-existent tenant via v2 API should fail"""
         # Assign invalid tenant ids
         invalid_id = list()
         invalid_id.append(data_utils.rand_name('999'))
diff --git a/tempest/api/identity/admin/v3/test_application_credentials.py b/tempest/api/identity/admin/v3/test_application_credentials.py
index 7e802c6..c9cafd8 100644
--- a/tempest/api/identity/admin/v3/test_application_credentials.py
+++ b/tempest/api/identity/admin/v3/test_application_credentials.py
@@ -20,9 +20,11 @@
 
 class ApplicationCredentialsV3AdminTest(base.BaseApplicationCredentialsV3Test,
                                         base.BaseIdentityV3AdminTest):
+    """Test keystone application credentials"""
 
     @decorators.idempotent_id('3b3dd48f-3388-406a-a9e6-4d078a552d0e')
     def test_create_application_credential_with_roles(self):
+        """Test creating keystone application credential with roles"""
         role = self.setup_test_role()
         self.os_admin.roles_v3_client.create_user_role_on_project(
             self.project_id,
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 23fe788..441f10f 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -20,6 +20,8 @@
 
 
 class CredentialsTestJSON(base.BaseIdentityV3AdminTest):
+    """Test keystone credentials"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -47,6 +49,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('7cd59bf9-bda4-4c72-9467-d21cab278355')
     def test_credentials_create_get_update_delete(self):
+        """Test creating, getting, updating, deleting of credentials"""
         blob = '{"access": "%s", "secret": "%s"}' % (
             data_utils.rand_name('Access'), data_utils.rand_name('Secret'))
         cred = self.creds_client.create_credential(
@@ -82,6 +85,7 @@
 
     @decorators.idempotent_id('13202c00-0021-42a1-88d4-81b44d448aab')
     def test_credentials_list_delete(self):
+        """Test listing credentials"""
         created_cred_ids = list()
         fetched_cred_ids = list()
 
diff --git a/tempest/api/identity/admin/v3/test_domain_configuration.py b/tempest/api/identity/admin/v3/test_domain_configuration.py
index c0b18ca..a246a36 100644
--- a/tempest/api/identity/admin/v3/test_domain_configuration.py
+++ b/tempest/api/identity/admin/v3/test_domain_configuration.py
@@ -21,6 +21,8 @@
 
 
 class DomainConfigurationTestJSON(base.BaseIdentityV3AdminTest):
+    """Test domain configuration"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -51,10 +53,12 @@
 
     @decorators.idempotent_id('11a02bf0-6f94-4380-b3b0-c8dc18fc0d22')
     def test_show_default_group_config_and_options(self):
-        # The API supports only the identity and ldap groups. For the ldap
-        # group, a valid value is url or user_tree_dn. For the identity group,
-        # a valid value is driver.
+        """Test showing default keystone group config and options
 
+        The API supports only the identity and ldap groups. For the ldap
+        group, a valid value is url or user_tree_dn. For the identity group,
+        a valid value is driver.
+        """
         # Check that the default config has the identity and ldap groups.
         config = self.client.show_default_config_settings()['config']
         self.assertIsInstance(config, dict)
@@ -93,6 +97,7 @@
 
     @decorators.idempotent_id('9e3ff13c-f597-4f01-9377-d6c06c2a1477')
     def test_create_domain_config_and_show_config_groups_and_options(self):
+        """Test creating and showing keystone config groups and options"""
         domain, created_config = self._create_domain_and_config(
             self.custom_config)
 
@@ -117,6 +122,7 @@
 
     @decorators.idempotent_id('7161023e-5dd0-4612-9da0-1bac6ac30b63')
     def test_create_update_and_delete_domain_config(self):
+        """Test creating, updating and deleting keystone domain config"""
         domain, created_config = self._create_domain_and_config(
             self.custom_config)
 
@@ -140,6 +146,7 @@
 
     @decorators.idempotent_id('c7510fa2-6661-4170-9c6b-4783a80651e9')
     def test_create_update_and_delete_domain_config_groups_and_opts(self):
+        """Test create/update/delete keystone domain config groups and opts"""
         domain, _ = self._create_domain_and_config(self.custom_config)
 
         # Check that updating configuration groups work.
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 07175f4..32ccb9e 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -24,6 +24,7 @@
 
 
 class DomainsTestJSON(base.BaseIdentityV3AdminTest):
+    """Test identity domains"""
 
     @classmethod
     def resource_setup(cls):
@@ -37,7 +38,7 @@
 
     @decorators.idempotent_id('8cf516ef-2114-48f1-907b-d32726c734d4')
     def test_list_domains(self):
-        # Test to list domains
+        """Test listing domains"""
         fetched_ids = list()
         # List and Verify Domains
         body = self.domains_client.list_domains()['domains']
@@ -49,7 +50,7 @@
 
     @decorators.idempotent_id('c6aee07b-4981-440c-bb0b-eb598f58ffe9')
     def test_list_domains_filter_by_name(self):
-        # List domains filtering by name
+        """Test listing domains filtering by name"""
         params = {'name': self.setup_domains[0]['name']}
         fetched_domains = self.domains_client.list_domains(
             **params)['domains']
@@ -61,7 +62,7 @@
 
     @decorators.idempotent_id('3fd19840-65c1-43f8-b48c-51bdd066dff9')
     def test_list_domains_filter_by_enabled(self):
-        # List domains filtering by enabled domains
+        """Test listing domains filtering by enabled domains"""
         params = {'enabled': True}
         fetched_domains = self.domains_client.list_domains(
             **params)['domains']
@@ -74,6 +75,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('f2f5b44a-82e8-4dad-8084-0661ea3b18cf')
     def test_create_update_delete_domain(self):
+        """Test creating, updating and deleting domain"""
         # Create domain
         d_name = data_utils.rand_name('domain')
         d_desc = data_utils.rand_name('domain-desc')
@@ -118,6 +120,7 @@
 
     @decorators.idempotent_id('d8d318b7-d1b3-4c37-94c5-3c5ba0b121ea')
     def test_domain_delete_cascades_content(self):
+        """Test deleting domain will delete its associated contents"""
         # Create a domain with a user and a group in it
         domain = self.setup_test_domain()
         user = self.create_test_user(domain_id=domain['id'])
@@ -134,6 +137,7 @@
 
     @decorators.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
     def test_create_domain_with_disabled_status(self):
+        """Test creating domain with disabled status"""
         # Create domain with enabled status as false
         d_name = data_utils.rand_name('domain')
         d_desc = data_utils.rand_name('domain-desc')
@@ -146,6 +150,7 @@
 
     @decorators.idempotent_id('2abf8764-309a-4fa9-bc58-201b799817ad')
     def test_create_domain_without_description(self):
+        """Test creating domain without description"""
         # Create domain only with name
         d_name = data_utils.rand_name('domain')
         domain = self.domains_client.create_domain(name=d_name)['domain']
diff --git a/tempest/api/identity/admin/v3/test_domains_negative.py b/tempest/api/identity/admin/v3/test_domains_negative.py
index b3c68fb..c90206d 100644
--- a/tempest/api/identity/admin/v3/test_domains_negative.py
+++ b/tempest/api/identity/admin/v3/test_domains_negative.py
@@ -20,6 +20,8 @@
 
 
 class DomainsNegativeTestJSON(base.BaseIdentityV3AdminTest):
+    """Negative tests of identity domains"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -28,6 +30,7 @@
     @decorators.attr(type=['negative', 'gate'])
     @decorators.idempotent_id('1f3fbff5-4e44-400d-9ca1-d953f05f609b')
     def test_delete_active_domain(self):
+        """Test deleting active domain should fail"""
         domain = self.create_domain()
         domain_id = domain['id']
 
@@ -40,14 +43,20 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9018461d-7d24-408d-b3fe-ae37e8cd5c9e')
     def test_create_domain_with_empty_name(self):
-        # Domain name should not be empty
+        """Test creating domain with empty name should fail
+
+        Domain name should not be empty
+        """
         self.assertRaises(lib_exc.BadRequest,
                           self.domains_client.create_domain, name='')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('37b1bbf2-d664-4785-9a11-333438586eae')
     def test_create_domain_with_name_length_over_64(self):
-        # Domain name length should not ne greater than 64 characters
+        """Test creating domain with name over length
+
+        Domain name length should not ne greater than 64 characters
+        """
         d_name = 'a' * 65
         self.assertRaises(lib_exc.BadRequest,
                           self.domains_client.create_domain,
@@ -56,13 +65,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('43781c07-764f-4cf2-a405-953c1916f605')
     def test_delete_non_existent_domain(self):
-        # Attempt to delete a non existent domain should fail
+        """Test attempting to delete a non existent domain should fail"""
         self.assertRaises(lib_exc.NotFound, self.domains_client.delete_domain,
                           data_utils.rand_uuid_hex())
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e6f9e4a2-4f36-4be8-bdbc-4e199ae29427')
     def test_domain_create_duplicate(self):
+        """Test creating domain with duplicate name should fail"""
         domain_name = data_utils.rand_name('domain-dup')
         domain = self.domains_client.create_domain(name=domain_name)['domain']
         domain_id = domain['id']
diff --git a/tempest/api/identity/admin/v3/test_endpoint_groups.py b/tempest/api/identity/admin/v3/test_endpoint_groups.py
index 7d85dc9..2fa92e3 100644
--- a/tempest/api/identity/admin/v3/test_endpoint_groups.py
+++ b/tempest/api/identity/admin/v3/test_endpoint_groups.py
@@ -20,6 +20,8 @@
 
 
 class EndPointGroupsTest(base.BaseIdentityV3AdminTest):
+    """Test endpoint groups"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -68,6 +70,7 @@
 
     @decorators.idempotent_id('7c69e7a1-f865-402d-a2ea-44493017315a')
     def test_create_list_show_check_delete_endpoint_group(self):
+        """Test create/list/show/check/delete of endpoint group"""
         service_id = self._create_service()
         self.addCleanup(self.services_client.delete_service, service_id)
         name = data_utils.rand_name('service_group')
@@ -127,6 +130,7 @@
 
     @decorators.idempotent_id('51c8fc38-fa84-4e76-b5b6-6fc37770fb26')
     def test_update_endpoint_group(self):
+        """Test updating endpoint group"""
         # Creating an endpoint group so as to check update endpoint group
         # with new values
         service1_id = self._create_service()
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 366d6a0..0199d73 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -20,6 +20,8 @@
 
 
 class EndPointsTestJSON(base.BaseIdentityV3AdminTest):
+    """Test keystone endpoints"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -71,6 +73,7 @@
 
     @decorators.idempotent_id('c19ecf90-240e-4e23-9966-21cee3f6a618')
     def test_list_endpoints(self):
+        """Test listing keystone endpoints by filters"""
         # Get the list of all the endpoints.
         fetched_endpoints = self.client.list_endpoints()['endpoints']
         fetched_endpoint_ids = [e['id'] for e in fetched_endpoints]
@@ -111,6 +114,7 @@
 
     @decorators.idempotent_id('0e2446d2-c1fd-461b-a729-b9e73e3e3b37')
     def test_create_list_show_delete_endpoint(self):
+        """Test creating, listing, showing and deleting keystone endpoint"""
         region_name = data_utils.rand_name('region')
         url = data_utils.rand_url()
         interface = 'public'
@@ -152,6 +156,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('37e8f15e-ee7c-4657-a1e7-f6b61e375eff')
     def test_update_endpoint(self):
+        """Test updating keystone endpoint"""
         # NOTE(zhufl) Service2 should be created before endpoint_for_update
         # is created, because Service2 must be deleted after
         # endpoint_for_update is deleted, otherwise we will get a 404 error
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 164b577..9689d87 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -20,6 +20,8 @@
 
 
 class EndpointsNegativeTestJSON(base.BaseIdentityV3AdminTest):
+    """Negative tests of endpoint"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -48,7 +50,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('ac6c137e-4d3d-448f-8c83-4f13d0942651')
     def test_create_with_enabled_False(self):
-        # Enabled should be a boolean, not a string like 'False'
+        """Test creating endpoint with invalid enabled value 'False'
+
+        Enabled should be a boolean, not a string like 'False'
+        """
         interface = 'public'
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
@@ -59,7 +64,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9c43181e-0627-484a-8c79-923e8a59598b')
     def test_create_with_enabled_True(self):
-        # Enabled should be a boolean, not a string like 'True'
+        """Test creating endpoint with invalid enabled value 'True'
+
+        Enabled should be a boolean, not a string like 'True'
+        """
         interface = 'public'
         url = data_utils.rand_url()
         region = data_utils.rand_name('region')
@@ -88,11 +96,17 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('65e41f32-5eb7-498f-a92a-a6ccacf7439a')
     def test_update_with_enabled_False(self):
-        # Enabled should be a boolean, not a string like 'False'
+        """Test updating endpoint with invalid enabled value 'False'
+
+        Enabled should be a boolean, not a string like 'False'
+        """
         self._assert_update_raises_bad_request('False')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('faba3587-f066-4757-a48e-b4a3f01803bb')
     def test_update_with_enabled_True(self):
-        # Enabled should be a boolean, not a string like 'True'
+        """Test updating endpoint with invalid enabled value 'True'
+
+        Enabled should be a boolean, not a string like 'True'
+        """
         self._assert_update_raises_bad_request('True')
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 2dd1fe2..b2e3775 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -23,6 +23,8 @@
 
 
 class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
+    """Test keystone groups"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -35,6 +37,7 @@
 
     @decorators.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
     def test_group_create_update_get(self):
+        """Test creating, updating and getting keystone group"""
         # Verify group creation works.
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
@@ -78,6 +81,7 @@
                       'immutable user source and solely '
                       'provides read-only access to users.')
     def test_group_users_add_list_delete(self):
+        """Test adding/listing/deleting group users"""
         group = self.setup_test_group(domain_id=self.domain['id'])
         # add user into group
         users = []
@@ -104,6 +108,7 @@
                       'immutable user source and solely '
                       'provides read-only access to users.')
     def test_list_user_groups(self):
+        """Test listing user groups when the user is in two groups"""
         # create a user
         user = self.create_test_user()
         # create two groups, and add user into them
@@ -127,7 +132,7 @@
 
     @decorators.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
     def test_list_groups(self):
-        # Test to list groups
+        """Test listing groups"""
         group_ids = list()
         fetched_ids = list()
         for _ in range(3):
diff --git a/tempest/api/identity/admin/v3/test_inherits.py b/tempest/api/identity/admin/v3/test_inherits.py
index 2672f71..cababc6 100644
--- a/tempest/api/identity/admin/v3/test_inherits.py
+++ b/tempest/api/identity/admin/v3/test_inherits.py
@@ -21,6 +21,8 @@
 
 
 class InheritsV3TestJSON(base.BaseIdentityV3AdminTest):
+    """Test keystone inherits"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -72,6 +74,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_inherit_assign_list_check_revoke_roles_on_domains_user(self):
+        """Test assign/list/check/revoke inherited role on domain user"""
         # Create role
         src_role = self.setup_test_role()
         # Assign role on domains user
@@ -96,6 +99,7 @@
 
     @decorators.idempotent_id('c7a8dda2-be50-4fb4-9a9c-e830771078b1')
     def test_inherit_assign_list_check_revoke_roles_on_domains_group(self):
+        """Test assign/list/check/revoke inherited role on domain group"""
         # Create role
         src_role = self.setup_test_role()
         # Assign role on domains group
@@ -123,6 +127,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_inherit_assign_check_revoke_roles_on_projects_user(self):
+        """Test assign/list/check/revoke inherited role on project user"""
         # Create role
         src_role = self.setup_test_role()
         # Assign role on projects user
@@ -138,6 +143,7 @@
 
     @decorators.idempotent_id('26021436-d5a4-4256-943c-ded01e0d4b45')
     def test_inherit_assign_check_revoke_roles_on_projects_group(self):
+        """Test assign/list/check/revoke inherited role on project group"""
         # Create role
         src_role = self.setup_test_role()
         # Assign role on projects group
@@ -157,6 +163,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_inherit_assign_list_revoke_user_roles_on_domain(self):
+        """Test assign/list/check/revoke inherited role on domain"""
         # Create role
         src_role = self.setup_test_role()
 
@@ -204,6 +211,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_inherit_assign_list_revoke_user_roles_on_project_tree(self):
+        """Test assign/list/check/revoke inherited role on project tree"""
         # Create role
         src_role = self.setup_test_role()
 
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index cb8ea11..b33d8bd 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -40,6 +40,7 @@
 
 
 class ListProjectsTestJSON(BaseListProjectsTestJSON):
+    """Test listing projects"""
 
     @classmethod
     def resource_setup(cls):
@@ -65,13 +66,13 @@
 
     @decorators.idempotent_id('0fe7a334-675a-4509-b00e-1c4b95d5dae8')
     def test_list_projects_with_enabled(self):
-        # List the projects with enabled
+        """Test listing the projects with enabled"""
         self._list_projects_with_params(
             [self.p1], [self.p2, self.p3], {'enabled': False}, 'enabled')
 
     @decorators.idempotent_id('6edc66f5-2941-4a17-9526-4073311c1fac')
     def test_list_projects_with_parent(self):
-        # List projects with parent
+        """Test listing projects with parent"""
         params = {'parent_id': self.p3['parent_id']}
         fetched_projects = self.projects_client.list_projects(
             params)['projects']
@@ -81,6 +82,11 @@
 
 
 class ListProjectsStaticTestJSON(BaseListProjectsTestJSON):
+    """Test listing projects
+
+    These tests can be executed in clouds using the pre-provisioned users
+    """
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -102,7 +108,7 @@
 
     @decorators.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
     def test_list_projects(self):
-        # List projects
+        """Test listing projects"""
         list_projects = self.projects_client.list_projects()['projects']
 
         for p in [self.p1, self.p2]:
@@ -112,13 +118,13 @@
 
     @decorators.idempotent_id('fa178524-4e6d-4925-907c-7ab9f42c7e26')
     def test_list_projects_with_name(self):
-        # List projects with name
+        """Test listing projects filtered by name"""
         self._list_projects_with_params(
             [self.p1], [self.p2], {'name': self.p1['name']}, 'name')
 
     @decorators.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
     def test_list_projects_with_domains(self):
-        # Verify project list filtered by domain
+        """Test listing projects filtered by domain"""
         key = 'domain_id'
         for p in [self.p1, self.p2]:
             params = {key: p[key]}
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index e46145d..be1216a 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -23,6 +23,8 @@
 
 
 class ProjectsTestJSON(base.BaseIdentityV3AdminTest):
+    """Test identity projects"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -30,7 +32,7 @@
 
     @decorators.idempotent_id('0ecf465c-0dc4-4532-ab53-91ffeb74d12d')
     def test_project_create_with_description(self):
-        # Create project with a description
+        """Test creating project with a description"""
         project_desc = data_utils.rand_name('desc')
         project = self.setup_test_project(description=project_desc)
         project_id = project['id']
@@ -44,7 +46,7 @@
 
     @decorators.idempotent_id('5f50fe07-8166-430b-a882-3b2ee0abe26f')
     def test_project_create_with_domain(self):
-        # Create project with a domain
+        """Test creating project with a domain"""
         domain = self.setup_test_domain()
         project_name = data_utils.rand_name('project')
         project = self.setup_test_project(
@@ -58,7 +60,7 @@
 
     @decorators.idempotent_id('1854f9c0-70bc-4d11-a08a-1c789d339e3d')
     def test_project_create_with_parent(self):
-        # Create root project without providing a parent_id
+        """Test creating root project without providing a parent_id"""
         domain = self.setup_test_domain()
         domain_id = domain['id']
 
@@ -83,6 +85,7 @@
 
     @decorators.idempotent_id('a7eb9416-6f9b-4dbb-b71b-7f73aaef59d5')
     def test_create_is_domain_project(self):
+        """Test creating is_domain project"""
         project = self.setup_test_project(domain_id=None, is_domain=True)
         # To delete a domain, we need to disable it first
         self.addCleanup(self.projects_client.update_project, project['id'],
@@ -103,7 +106,7 @@
 
     @decorators.idempotent_id('1f66dc76-50cc-4741-a200-af984509e480')
     def test_project_create_enabled(self):
-        # Create a project that is enabled
+        """Test creating a project that is enabled"""
         project = self.setup_test_project(enabled=True)
         project_id = project['id']
         self.assertTrue(project['enabled'],
@@ -113,7 +116,7 @@
 
     @decorators.idempotent_id('78f96a9c-e0e0-4ee6-a3ba-fbf6dfd03207')
     def test_project_create_not_enabled(self):
-        # Create a project that is not enabled
+        """Test creating a project that is not enabled"""
         project = self.setup_test_project(enabled=False)
         self.assertFalse(project['enabled'],
                          'Enable should be False in response')
@@ -123,7 +126,7 @@
 
     @decorators.idempotent_id('f608f368-048c-496b-ad63-d286c26dab6b')
     def test_project_update_name(self):
-        # Update name attribute of a project
+        """Test updating name attribute of a project"""
         p_name1 = data_utils.rand_name('project')
         project = self.setup_test_project(name=p_name1)
 
@@ -144,7 +147,7 @@
 
     @decorators.idempotent_id('f138b715-255e-4a7d-871d-351e1ef2e153')
     def test_project_update_desc(self):
-        # Update description attribute of a project
+        """Test updating description attribute of a project"""
         p_desc = data_utils.rand_name('desc')
         project = self.setup_test_project(description=p_desc)
         resp1_desc = project['description']
@@ -164,7 +167,7 @@
 
     @decorators.idempotent_id('b6b25683-c97f-474d-a595-55d410b68100')
     def test_project_update_enable(self):
-        # Update the enabled attribute of a project
+        """Test updating the enabled attribute of a project"""
         p_en = False
         project = self.setup_test_project(enabled=p_en)
 
@@ -189,7 +192,7 @@
                       'immutable user source and solely '
                       'provides read-only access to users.')
     def test_associate_user_to_project(self):
-        # Associate a user to a project
+        """Test associating a user to a project"""
         # Create a Project
         project = self.setup_test_project()
 
@@ -215,6 +218,7 @@
 
     @decorators.idempotent_id('d1db68b6-aebe-4fa0-b79d-d724d2e21162')
     def test_project_get_equals_list(self):
+        """Test the result of getting project equals that of listing"""
         fields = ['parent_id', 'is_domain', 'description', 'links',
                   'name', 'enabled', 'domain_id', 'id', 'tags']
 
diff --git a/tempest/api/identity/admin/v3/test_projects_negative.py b/tempest/api/identity/admin/v3/test_projects_negative.py
index 12f1d4a..79e3d29 100644
--- a/tempest/api/identity/admin/v3/test_projects_negative.py
+++ b/tempest/api/identity/admin/v3/test_projects_negative.py
@@ -20,11 +20,12 @@
 
 
 class ProjectsNegativeTestJSON(base.BaseIdentityV3AdminTest):
+    """Negative tests of projects"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('8d68c012-89e0-4394-8d6b-ccd7196def97')
     def test_project_delete_by_unauthorized_user(self):
-        # Non-admin user should not be able to delete a project
+        """Non-admin user should not be able to delete a project"""
         project = self.setup_test_project()
         self.assertRaises(
             lib_exc.Forbidden, self.non_admin_projects_client.delete_project,
@@ -32,6 +33,11 @@
 
 
 class ProjectsNegativeStaticTestJSON(base.BaseIdentityV3AdminTest):
+    """Negative tests of projects
+
+    These tests can be executed in clouds using the pre-provisioned users
+    """
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -40,14 +46,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('24c49279-45dd-4155-887a-cb738c2385aa')
     def test_list_projects_by_unauthorized_user(self):
-        # Non-admin user should not be able to list projects
+        """Non-admin user should not be able to list projects"""
         self.assertRaises(lib_exc.Forbidden,
                           self.non_admin_projects_client.list_projects)
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('874c3e84-d174-4348-a16b-8c01f599561b')
     def test_project_create_duplicate(self):
-        # Project names should be unique
+        """Project names should be unique"""
         project_name = data_utils.rand_name('project-dup')
         self.setup_test_project(name=project_name)
 
@@ -57,7 +63,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('8fba9de2-3e1f-4e77-812a-60cb68f8df13')
     def test_create_project_by_unauthorized_user(self):
-        # Non-admin user should not be authorized to create a project
+        """Non-admin user should not be authorized to create a project"""
         project_name = data_utils.rand_name('project')
         self.assertRaises(
             lib_exc.Forbidden, self.non_admin_projects_client.create_project,
@@ -66,14 +72,14 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7828db17-95e5-475b-9432-9a51b4aa79a9')
     def test_create_project_with_empty_name(self):
-        # Project name should not be empty
+        """Project name should not be empty"""
         self.assertRaises(lib_exc.BadRequest,
                           self.projects_client.create_project, name='')
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('502b6ceb-b0c8-4422-bf53-f08fdb21e2f0')
     def test_create_projects_name_length_over_64(self):
-        # Project name length should not be greater than 64 characters
+        """Project name length should not be greater than 64 characters"""
         project_name = 'a' * 65
         self.assertRaises(lib_exc.BadRequest,
                           self.projects_client.create_project, project_name)
@@ -81,7 +87,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7965b581-60c1-43b7-8169-95d4ab7fc6fb')
     def test_delete_non_existent_project(self):
-        # Attempt to delete a non existent project should fail
+        """Attempt to delete a non existent project should fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.projects_client.delete_project,
                           data_utils.rand_uuid_hex())
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index c8c0151..63e456e 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -20,6 +20,8 @@
 
 
 class RegionsTestJSON(base.BaseIdentityV3AdminTest):
+    """Test regions"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -44,6 +46,7 @@
 
     @decorators.idempotent_id('56186092-82e4-43f2-b954-91013218ba42')
     def test_create_update_get_delete_region(self):
+        """Test creating, updating, getting and updating region"""
         # Create region
         r_description = data_utils.rand_name('description')
         region = self.client.create_region(
@@ -81,7 +84,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('2c12c5b5-efcf-4aa5-90c5-bff1ab0cdbe2')
     def test_create_region_with_specific_id(self):
-        # Create a region with a specific id
+        """Test creating region with specific id"""
         r_region_id = data_utils.rand_uuid()
         r_description = data_utils.rand_name('description')
         region = self.client.create_region(
@@ -93,7 +96,7 @@
 
     @decorators.idempotent_id('d180bf99-544a-445c-ad0d-0c0d27663796')
     def test_list_regions(self):
-        # Get a list of regions
+        """Test getting a list of regions"""
         fetched_regions = self.client.list_regions()['regions']
         missing_regions =\
             [e for e in self.setup_regions if e not in fetched_regions]
@@ -104,6 +107,7 @@
 
     @decorators.idempotent_id('2d1057cb-bbde-413a-acdf-e2d265284542')
     def test_list_regions_filter_by_parent_region_id(self):
+        """Test listing regions filtered by parent region id"""
         # Add a sub-region to one of the existing test regions
         r_description = data_utils.rand_name('description')
         region = self.client.create_region(
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 5ba4c9f..dd7d5af 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -25,6 +25,8 @@
 
 
 class RolesV3TestJSON(base.BaseIdentityV3AdminTest):
+    """Test roles"""
+
     # NOTE: force_tenant_isolation is true in the base class by default but
     # overridden to false here to allow test execution for clouds using the
     # pre-provisioned credentials provider.
@@ -75,6 +77,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('18afc6c0-46cf-4911-824e-9989cc056c3a')
     def test_role_create_update_show_list(self):
+        """Test creating, updating, showing and listing a role"""
         r_name = data_utils.rand_name('Role')
         role = self.roles_client.create_role(name=r_name)['role']
         self.addCleanup(self.roles_client.delete_role, role['id'])
@@ -101,6 +104,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_grant_list_revoke_role_to_user_on_project(self):
+        """Test granting, listing, revoking role to user on project"""
         self.roles_client.create_user_role_on_project(self.project['id'],
                                                       self.user_body['id'],
                                                       self.role['id'])
@@ -122,6 +126,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_grant_list_revoke_role_to_user_on_domain(self):
+        """Test granting, listing, revoking role to user on domain"""
         self.roles_client.create_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
@@ -142,6 +147,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_grant_list_revoke_role_to_group_on_project(self):
+        """Test granting, listing, revoking role to group on project"""
         # Grant role to group on project
         self.roles_client.create_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
@@ -175,6 +181,7 @@
 
     @decorators.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
     def test_grant_list_revoke_role_to_group_on_domain(self):
+        """Test granting, listing, revoking role to group on domain"""
         self.roles_client.create_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
@@ -192,6 +199,7 @@
 
     @decorators.idempotent_id('f5654bcc-08c4-4f71-88fe-05d64e06de94')
     def test_list_roles(self):
+        """Test listing roles"""
         # Return a list of all roles
         body = self.roles_client.list_roles()['roles']
         found = [role for role in body if role in self.roles]
@@ -215,6 +223,7 @@
 
     @decorators.idempotent_id('c90c316c-d706-4728-bcba-eb1912081b69')
     def test_implied_roles_create_check_show_delete(self):
+        """Test creating, checking, showing and deleting implied roles"""
         prior_role_id = self.roles[0]['id']
         implies_role_id = self.roles[1]['id']
 
@@ -248,6 +257,7 @@
 
     @decorators.idempotent_id('dc6f5959-b74d-4e30-a9e5-a8255494ff00')
     def test_roles_hierarchy(self):
+        """Test creating implied role and listing role inferences rules"""
         # Create inference rule from "roles[0]" to "role[1]"
         self._create_implied_role(
             self.roles[0]['id'], self.roles[1]['id'])
@@ -280,6 +290,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_assignments_for_implied_roles_create_delete(self):
+        """Test assignments when implied roles are created and deleted"""
         # Create a grant using "roles[0]"
         self.roles_client.create_user_role_on_project(
             self.project['id'], self.user_body['id'], self.roles[0]['id'])
@@ -321,6 +332,7 @@
 
     @decorators.idempotent_id('d92a41d2-5501-497a-84bb-6e294330e8f8')
     def test_domain_roles_create_delete(self):
+        """Test creating, listing and deleting domain roles"""
         domain_role = self.roles_client.create_role(
             name=data_utils.rand_name('domain_role'),
             domain_id=self.domain['id'])['role']
@@ -341,6 +353,7 @@
 
     @decorators.idempotent_id('eb1e1c24-1bc4-4d47-9748-e127a1852c82')
     def test_implied_domain_roles(self):
+        """Test creating implied roles when roles are in domains"""
         # Create two roles in the same domain
         domain_role1 = self.setup_test_role(domain_id=self.domain['id'])
         domain_role2 = self.setup_test_role(domain_id=self.domain['id'])
@@ -373,6 +386,7 @@
                       'Skipped because environment has an immutable user '
                       'source and solely provides read-only access to users.')
     def test_assignments_for_domain_roles(self):
+        """Test assignments for domain roles"""
         domain_role = self.setup_test_role(domain_id=self.domain['id'])
 
         # Create a grant using "domain_role"
@@ -395,6 +409,7 @@
 
     @decorators.idempotent_id('3748c316-c18f-4b08-997b-c60567bc6235')
     def test_list_all_implied_roles(self):
+        """Test listing all implied roles"""
         # Create inference rule from "roles[0]" to "roles[1]"
         self._create_implied_role(
             self.roles[0]['id'], self.roles[1]['id'])
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 5f1b58d..f3a7471 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -24,6 +24,7 @@
 
 
 class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
+    """Test tokens"""
 
     credentials = ['primary', 'admin', 'alt']
 
@@ -123,6 +124,7 @@
 
     @decorators.idempotent_id('08ed85ce-2ba8-4864-b442-bcc61f16ae89')
     def test_get_available_project_scopes(self):
+        """Test getting available project scopes"""
         manager_project_id = self.os_primary.credentials.project_id
         admin_user_id = self.os_admin.credentials.user_id
         admin_role_id = self.get_role_by_name(CONF.identity.admin_role)['id']
@@ -152,10 +154,13 @@
 
     @decorators.idempotent_id('ec5ecb05-af64-4c04-ac86-4d9f6f12f185')
     def test_get_available_domain_scopes(self):
-        # Test for verifying that listing domain scopes for a user works if
-        # the user has a domain role or belongs to a group that has a domain
-        # role. For this test, admin client is used to add roles to alt user,
-        # which performs API calls, to avoid 401 Unauthorized errors.
+        """Test getting available domain scopes
+
+        To verify that listing domain scopes for a user works if
+        the user has a domain role or belongs to a group that has a domain
+        role. For this test, admin client is used to add roles to alt user,
+        which performs API calls, to avoid 401 Unauthorized errors.
+        """
         alt_user_id = self.os_alt.credentials.user_id
 
         def _create_user_domain_role_for_alt_user():
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 78e3cce..580e304 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -27,6 +27,7 @@
 
 
 class TrustsV3TestJSON(base.BaseIdentityV3AdminTest):
+    """Test keystone trusts"""
 
     @classmethod
     def skip_checks(cls):
@@ -195,8 +196,11 @@
 
     @decorators.idempotent_id('5a0a91a4-baef-4a14-baba-59bf4d7fcace')
     def test_trust_impersonate(self):
-        # Test case to check we can create, get and delete a trust
-        # updates are not supported for trusts
+        """Test keystone trust with impersonation enabled
+
+        To check we can create, get and delete a trust.
+        Updates are not supported for trusts
+        """
         trust = self.create_trust()
         self.validate_trust(trust)
 
@@ -207,8 +211,11 @@
 
     @decorators.idempotent_id('ed2a8779-a7ac-49dc-afd7-30f32f936ed2')
     def test_trust_noimpersonate(self):
-        # Test case to check we can create, get and delete a trust
-        # with impersonation=False
+        """Test keystone trust with impersonation disabled
+
+        To check we can create, get and delete a trust
+        with impersonation=False
+        """
         trust = self.create_trust(impersonate=False)
         self.validate_trust(trust, impersonate=False)
 
@@ -219,8 +226,11 @@
 
     @decorators.idempotent_id('0ed14b66-cefd-4b5c-a964-65759453e292')
     def test_trust_expire(self):
-        # Test case to check we can create, get and delete a trust
-        # with an expiry specified
+        """Test expire attribute of keystone trust
+
+        To check we can create, get and delete a trust
+        with an expiry specified
+        """
         expires_at = timeutils.utcnow() + datetime.timedelta(hours=1)
         # NOTE(ylobankov) In some cases the expiry time may be rounded up
         # because of microseconds. In fact, it depends on database and its
@@ -246,8 +256,10 @@
 
     @decorators.idempotent_id('3e48f95d-e660-4fa9-85e0-5a3d85594384')
     def test_trust_expire_invalid(self):
-        # Test case to check we can check an invalid expiry time
-        # is rejected with the correct error
+        """Test invalid expire attribute of a keystone trust
+
+        To check an invalid expiry time is rejected with the correct error
+        """
         # with an expiry specified
         expires_str = 'bad.123Z'
         self.assertRaises(lib_exc.BadRequest,
@@ -256,6 +268,7 @@
 
     @decorators.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
     def test_get_trusts_query(self):
+        """Test getting keystone trusts"""
         self.create_trust()
         trusts_get = self.trustor_client.list_trusts(
             trustor_user_id=self.trustor_user_id)['trusts']
@@ -265,7 +278,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('4773ebd5-ecbf-4255-b8d8-b63e6f72b65d')
     def test_get_trusts_all(self):
-
+        """Test getting all keystone trusts"""
         # Simple function that can be used for cleanup
         def set_scope(auth_provider, scope):
             auth_provider.scope = scope
diff --git a/tempest/api/identity/admin/v3/test_users_negative.py b/tempest/api/identity/admin/v3/test_users_negative.py
index 11dcdb0..1cba945 100644
--- a/tempest/api/identity/admin/v3/test_users_negative.py
+++ b/tempest/api/identity/admin/v3/test_users_negative.py
@@ -23,11 +23,12 @@
 
 
 class UsersNegativeTest(base.BaseIdentityV3AdminTest):
+    """Negative tests of keystone users"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('e75f006c-89cc-477b-874d-588e4eab4b17')
     def test_create_user_for_non_existent_domain(self):
-        # Attempt to create a user in a non-existent domain should fail
+        """Attempt to create a user in a non-existent domain should fail"""
         u_name = data_utils.rand_name('user')
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_password()
@@ -39,7 +40,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b3c9fccc-4134-46f5-b600-1da6fb0a3b1f')
     def test_authentication_for_disabled_user(self):
-        # Attempt to authenticate for disabled user should fail
+        """Attempt to authenticate for disabled user should fail"""
         password = data_utils.rand_password()
         user = self.setup_test_user(password)
         self.disable_user(user['name'], user['domain_id'])
diff --git a/tempest/api/identity/v3/test_application_credentials.py b/tempest/api/identity/v3/test_application_credentials.py
index 1cee902..ef1bbdf 100644
--- a/tempest/api/identity/v3/test_application_credentials.py
+++ b/tempest/api/identity/v3/test_application_credentials.py
@@ -23,6 +23,7 @@
 
 
 class ApplicationCredentialsV3Test(base.BaseApplicationCredentialsV3Test):
+    """Test application credentials"""
 
     def _list_app_creds(self, name=None):
         kwargs = dict(user_id=self.user_id)
@@ -33,6 +34,7 @@
 
     @decorators.idempotent_id('8080c75c-eddc-4786-941a-c2da7039ae61')
     def test_create_application_credential(self):
+        """Test creating application credential"""
         app_cred = self.create_application_credential()
 
         # Check that the secret appears in the create response
@@ -55,6 +57,7 @@
 
     @decorators.idempotent_id('852daf0c-42b5-4239-8466-d193d0543ed3')
     def test_create_application_credential_expires(self):
+        """Test creating application credential with expire time"""
         expires_at = timeutils.utcnow() + datetime.timedelta(hours=1)
 
         app_cred = self.create_application_credential(expires_at=expires_at)
@@ -64,6 +67,7 @@
 
     @decorators.idempotent_id('ff0cd457-6224-46e7-b79e-0ada4964a8a6')
     def test_list_application_credentials(self):
+        """Test listing application credentials"""
         self.create_application_credential()
         self.create_application_credential()
 
@@ -72,6 +76,7 @@
 
     @decorators.idempotent_id('9bb5e5cc-5250-493a-8869-8b665f6aa5f6')
     def test_query_application_credentials(self):
+        """Test listing application credentials filtered by name"""
         self.create_application_credential()
         app_cred_two = self.create_application_credential()
         app_cred_two_name = app_cred_two['name']
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index c4a3e0e..c1a7211 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -29,6 +29,90 @@
 LOG = logging.getLogger(__name__)
 
 
+class ImportImagesTest(base.BaseV2ImageTest):
+    """Here we test the import operations for image"""
+
+    @classmethod
+    def skip_checks(cls):
+        super(ImportImagesTest, cls).skip_checks()
+        if not CONF.image_feature_enabled.import_image:
+            skip_msg = (
+                "%s skipped as image import is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
+    def resource_setup(cls):
+        super(ImportImagesTest, cls).resource_setup()
+        cls.available_import_methods = cls.client.info_import()[
+            'import-methods']['value']
+        if not cls.available_import_methods:
+            raise cls.skipException('Server does not support '
+                                    'any import method')
+
+    def _create_image(self):
+        # Create image
+        uuid = '00000000-1111-2222-3333-444455556666'
+        image_name = data_utils.rand_name('image')
+        container_format = CONF.image.container_formats[0]
+        disk_format = CONF.image.disk_formats[0]
+        image = self.create_image(name=image_name,
+                                  container_format=container_format,
+                                  disk_format=disk_format,
+                                  visibility='private',
+                                  ramdisk_id=uuid)
+        self.assertIn('name', image)
+        self.assertEqual(image_name, image['name'])
+        self.assertIn('visibility', image)
+        self.assertEqual('private', image['visibility'])
+        self.assertIn('status', image)
+        self.assertEqual('queued', image['status'])
+        return image
+
+    @decorators.idempotent_id('32ca0c20-e16f-44ac-8590-07869c9b4cc2')
+    def test_image_glance_direct_import(self):
+        """Test 'glance-direct' import functionalities
+
+        Create image, stage image data, import image and verify
+        that import succeeded.
+        """
+        if 'glance-direct' not in self.available_import_methods:
+            raise self.skipException('Server does not support '
+                                     'glance-direct import method')
+        image = self._create_image()
+        # Stage image data
+        file_content = data_utils.random_bytes()
+        image_file = six.BytesIO(file_content)
+        self.client.stage_image_file(image['id'], image_file)
+        # Check image status is 'uploading'
+        body = self.client.show_image(image['id'])
+        self.assertEqual(image['id'], body['id'])
+        self.assertEqual('uploading', body['status'])
+        # import image from staging to backend
+        self.client.image_import(image['id'], method='glance-direct')
+        self.client.wait_for_resource_activation(image['id'])
+
+    @decorators.idempotent_id('f6feb7a4-b04f-4706-a011-206129f83e62')
+    def test_image_web_download_import(self):
+        """Test 'web-download' import functionalities
+
+        Create image, import image and verify that import
+        succeeded.
+        """
+        if 'web-download' not in self.available_import_methods:
+            raise self.skipException('Server does not support '
+                                     'web-download import method')
+        image = self._create_image()
+        # Now try to get image details
+        body = self.client.show_image(image['id'])
+        self.assertEqual(image['id'], body['id'])
+        self.assertEqual('queued', body['status'])
+        # import image from web to backend
+        image_uri = CONF.image.http_image
+        self.client.image_import(image['id'], method='web-download',
+                                 image_uri=image_uri)
+        self.client.wait_for_resource_activation(image['id'])
+
+
 class BasicOperationsImagesTest(base.BaseV2ImageTest):
     """Here we test the basic operations of images"""
 
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 4631ea9..2506185 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -18,6 +18,7 @@
 
 
 class DHCPAgentSchedulersTestJSON(base.BaseAdminNetworkTest):
+    """Test network DHCP agent scheduler extension"""
 
     @classmethod
     def skip_checks(cls):
@@ -37,11 +38,13 @@
 
     @decorators.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
     def test_list_dhcp_agent_hosting_network(self):
+        """Test Listing DHCP agents hosting a network"""
         self.admin_networks_client.list_dhcp_agents_on_hosting_network(
             self.network['id'])
 
     @decorators.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
     def test_list_networks_hosted_by_one_dhcp(self):
+        """Test Listing networks hosted by a DHCP agent"""
         body = self.admin_networks_client.list_dhcp_agents_on_hosting_network(
             self.network['id'])
         agents = body['agents']
@@ -61,6 +64,7 @@
 
     @decorators.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
     def test_add_remove_network_from_dhcp_agent(self):
+        """Test adding and removing network from a DHCP agent"""
         # The agent is now bound to the network, we can free the port
         self.ports_client.delete_port(self.port['id'])
         agent = dict()
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 5bd3fce..0cec316 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -23,6 +23,7 @@
 
 
 class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
+    """Test external networks"""
 
     @classmethod
     def resource_setup(cls):
@@ -42,8 +43,11 @@
 
     @decorators.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
     def test_create_external_network(self):
-        # Create a network as an admin user specifying the
-        # external network extension attribute
+        """Test creating external network
+
+        Create a network as an admin user specifying the
+        external network extension attribute
+        """
         ext_network = self._create_network()
         # Verifies router:external parameter
         self.assertIsNotNone(ext_network['id'])
@@ -51,8 +55,11 @@
 
     @decorators.idempotent_id('4db5417a-e11c-474d-a361-af00ebef57c5')
     def test_update_external_network(self):
-        # Update a network as an admin user specifying the
-        # external network extension attribute
+        """Test updating external network
+
+        Update a network as an admin user specifying the
+        external network extension attribute
+        """
         network = self._create_network(external=False)
         self.assertFalse(network.get('router:external', False))
         update_body = {'router:external': True}
@@ -64,6 +71,7 @@
 
     @decorators.idempotent_id('39be4c9b-a57e-4ff9-b7c7-b218e209dfcc')
     def test_list_external_networks(self):
+        """Test listing external networks"""
         # Create external_net
         external_network = self._create_network()
         # List networks as a normal user and confirm the external
@@ -81,6 +89,7 @@
 
     @decorators.idempotent_id('2ac50ab2-7ebd-4e27-b3ce-a9e399faaea2')
     def test_show_external_networks_attribute(self):
+        """Test showing external network attribute"""
         # Create external_net
         external_network = self._create_network()
         # Show an external network as a normal user and confirm the
@@ -101,9 +110,11 @@
     @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
                           'Floating ips are not availabled')
     def test_delete_external_networks_with_floating_ip(self):
-        # Verifies external network can be deleted while still holding
-        # (unassociated) floating IPs
+        """Test deleting external network with unassociated floating ips
 
+        Verifies external network can be deleted while still holding
+        (unassociated) floating IPs
+        """
         body = self.admin_networks_client.create_network(
             **{'router:external': True})
         external_network = body['network']
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index da32f2d..92731f6 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -25,16 +25,19 @@
 
 
 class ExternalNetworksAdminNegativeTestJSON(base.BaseAdminNetworkTest):
+    """Negative tests of external network"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
-        # NOTE: External networks can be used to create both floating-ip as
-        # well as instance-ip. So, creating an instance-ip with a value of a
-        # pre-created floating-ip should be denied.
+        """Test creating port with precreated floating ip as fixed ip
 
+        NOTE: External networks can be used to create both floating-ip as
+        well as instance-ip. So, creating an instance-ip with a value of a
+        pre-created floating-ip should be denied.
+        """
         # create a floating ip
         body = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=CONF.network.public_network_id)
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index adc4dda..ad7dfb3 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -23,6 +23,8 @@
 
 
 class FloatingIPAdminTestJSON(base.BaseAdminNetworkTest):
+    """Test floating ips"""
+
     credentials = ['primary', 'alt', 'admin']
 
     @classmethod
@@ -55,6 +57,13 @@
 
     @decorators.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
     def test_list_floating_ips_from_admin_and_nonadmin(self):
+        """Test listing floating ips from admin and non admin users
+
+        This test performs below operations:
+        1. Create couple floating ips for admin and non-admin users.
+        2. Verify if admin can access all floating ips including other user
+           and non-admin user can only access its own floating ips.
+        """
         # Create floating ip from admin user
         floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
@@ -90,10 +99,11 @@
 
     @decorators.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
     def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
+        """Verify if admin can create/list/show floating ip with tenant id"""
         # Creates a floating IP
         body = self.admin_floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
-            tenant_id=self.network['tenant_id'],
+            project_id=self.network['project_id'],
             port_id=self.port['id'])
         created_floating_ip = body['floatingip']
         self.addCleanup(
@@ -101,7 +111,7 @@
             self.floating_ips_client.delete_floatingip,
             created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
-        self.assertIsNotNone(created_floating_ip['tenant_id'])
+        self.assertIsNotNone(created_floating_ip['project_id'])
         self.assertIsNotNone(created_floating_ip['floating_ip_address'])
         self.assertEqual(created_floating_ip['port_id'], self.port['id'])
         self.assertEqual(created_floating_ip['floating_network_id'],
@@ -116,8 +126,8 @@
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
         self.assertEqual(shown_floating_ip['floating_network_id'],
                          self.ext_net_id)
-        self.assertEqual(shown_floating_ip['tenant_id'],
-                         self.network['tenant_id'])
+        self.assertEqual(shown_floating_ip['project_id'],
+                         self.network['project_id'])
         self.assertEqual(shown_floating_ip['floating_ip_address'],
                          created_floating_ip['floating_ip_address'])
         self.assertEqual(shown_floating_ip['port_id'], self.port['id'])
diff --git a/tempest/api/network/admin/test_metering_extensions.py b/tempest/api/network/admin/test_metering_extensions.py
index 5063fef..a60cd48 100644
--- a/tempest/api/network/admin/test_metering_extensions.py
+++ b/tempest/api/network/admin/test_metering_extensions.py
@@ -92,13 +92,14 @@
 
     @decorators.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
     def test_list_metering_labels(self):
-        # Verify label filtering
+        """Verify listing metering labels"""
         body = self.admin_metering_labels_client.list_metering_labels(id=33)
         metering_labels = body['metering_labels']
         self.assertEmpty(metering_labels)
 
     @decorators.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
     def test_create_delete_metering_label_with_filters(self):
+        """Verifies creating and deleting metering label with filters"""
         # Creates a label
         name = data_utils.rand_name('metering-label-')
         description = "label created by tempest"
@@ -115,19 +116,20 @@
 
     @decorators.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
     def test_show_metering_label(self):
-        # Verifies the details of a label
+        """Verifies the details of a metering label"""
         body = self.admin_metering_labels_client.show_metering_label(
             self.metering_label['id'])
         metering_label = body['metering_label']
         self.assertEqual(self.metering_label['id'], metering_label['id'])
         self.assertEqual(self.metering_label['tenant_id'],
-                         metering_label['tenant_id'])
+                         metering_label['project_id'])
         self.assertEqual(self.metering_label['name'], metering_label['name'])
         self.assertEqual(self.metering_label['description'],
                          metering_label['description'])
 
     @decorators.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
     def test_list_metering_label_rules(self):
+        """Verifies listing metering label rules"""
         client = self.admin_metering_label_rules_client
         # Verify rule filtering
         body = client.list_metering_label_rules(id=33)
@@ -136,6 +138,7 @@
 
     @decorators.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
     def test_create_delete_metering_label_rule_with_filters(self):
+        """Verifies creating and deleting metering label rule with filters"""
         # Creates a rule
         remote_ip_prefix = ("10.0.1.0/24" if self._ip_version == 4
                             else "fd03::/64")
@@ -154,7 +157,7 @@
 
     @decorators.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
     def test_show_metering_label_rule(self):
-        # Verifies the details of a rule
+        """Verifies the metering details of a rule"""
         client = self.admin_metering_label_rules_client
         body = (client.show_metering_label_rule(
                 self.metering_label_rule['id']))
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index 0db038d..190d9e3 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -53,17 +53,18 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('644f4e1b-1bf9-4af0-9fd8-eb56ac0f51cf')
     def test_network_quota_exceeding(self):
+        """Test creating network when exceeding network quota will fail"""
         # Set the network quota to two
         self.admin_quotas_client.update_quotas(self.project['id'], network=2)
 
         # Create two networks
         n1 = self.admin_networks_client.create_network(
-            tenant_id=self.project['id'])
+            project_id=self.project['id'])
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.admin_networks_client.delete_network,
                         n1['network']['id'])
         n2 = self.admin_networks_client.create_network(
-            tenant_id=self.project['id'])
+            project_id=self.project['id'])
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.admin_networks_client.delete_network,
                         n2['network']['id'])
@@ -73,7 +74,7 @@
                 lib_exc.Conflict,
                 r"Quota exceeded for resources: \['network'\].*"):
             n3 = self.admin_networks_client.create_network(
-                tenant_id=self.project['id'])
+                project_id=self.project['id'])
             self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                             self.admin_networks_client.delete_network,
                             n3['network']['id'])
diff --git a/tempest/api/network/admin/test_ports.py b/tempest/api/network/admin/test_ports.py
index 289e577..51f2857 100644
--- a/tempest/api/network/admin/test_ports.py
+++ b/tempest/api/network/admin/test_ports.py
@@ -24,6 +24,7 @@
 
 
 class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
+    """Test extended attributes of ports"""
 
     @classmethod
     def setup_clients(cls):
@@ -41,6 +42,7 @@
     @decorators.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
     @utils.services('compute')
     def test_create_port_binding_ext_attr(self):
+        """Test creating port with extended attribute"""
         post_body = {"network_id": self.network['id'],
                      "binding:host_id": self.host_id,
                      "name": data_utils.rand_name(self.__class__.__name__)}
@@ -56,6 +58,7 @@
     @decorators.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
     @utils.services('compute')
     def test_update_port_binding_ext_attr(self):
+        """Test updating port's extended attribute"""
         post_body = {"network_id": self.network['id'],
                      "name": data_utils.rand_name(self.__class__.__name__)}
         body = self.admin_ports_client.create_port(**post_body)
@@ -73,6 +76,7 @@
     @decorators.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
     @utils.services('compute')
     def test_list_ports_binding_ext_attr(self):
+        """Test updating and listing port's extended attribute"""
         # Create a new port
         post_body = {"network_id": self.network['id'],
                      "name": data_utils.rand_name(self.__class__.__name__)}
@@ -101,6 +105,7 @@
 
     @decorators.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
     def test_show_port_binding_ext_attr(self):
+        """Test showing port's extended attribute"""
         body = self.admin_ports_client.create_port(
             name=data_utils.rand_name(self.__class__.__name__),
             network_id=self.network['id'])
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index ef5ebb6..d8db298 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -67,7 +67,7 @@
         non_default_quotas = self.admin_quotas_client.list_quotas()
         found = False
         for qs in non_default_quotas['quotas']:
-            if qs['tenant_id'] == project_id:
+            if qs['project_id'] == project_id:
                 found = True
         self.assertTrue(found)
 
@@ -81,7 +81,7 @@
         self.admin_quotas_client.reset_quotas(project_id)
         non_default_quotas = self.admin_quotas_client.list_quotas()
         for q in non_default_quotas['quotas']:
-            self.assertNotEqual(project_id, q['tenant_id'])
+            self.assertNotEqual(project_id, q['project_id'])
         quota_set = self.admin_quotas_client.show_quotas(project_id)['quota']
         default_quotas = self.admin_quotas_client.show_default_quotas(
             project_id)['quota']
@@ -89,6 +89,7 @@
 
     @decorators.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
     def test_quotas(self):
+        """Test update/list/show/reset of network quotas"""
         new_quotas = {'network': 0, 'port': 0}
         self._check_quotas(new_quotas)
 
@@ -96,6 +97,7 @@
         'quota_details', 'network'), 'Quota details extension not enabled.')
     @decorators.idempotent_id('7b05ec5f-bf44-43cb-b28f-ddd72a824288')
     def test_show_quota_details(self):
+        """Test showing network quota details"""
         # Show quota details for an existing project
         quota_details = self.admin_quotas_client.show_quota_details(
             self.admin_quotas_client.tenant_id)['quota']
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index 41f97d8..90e0917 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -27,6 +27,8 @@
 
 
 class RoutersAdminTest(base.BaseAdminNetworkTest):
+    """Test routers operation supported by admin"""
+
     # NOTE(salv-orlando): This class inherits from BaseAdminNetworkTest
     # as some router operations, such as enabling or disabling SNAT
     # require admin credentials by default
@@ -52,7 +54,7 @@
 
     @decorators.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
     def test_create_router_setting_project_id(self):
-        # Test creating router from admin user setting project_id.
+        """Test creating router from admin user setting project_id."""
         project = data_utils.rand_name('test_tenant_')
         description = data_utils.rand_name('desc_')
         project = identity.identity_utils(self.os_admin).create_project(
@@ -63,18 +65,18 @@
 
         name = data_utils.rand_name('router-')
         create_body = self.admin_routers_client.create_router(
-            name=name, tenant_id=project_id)
+            name=name, project_id=project_id)
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.admin_routers_client.delete_router,
                         create_body['router']['id'])
-        self.assertEqual(project_id, create_body['router']['tenant_id'])
+        self.assertEqual(project_id, create_body['router']['project_id'])
 
     @decorators.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
     @utils.requires_ext(extension='ext-gw-mode', service='network')
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_create_router_with_default_snat_value(self):
-        # Create a router with default snat rule
+        """Create a router with default snat rule"""
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
         self._verify_router_gateway(
@@ -86,6 +88,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_create_router_with_snat_explicit(self):
+        """Test creating router with specified enable_snat value"""
         name = data_utils.rand_name('snat-router')
         # Create a router enabling snat attributes
         enable_snat_states = [False, True]
@@ -134,6 +137,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_update_router_set_gateway(self):
+        """Test updating router's gateway info"""
         router = self._create_router()
         self.routers_client.update_router(
             router['id'],
@@ -150,6 +154,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_update_router_set_gateway_with_snat_explicit(self):
+        """Test setting router's gateway with snat enabled"""
         router = self._create_router()
         self.admin_routers_client.update_router(
             router['id'],
@@ -167,6 +172,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_update_router_set_gateway_without_snat(self):
+        """Test setting router's gateway with snat not enabled"""
         router = self._create_router()
         self.admin_routers_client.update_router(
             router['id'],
@@ -183,6 +189,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_update_router_unset_gateway(self):
+        """Test unsetting router's gateway"""
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
         self.routers_client.update_router(router['id'],
@@ -199,6 +206,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_update_router_reset_gateway_without_snat(self):
+        """Test updating router's gateway to be with snat not enabled"""
         router = self._create_router(
             external_network_id=CONF.network.public_network_id)
         self.admin_routers_client.update_router(
@@ -215,6 +223,7 @@
     @decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
     @utils.requires_ext(extension='ext-gw-mode', service='network')
     def test_create_router_set_gateway_with_fixed_ip(self):
+        """Test creating router setting gateway with fixed ip"""
         # At first create an external network and then use that
         # to create address and delete
         network_name = data_utils.rand_name(self.__class__.__name__)
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index 270f802..291581c 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -106,14 +106,14 @@
         attribute will be set to True
         """
         name = data_utils.rand_name('router')
-        tenant_id = self.routers_client.tenant_id
+        project_id = self.routers_client.project_id
         # router needs to be in admin state down in order to be upgraded to DVR
         # l3ha routers are not upgradable to dvr, make it explicitly non ha
         router = self.admin_routers_client.create_router(name=name,
                                                          distributed=False,
                                                          admin_state_up=False,
                                                          ha=False,
-                                                         tenant_id=tenant_id)
+                                                         project_id=project_id)
         router_id = router['router']['id']
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.admin_routers_client.delete_router, router_id)
diff --git a/tempest/api/network/admin/test_routers_negative.py b/tempest/api/network/admin/test_routers_negative.py
index f605945..914c046 100644
--- a/tempest/api/network/admin/test_routers_negative.py
+++ b/tempest/api/network/admin/test_routers_negative.py
@@ -27,6 +27,7 @@
 
 
 class RoutersAdminNegativeTest(base.BaseAdminNetworkTest):
+    """Admin negative tests of routers"""
 
     @classmethod
     def skip_checks(cls):
@@ -41,6 +42,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_router_set_gateway_used_ip_returns_409(self):
+        """Test creating router with gateway set to used ip should fail"""
         # At first create a address from public_network_id
         port = self.admin_ports_client.create_port(
             name=data_utils.rand_name(self.__class__.__name__),
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 639defb..ff5026b 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -57,7 +57,7 @@
 
     @decorators.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
     def test_create_list_port_with_address_pair(self):
-        # Create port with allowed address pair attribute
+        """Create and list port with allowed address pair attribute"""
         allowed_address_pairs = [{'ip_address': self.ip_address,
                                   'mac_address': self.mac_address}]
         body = self.ports_client.create_port(
@@ -100,17 +100,17 @@
 
     @decorators.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
     def test_update_port_with_address_pair(self):
-        # Update port with allowed address pair
+        """Update port with allowed address pair"""
         self._update_port_with_address(self.ip_address)
 
     @decorators.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
     def test_update_port_with_cidr_address_pair(self):
-        # Update allowed address pair with cidr
+        """Update allowed address pair with cidr"""
         self._update_port_with_address(str(self.cidr))
 
     @decorators.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
     def test_update_port_with_multiple_ip_mac_address_pair(self):
-        # Create an ip _address and mac_address through port create
+        """Update allowed address pair port with multiple ip and mac"""
         resp = self.ports_client.create_port(
             network_id=self.network['id'],
             name=data_utils.rand_name(self.__class__.__name__))
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index eb31ed3..fee6af5 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -104,9 +104,12 @@
 
     @decorators.idempotent_id('e5517e62-6f16-430d-a672-f80875493d4c')
     def test_dhcpv6_stateless_eui64(self):
-        # NOTE: When subnets configured with RAs SLAAC (AOM=100) and DHCP
-        # stateless (AOM=110) both for radvd and dnsmasq, port shall receive
-        # IP address calculated from its MAC.
+        """Test eui64 ip when setting slaac and statelss for subnet
+
+        NOTE: When subnets configured with RAs SLAAC (AOM=100) and DHCP
+        stateless (AOM=110) both for radvd and dnsmasq, port shall receive
+        IP address calculated from its MAC.
+        """
         for ra_mode, add_mode in (
                 ('slaac', 'slaac'),
                 ('dhcpv6-stateless', 'dhcpv6-stateless'),
@@ -122,9 +125,12 @@
 
     @decorators.idempotent_id('ae2f4a5d-03ff-4c42-a3b0-ce2fcb7ea832')
     def test_dhcpv6_stateless_no_ra(self):
-        # NOTE: When subnets configured with dnsmasq SLAAC and DHCP stateless
-        # and there is no radvd, port shall receive IP address calculated
-        # from its MAC and mask of subnet.
+        """Test eui64 ip when setting stateless and no radvd for subnets
+
+        NOTE: When subnets configured with dnsmasq SLAAC and DHCP stateless
+        and there is no radvd, port shall receive IP address calculated
+        from its MAC and mask of subnet.
+        """
         for ra_mode, add_mode in (
                 (None, 'slaac'),
                 (None, 'dhcpv6-stateless'),
@@ -161,8 +167,11 @@
 
     @decorators.idempotent_id('21635b6f-165a-4d42-bf49-7d195e47342f')
     def test_dhcpv6_stateless_no_ra_no_dhcp(self):
-        # NOTE: If no radvd option and no dnsmasq option is configured
-        # port shall receive IP from fixed IPs list of subnet.
+        """Test eui64 ip when setting no radvd and no dnsmasq for subnets
+
+        NOTE: If no radvd option and no dnsmasq option is configured
+        port shall receive IP from fixed IPs list of subnet.
+        """
         real_ip, eui_ip = self._get_ips_from_subnet()
         self._clean_network()
         self.assertNotEqual(eui_ip, real_ip,
@@ -173,10 +182,13 @@
 
     @decorators.idempotent_id('4544adf7-bb5f-4bdc-b769-b3e77026cef2')
     def test_dhcpv6_two_subnets(self):
-        # NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
-        # stateless and other IPv6 is with DHCP stateful, port shall receive
-        # EUI-64 IP addresses from first subnet and DHCP address from second
-        # one. Order of subnet creating should be unimportant.
+        """Test eui64 ip when creating port under network with two subnets
+
+        NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
+        stateless and other IPv6 is with DHCP stateful, port shall receive
+        EUI-64 IP addresses from first subnet and DHCP address from second
+        one. Order of subnet creating should be unimportant.
+        """
         for order in ("slaac_first", "dhcp_first"):
             for ra_mode, add_mode in (
                     ('slaac', 'slaac'),
@@ -225,10 +237,13 @@
 
     @decorators.idempotent_id('4256c61d-c538-41ea-9147-3c450c36669e')
     def test_dhcpv6_64_subnets(self):
-        # NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
-        # stateless and other IPv4 is with DHCP of IPv4, port shall receive
-        # EUI-64 IP addresses from first subnet and IPv4 DHCP address from
-        # second one. Order of subnet creating should be unimportant.
+        """Test eui64 ip when setting slaac and stateless for subnets
+
+        NOTE: When one IPv6 subnet configured with dnsmasq SLAAC or DHCP
+        stateless and other IPv4 is with DHCP of IPv4, port shall receive
+        EUI-64 IP addresses from first subnet and IPv4 DHCP address from
+        second one. Order of subnet creating should be unimportant.
+        """
         for order in ("slaac_first", "dhcp_first"):
             for ra_mode, add_mode in (
                     ('slaac', 'slaac'),
@@ -271,8 +286,11 @@
 
     @decorators.idempotent_id('4ab211a0-276f-4552-9070-51e27f58fecf')
     def test_dhcp_stateful(self):
-        # NOTE: With all options below, DHCPv6 shall allocate address from
-        # subnet pool to port.
+        """Test creating port when setting stateful for subnets
+
+        NOTE: With all options below, DHCPv6 shall allocate address from
+        subnet pool to port.
+        """
         for ra_mode, add_mode in (
                 ('dhcpv6-stateful', 'dhcpv6-stateful'),
                 ('dhcpv6-stateful', None),
@@ -294,9 +312,12 @@
 
     @decorators.idempotent_id('51a5e97f-f02e-4e4e-9a17-a69811d300e3')
     def test_dhcp_stateful_fixedips(self):
-        # NOTE: With all options below, port shall be able to get
-        # requested IP from fixed IP range not depending on
-        # DHCP stateful (not SLAAC!) settings configured.
+        """Test creating port with fixed ip when setting stateful for subnets
+
+        NOTE: With all options below, port shall be able to get
+        requested IP from fixed IP range not depending on
+        DHCP stateful (not SLAAC!) settings configured.
+        """
         for ra_mode, add_mode in (
                 ('dhcpv6-stateful', 'dhcpv6-stateful'),
                 ('dhcpv6-stateful', None),
@@ -324,8 +345,11 @@
 
     @decorators.idempotent_id('98244d88-d990-4570-91d4-6b25d70d08af')
     def test_dhcp_stateful_fixedips_outrange(self):
-        # NOTE: When port gets IP address from fixed IP range it
-        # shall be checked if it's from subnets range.
+        """Test creating port with fixed ip that is not in the range
+
+        NOTE: When port gets IP address from fixed IP range it
+        shall be checked if it's from subnets range.
+        """
         kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
                   'ipv6_address_mode': 'dhcpv6-stateful'}
         subnet = self.create_subnet(self.network, **kwargs)
@@ -342,8 +366,11 @@
 
     @decorators.idempotent_id('57b8302b-cba9-4fbb-8835-9168df029051')
     def test_dhcp_stateful_fixedips_duplicate(self):
-        # NOTE: When port gets IP address from fixed IP range it
-        # shall be checked if it's not duplicate.
+        """Test creating port with duplicate fixed ip
+
+        NOTE: When port gets IP address from fixed IP range it
+        shall be checked if it's not duplicate.
+        """
         kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
                   'ipv6_address_mode': 'dhcpv6-stateful'}
         subnet = self.create_subnet(self.network, **kwargs)
@@ -376,8 +403,11 @@
 
     @decorators.idempotent_id('e98f65db-68f4-4330-9fea-abd8c5192d4d')
     def test_dhcp_stateful_router(self):
-        # NOTE: With all options below the router interface shall
-        # receive DHCPv6 IP address from allocation pool.
+        """Test creating router with dhcp stateful
+
+        NOTE: With all options below the router interface shall
+        receive DHCPv6 IP address from allocation pool.
+        """
         for ra_mode, add_mode in (
                 ('dhcpv6-stateful', 'dhcpv6-stateful'),
                 ('dhcpv6-stateful', None),
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 4804ada..e116d7c 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -32,7 +32,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('ef28c7e6-e646-4979-9d67-deb207bc5564')
     def test_list_show_extensions(self):
-        # List available extensions for the project
+        """List available extensions and show the detail of each extension"""
         expected_alias = ['security-group', 'l3_agent_scheduler',
                           'ext-gw-mode', 'binding', 'quotas',
                           'agent', 'dhcp_agent_scheduler', 'provider',
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index d363081..bc6418a 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -58,7 +58,7 @@
 
     @decorators.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
     def test_create_list_port_with_extra_dhcp_options(self):
-        # Create a port with Extra DHCP Options
+        """Test creating a port with Extra DHCP Options and list those"""
         body = self.ports_client.create_port(
             network_id=self.network['id'],
             name=data_utils.rand_name(self.__class__.__name__),
@@ -76,7 +76,7 @@
 
     @decorators.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
     def test_update_show_port_with_extra_dhcp_options(self):
-        # Update port with extra dhcp options
+        """Test updating port with extra DHCP options and show that port"""
         name = data_utils.rand_name('new-port-name')
         self.ports_client.update_port(
             self.port['id'],
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index aaa5497..c32d3c1 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -73,6 +73,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
     def test_create_list_show_update_delete_floating_ip(self):
+        """Test create/list/show/update/delete floating ip"""
         # Creates a floating IP
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
@@ -83,7 +84,7 @@
             self.floating_ips_client.delete_floatingip,
             created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
-        self.assertIsNotNone(created_floating_ip['tenant_id'])
+        self.assertIsNotNone(created_floating_ip['project_id'])
         self.assertIsNotNone(created_floating_ip['floating_ip_address'])
         self.assertEqual(created_floating_ip['port_id'], self.ports[0]['id'])
         self.assertEqual(created_floating_ip['floating_network_id'],
@@ -97,8 +98,8 @@
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
         self.assertEqual(shown_floating_ip['floating_network_id'],
                          self.ext_net_id)
-        self.assertEqual(shown_floating_ip['tenant_id'],
-                         created_floating_ip['tenant_id'])
+        self.assertEqual(shown_floating_ip['project_id'],
+                         created_floating_ip['project_id'])
         self.assertEqual(shown_floating_ip['floating_ip_address'],
                          created_floating_ip['floating_ip_address'])
         self.assertEqual(shown_floating_ip['port_id'], self.ports[0]['id'])
@@ -133,6 +134,14 @@
 
     @decorators.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
     def test_floating_ip_delete_port(self):
+        """Test deleting floating ip's port
+
+        1. Create a floating ip
+        2. Create a port
+        3. Update the floating ip's port_id to the created port
+        4. Delete the port
+        5. Verify that the port details are cleared from the floating ip
+        """
         # Create a floating IP
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
@@ -163,6 +172,7 @@
 
     @decorators.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
     def test_floating_ip_update_different_router(self):
+        """Test associating a floating ip to a port on different router"""
         # Associate a floating IP to a port on a router
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
@@ -211,6 +221,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('36de4bd0-f09c-43e3-a8e1-1decc1ffd3a5')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
+        """Test creating floating ip with specified fixed ip"""
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=self.ports[1]['id'],
@@ -230,6 +241,12 @@
 
     @decorators.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
     def test_create_update_floatingip_with_port_multiple_ip_address(self):
+        """Test updating floating ip's fixed_ips to another ip of same port
+
+        First we create a port with 2 fixed ips, then we create a floating ip
+        with one of the fixed ips, and then we update the floating ip to
+        another fixed ip of that port.
+        """
         # Find out ips that can be used for tests
         list_ips = net_utils.get_unused_ip_addresses(
             self.ports_client,
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 1688c9d..80df5d6 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -58,6 +58,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
     def test_create_floatingip_with_port_ext_net_unreachable(self):
+        """Creating floating ip when port's external network is unreachable"""
         self.assertRaises(
             lib_exc.NotFound, self.floating_ips_client.create_floatingip,
             floating_network_id=self.ext_net_id, port_id=self.port['id'],
@@ -67,6 +68,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
     def test_create_floatingip_in_private_network(self):
+        """Test creating floating in private network"""
         self.assertRaises(lib_exc.BadRequest,
                           self.floating_ips_client.create_floatingip,
                           floating_network_id=self.network['id'],
@@ -77,6 +79,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
     def test_associate_floatingip_port_ext_net_unreachable(self):
+        """Associate floating ip to port with unreachable external network"""
         # Create floating ip
         body = self.floating_ips_client.create_floatingip(
             floating_network_id=self.ext_net_id)
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index eba1f6c..7646b63 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -29,6 +29,7 @@
 
 
 class BaseNetworkTestResources(base.BaseNetworkTest):
+    """Test networks"""
 
     @classmethod
     def resource_setup(cls):
@@ -158,6 +159,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('0e269138-0da6-4efc-a46d-578161e7b221')
     def test_create_update_delete_network_subnet(self):
+        """Verify creating, updating and deleting network subnet"""
         # Create a network
         network = self.create_network()
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
@@ -183,7 +185,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
     def test_show_network(self):
-        # Verify the details of a network
+        """Verify the details of a network"""
         body = self.networks_client.show_network(self.network['id'])
         network = body['network']
         for key in ['id', 'name']:
@@ -191,7 +193,7 @@
 
     @decorators.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
     def test_show_network_fields(self):
-        # Verify specific fields of a network
+        """Verify specific fields of a network"""
         fields = ['id', 'name']
         if utils.is_extension_enabled('net-mtu', 'network'):
             fields.append('mtu')
@@ -207,7 +209,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
     def test_list_networks(self):
-        # Verify the network exists in the list of all networks
+        """Verify the network exists in the list of all networks"""
         body = self.networks_client.list_networks()
         networks = [network['id'] for network in body['networks']
                     if network['id'] == self.network['id']]
@@ -215,7 +217,7 @@
 
     @decorators.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
     def test_list_networks_fields(self):
-        # Verify specific fields of the networks
+        """Verify specific fields of the networks"""
         fields = ['id', 'name']
         if utils.is_extension_enabled('net-mtu', 'network'):
             fields.append('mtu')
@@ -228,7 +230,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc')
     def test_show_subnet(self):
-        # Verify the details of a subnet
+        """Verify the details of a subnet"""
         body = self.subnets_client.show_subnet(self.subnet['id'])
         subnet = body['subnet']
         self.assertNotEmpty(subnet, "Subnet returned has no fields")
@@ -238,7 +240,7 @@
 
     @decorators.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
     def test_show_subnet_fields(self):
-        # Verify specific fields of a subnet
+        """Verify specific fields of a subnet"""
         fields = ['id', 'network_id']
         body = self.subnets_client.show_subnet(self.subnet['id'],
                                                fields=fields)
@@ -250,7 +252,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('db68ba48-f4ea-49e9-81d1-e367f6d0b20a')
     def test_list_subnets(self):
-        # Verify the subnet exists in the list of all subnets
+        """Verify the subnet exists in the list of all subnets"""
         body = self.subnets_client.list_subnets()
         subnets = [subnet['id'] for subnet in body['subnets']
                    if subnet['id'] == self.subnet['id']]
@@ -258,7 +260,7 @@
 
     @decorators.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
     def test_list_subnets_fields(self):
-        # Verify specific fields of subnets
+        """Verify specific fields of subnets"""
         fields = ['id', 'network_id']
         body = self.subnets_client.list_subnets(fields=fields)
         subnets = body['subnets']
@@ -268,6 +270,7 @@
 
     @decorators.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
     def test_delete_network_with_subnet(self):
+        """Verify deleting network with subnet"""
         # Creates a network
         network = self.create_network()
         net_id = network['id']
@@ -287,34 +290,41 @@
 
     @decorators.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
     def test_create_delete_subnet_without_gateway(self):
+        """Verify creating and deleting subnet without gateway"""
         self._create_verify_delete_subnet()
 
     @decorators.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
     def test_create_delete_subnet_with_gw(self):
+        """Verify creating and deleting subnet with gateway"""
         self._create_verify_delete_subnet(
             **self.subnet_dict(['gateway']))
 
     @decorators.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
     def test_create_delete_subnet_with_allocation_pools(self):
+        """Verify creating and deleting subnet with allocation pools"""
         self._create_verify_delete_subnet(
             **self.subnet_dict(['allocation_pools']))
 
     @decorators.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
     def test_create_delete_subnet_with_gw_and_allocation_pools(self):
+        """Verify create/delete subnet with gateway and allocation pools"""
         self._create_verify_delete_subnet(**self.subnet_dict(
             ['gateway', 'allocation_pools']))
 
     @decorators.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
     def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
+        """Verify create/delete subnet with host routes and name servers"""
         self._create_verify_delete_subnet(
             **self.subnet_dict(['host_routes', 'dns_nameservers']))
 
     @decorators.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
     def test_create_delete_subnet_with_dhcp_enabled(self):
+        """Verify create/delete subnet with dhcp enabled"""
         self._create_verify_delete_subnet(enable_dhcp=True)
 
     @decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
+        """Verify updating subnet's gateway/nameserver/routes/dhcp"""
         network = self.create_network()
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.networks_client.delete_network, network['id'])
@@ -349,6 +359,7 @@
 
     @decorators.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
     def test_create_delete_subnet_all_attributes(self):
+        """Verify create/delete subnet's all attributes"""
         self._create_verify_delete_subnet(
             enable_dhcp=True,
             **self.subnet_dict(['gateway', 'host_routes', 'dns_nameservers']))
@@ -359,6 +370,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_external_network_visibility(self):
+        """Verify external network's visibility"""
         public_network_id = CONF.network.public_network_id
 
         # find external network matching public_network_id
@@ -394,6 +406,7 @@
     @utils.requires_ext(extension="standard-attr-description",
                         service="network")
     def test_create_update_network_description(self):
+        """Verify creating and updating network's description"""
         body = self.create_network(description='d1')
         self.assertEqual('d1', body['description'])
         net_id = body['id']
@@ -454,6 +467,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('d4f9024d-1e28-4fc1-a6b1-25dbc6fa11e2')
     def test_bulk_create_delete_network(self):
+        """Verify creating and deleting multiple networks in one request"""
         # Creates 2 networks in one request
         network_list = [{'name': data_utils.rand_name('network-')},
                         {'name': data_utils.rand_name('network-')}]
@@ -470,6 +484,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('8936533b-c0aa-4f29-8e53-6cc873aec489')
     def test_bulk_create_delete_subnet(self):
+        """Verify creating and deleting multiple subnets in one request"""
         networks = [self.create_network(), self.create_network()]
         # Creates 2 subnets in one request
         cidrs = [subnet_cidr
@@ -499,6 +514,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('48037ff2-e889-4c3b-b86a-8e3f34d2d060')
     def test_bulk_create_delete_port(self):
+        """Verify creating and deleting multiple ports in one request"""
         networks = [self.create_network(), self.create_network()]
         # Creates 2 ports in one request
         names = [data_utils.rand_name('port-') for i in range(len(networks))]
@@ -532,6 +548,7 @@
 
     @decorators.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
     def test_create_delete_subnet_with_gw(self):
+        """Verify creating and deleting subnet with gateway"""
         net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway = str(netaddr.IPAddress(net.first + 2))
         network = self.create_network()
@@ -541,6 +558,7 @@
 
     @decorators.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
     def test_create_delete_subnet_with_default_gw(self):
+        """Verify creating and deleting subnet without specified gateway"""
         net = netaddr.IPNetwork(CONF.network.project_network_v6_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
         network = self.create_network()
@@ -550,6 +568,12 @@
 
     @decorators.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
     def test_create_list_subnet_with_no_gw64_one_network(self):
+        """Verify subnets with and without gateway are in one network
+
+        First we create a network, then we create one ipv6 subnet with
+        gateway and one ipv4 subnet without gateway, the two subnets
+        should be in the same network
+        """
         network = self.create_network()
         ipv6_gateway = self.subnet_dict(['gateway'])['gateway']
         subnet1 = self.create_subnet(network,
@@ -589,6 +613,7 @@
 
     @decorators.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
     def test_create_delete_subnet_with_v6_attributes_stateful(self):
+        """Test create/delete subnet with ipv6 attributes stateful"""
         self._create_verify_delete_subnet(
             gateway=self._subnet_data[self._ip_version]['gateway'],
             ipv6_ra_mode='dhcpv6-stateful',
@@ -596,12 +621,14 @@
 
     @decorators.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
     def test_create_delete_subnet_with_v6_attributes_slaac(self):
+        """Test create/delete subnet with ipv6 attributes slaac"""
         self._create_verify_delete_subnet(
             ipv6_ra_mode='slaac',
             ipv6_address_mode='slaac')
 
     @decorators.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
     def test_create_delete_subnet_with_v6_attributes_stateless(self):
+        """Test create/delete subnet with ipv6 attributes stateless"""
         self._create_verify_delete_subnet(
             ipv6_ra_mode='dhcpv6-stateless',
             ipv6_address_mode='dhcpv6-stateless')
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 3af67dd..0525484 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -21,10 +21,12 @@
 
 
 class NetworksNegativeTestJSON(base.BaseNetworkTest):
+    """Negative tests of network"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
     def test_show_non_existent_network(self):
+        """Test showing non existent network"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.networks_client.show_network,
                           non_exist_id)
@@ -32,6 +34,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
     def test_show_non_existent_subnet(self):
+        """Test showing non existent subnet"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.subnets_client.show_subnet,
                           non_exist_id)
@@ -39,6 +42,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
     def test_show_non_existent_port(self):
+        """Test showing non existent port"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.ports_client.show_port,
                           non_exist_id)
@@ -46,6 +50,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
     def test_update_non_existent_network(self):
+        """Test updating non existent network"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
             lib_exc.NotFound, self.networks_client.update_network,
@@ -54,6 +59,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
     def test_delete_non_existent_network(self):
+        """Test deleting non existent network"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.networks_client.delete_network,
@@ -62,6 +68,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('1cc47884-ac52-4415-a31c-e7ce5474a868')
     def test_update_non_existent_subnet(self):
+        """Test updating non existent subnet"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.subnets_client.update_subnet,
                           non_exist_id, name='new_name')
@@ -69,6 +76,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a176c859-99fb-42ec-a208-8a85b552a239')
     def test_delete_non_existent_subnet(self):
+        """Test deleting non existent subnet"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.subnets_client.delete_subnet, non_exist_id)
@@ -76,6 +84,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('13d3b106-47e6-4b9b-8d53-dae947f092fe')
     def test_create_port_on_non_existent_network(self):
+        """Test creating port on non existent network"""
         non_exist_net_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.ports_client.create_port,
@@ -85,6 +94,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('cf8eef21-4351-4f53-adcd-cc5cb1e76b92')
     def test_update_non_existent_port(self):
+        """Test updating non existent port"""
         non_exist_port_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound, self.ports_client.update_port,
                           non_exist_port_id, name='new_name')
@@ -92,6 +102,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('49ec2bbd-ac2e-46fd-8054-798e679ff894')
     def test_delete_non_existent_port(self):
+        """Test deleting non existent port"""
         non_exist_port_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.ports_client.delete_port, non_exist_port_id)
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 10121de..c6d049a 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -70,6 +70,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
     def test_create_update_delete_port(self):
+        """Test creating, updating and deleting port"""
         # Verify port creation
         body = self.ports_client.create_port(
             network_id=self.network['id'],
@@ -89,6 +90,7 @@
 
     @decorators.idempotent_id('67f1b811-f8db-43e2-86bd-72c074d4a42c')
     def test_create_bulk_port(self):
+        """Test creating multiple ports in a single request"""
         network1 = self.network
         network2 = self._create_network()
         network_list = [network1['id'], network2['id']]
@@ -107,6 +109,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('0435f278-40ae-48cb-a404-b8a087bc09b1')
     def test_create_port_in_allowed_allocation_pools(self):
+        """Test creating port in allowed allocation pools"""
         network = self._create_network()
         net_id = network['id']
         address = self.cidr
@@ -136,7 +139,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
     def test_show_port(self):
-        # Verify the details of port
+        """Verify the details of port"""
         body = self.ports_client.show_port(self.port['id'])
         port = body['port']
         self.assertIn('id', port)
@@ -152,7 +155,7 @@
 
     @decorators.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
     def test_show_port_fields(self):
-        # Verify specific fields of a port
+        """Verify specific fields of a port"""
         fields = ['id', 'mac_address']
         body = self.ports_client.show_port(self.port['id'],
                                            fields=fields)
@@ -164,7 +167,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('cf95b358-3e92-4a29-a148-52445e1ac50e')
     def test_list_ports(self):
-        # Verify the port exists in the list of all ports
+        """Verify the port exists in the list of all ports"""
         body = self.ports_client.list_ports()
         ports = [port['id'] for port in body['ports']
                  if port['id'] == self.port['id']]
@@ -172,6 +175,7 @@
 
     @decorators.idempotent_id('e7fe260b-1e79-4dd3-86d9-bec6a7959fc5')
     def test_port_list_filter_by_ip(self):
+        """Test listing ports filtered by ip"""
         # Create network and subnet
         network = self._create_network()
         self._create_subnet(network)
@@ -192,9 +196,9 @@
         port_list = self.ports_client.list_ports(fixed_ips=fixed_ips)
         # Check that we got the desired port
         ports = port_list['ports']
-        tenant_ids = set([port['tenant_id'] for port in ports])
-        self.assertEqual(len(tenant_ids), 1,
-                         'Ports from multiple tenants are in the list resp')
+        project_ids = set([port['project_id'] for port in ports])
+        self.assertEqual(len(project_ids), 1,
+                         'Ports from multiple projects are in the list resp')
         port_ids = [port['id'] for port in ports]
         fixed_ips = [port['fixed_ips'] for port in ports]
         port_net_ids = [port['network_id'] for port in ports]
@@ -211,6 +215,7 @@
         utils.is_extension_enabled('ip-substring-filtering', 'network'),
         'ip-substring-filtering extension not enabled.')
     def test_port_list_filter_by_ip_substr(self):
+        """Test listing ports filtered by part of ip address string"""
         # Create network and subnet
         network = self._create_network()
         subnet = self._create_subnet(network)
@@ -289,6 +294,7 @@
 
     @decorators.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
     def test_port_list_filter_by_router_id(self):
+        """Test listing ports filtered by router id"""
         # Create a router
         network = self._create_network()
         self._create_subnet(network)
@@ -313,7 +319,7 @@
 
     @decorators.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
     def test_list_ports_fields(self):
-        # Verify specific fields of ports
+        """Verify specific fields of ports"""
         fields = ['id', 'mac_address']
         body = self.ports_client.list_ports(fields=fields)
         ports = body['ports']
@@ -324,6 +330,7 @@
 
     @decorators.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
     def test_create_update_port_with_second_ip(self):
+        """Test updating port from 2 fixed ips to 1 fixed ip and vice versa"""
         # Create a network with two subnets
         network = self._create_network()
         subnet_1 = self._create_subnet(network)
@@ -410,6 +417,12 @@
         utils.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
     def test_update_port_with_security_group_and_extra_attributes(self):
+        """Test updating port's security_group along with extra attributes
+
+        First we create a port with one security group, and then we update the
+        port's security_group, in the same update request we also change
+        the port's fixed ips.
+        """
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup')])
 
@@ -418,12 +431,19 @@
         utils.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
     def test_update_port_with_two_security_groups_and_extra_attributes(self):
+        """Test updating port with two security_groups and extra attributes
+
+        First we create a port with one security group, and then we update the
+        port to two security_groups, in the same update request we also change
+        the port's fixed ips.
+        """
         self._update_port_with_security_groups(
             [data_utils.rand_name('secgroup'),
              data_utils.rand_name('secgroup')])
 
     @decorators.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
     def test_create_show_delete_port_user_defined_mac(self):
+        """Test creating port with user defined mac address"""
         # Create a port for a legal mac
         body = self.ports_client.create_port(
             network_id=self.network['id'],
@@ -450,6 +470,7 @@
         utils.is_extension_enabled('security-group', 'network'),
         'security-group extension not enabled.')
     def test_create_port_with_no_securitygroups(self):
+        """Test creating port without security groups"""
         network = self._create_network()
         self._create_subnet(network)
         port = self.create_port(network, security_groups=[])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 30423e3..c03a8a2 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -27,6 +27,7 @@
 
 
 class RoutersTest(base.BaseNetworkTest):
+    """Test routers"""
 
     def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
         interface = self.routers_client.add_router_interface(
@@ -53,6 +54,7 @@
     @testtools.skipUnless(CONF.network.public_network_id,
                           'The public_network_id option must be specified.')
     def test_create_show_list_update_delete_router(self):
+        """Test create/show/list/update/delete of a router"""
         # Create a router
         router_name = data_utils.rand_name(self.__class__.__name__ + '-router')
         router = self.create_router(
@@ -87,6 +89,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('b42e6e39-2e37-49cc-a6f4-8467e940900a')
     def test_add_remove_router_interface_with_subnet_id(self):
+        """Test adding and removing router interface with subnet id"""
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
@@ -113,6 +116,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('2b7d2f37-6748-4d78-92e5-1d590234f0d5')
     def test_add_remove_router_interface_with_port_id(self):
+        """Test adding and removing router interface with port id"""
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
@@ -145,6 +149,7 @@
     @decorators.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
     @utils.requires_ext(extension='extraroute', service='network')
     def test_update_delete_extra_route(self):
+        """Test updating and deleting router with extra route"""
         # Create different cidr for each subnet to avoid cidr duplicate
         # The cidr starts from project_cidr
         next_cidr = self.cidr
@@ -215,6 +220,7 @@
 
     @decorators.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
     def test_update_router_admin_state(self):
+        """Test updating router's admin state"""
         router = self.create_router()
         self.addCleanup(self.delete_router, router)
         self.assertFalse(router['admin_state_up'])
@@ -228,6 +234,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('802c73c9-c937-4cef-824b-2191e24a6aab')
     def test_add_multiple_router_interfaces(self):
+        """Test adding multiple router interfaces"""
         network_name = data_utils.rand_name(self.__class__.__name__)
         network01 = self.networks_client.create_network(
             name=network_name)['network']
@@ -258,6 +265,7 @@
 
     @decorators.idempotent_id('96522edf-b4b5-45d9-8443-fa11c26e6eff')
     def test_router_interface_port_update_with_fixed_ip(self):
+        """Test updating router interface port's fixed ip"""
         network_name = data_utils.rand_name(self.__class__.__name__)
         network = self.networks_client.create_network(
             name=network_name)['network']
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 0b61860..10a2706 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -21,6 +21,7 @@
 
 
 class RoutersNegativeTest(base.BaseNetworkTest):
+    """Negative tests of routers"""
 
     @classmethod
     def skip_checks(cls):
@@ -39,6 +40,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
     def test_router_add_gateway_invalid_network_returns_404(self):
+        """Test adding gateway with invalid network for router"""
         self.assertRaises(lib_exc.NotFound,
                           self.routers_client.update_router,
                           self.router['id'],
@@ -48,6 +50,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
     def test_router_add_gateway_net_not_external_returns_400(self):
+        """Test adding gateway with not external network for router"""
         alt_network = self.create_network()
         sub_cidr = self.cidr.next()
         self.create_subnet(alt_network, cidr=sub_cidr)
@@ -60,6 +63,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('957751a3-3c68-4fa2-93b6-eb52ea10db6e')
     def test_add_router_interfaces_on_overlapping_subnets_returns_400(self):
+        """Test adding router interface which is on overlapping subnets"""
         network01 = self.create_network(
             network_name=data_utils.rand_name('router-network01-'))
         network02 = self.create_network(
@@ -79,6 +83,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
     def test_router_remove_interface_in_use_returns_409(self):
+        """Test removing in-use interface from router"""
         self.routers_client.add_router_interface(self.router['id'],
                                                  subnet_id=self.subnet['id'])
         self.addCleanup(self.routers_client.remove_router_interface,
@@ -90,6 +95,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c2a70d72-8826-43a7-8208-0209e6360c47')
     def test_show_non_existent_router_returns_404(self):
+        """Test showing non existent router"""
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.show_router,
                           router)
@@ -97,6 +103,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b23d1569-8b0c-4169-8d4b-6abd34fad5c7')
     def test_update_non_existent_router_returns_404(self):
+        """Test updating non existent router"""
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.update_router,
                           router, name="new_name")
@@ -104,6 +111,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4')
     def test_delete_non_existent_router_returns_404(self):
+        """Test deleting non existent router"""
         router = data_utils.rand_name('non_exist_router')
         self.assertRaises(lib_exc.NotFound, self.routers_client.delete_router,
                           router)
@@ -114,6 +122,7 @@
 
 
 class DvrRoutersNegativeTest(base.BaseNetworkTest):
+    """Negative tests of DVR router"""
 
     @classmethod
     def skip_checks(cls):
@@ -125,5 +134,6 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4990b055-8fc7-48ab-bba7-aa28beaad0b9')
     def test_router_create_tenant_distributed_returns_forbidden(self):
+        """Non admin user is not allowed to create distributed router"""
         self.assertRaises(lib_exc.Forbidden, self.create_router,
                           distributed=True)
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index ef19122..d75acfc 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -21,6 +21,7 @@
 
 
 class SecGroupTest(base.BaseSecGroupTest):
+    """Test security groups"""
 
     @classmethod
     def skip_checks(cls):
@@ -67,7 +68,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('e30abd17-fef9-4739-8617-dc26da88e686')
     def test_list_security_groups(self):
-        # Verify the security group belonging to project exist in list
+        """Verify that default security group exist"""
         body = self.security_groups_client.list_security_groups()
         security_groups = body['security_groups']
         found = None
@@ -80,6 +81,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('bfd128e5-3c92-44b6-9d66-7fe29d22c802')
     def test_create_list_update_show_delete_security_group(self):
+        """Verify create/list/update/show/delete of security group"""
         group_create_body, _ = self._create_security_group()
 
         # List security groups and verify if created group is there in response
@@ -111,6 +113,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
     def test_create_show_delete_security_group_rule(self):
+        """Test create/show/delete of security group rule"""
         group_create_body, _ = self._create_security_group()
 
         # Create rules for each protocol
@@ -191,7 +194,7 @@
 
     @decorators.idempotent_id('c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b')
     def test_create_security_group_rule_with_remote_group_id(self):
-        # Verify creating security group rule with remote_group_id works
+        """Verify creating security group rule with remote_group_id works"""
         sg1_body, _ = self._create_security_group()
         sg2_body, _ = self._create_security_group()
 
@@ -209,7 +212,7 @@
 
     @decorators.idempotent_id('16459776-5da2-4634-bce4-4b55ee3ec188')
     def test_create_security_group_rule_with_remote_ip_prefix(self):
-        # Verify creating security group rule with remote_ip_prefix works
+        """Verify creating security group rule with remote_ip_prefix works"""
         sg1_body, _ = self._create_security_group()
 
         sg_id = sg1_body['security_group']['id']
@@ -226,9 +229,10 @@
 
     @decorators.idempotent_id('0a307599-6655-4220-bebc-fd70c64f2290')
     def test_create_security_group_rule_with_protocol_integer_value(self):
-        # Verify creating security group rule with the
-        # protocol as integer value
-        # arguments : "protocol": 17
+        """Verify creating security group rule with the integer protocol value
+
+        arguments : "protocol": 17
+        """
         group_create_body, _ = self._create_security_group()
         direction = 'ingress'
         protocol = 17
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index d054865..beaeb20 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -24,6 +24,7 @@
 
 
 class NegativeSecGroupTest(base.BaseSecGroupTest):
+    """Negative tests of security groups"""
 
     @classmethod
     def skip_checks(cls):
@@ -35,6 +36,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('424fd5c3-9ddc-486a-b45f-39bf0c820fc6')
     def test_show_non_existent_security_group(self):
+        """Test showing non existent security group"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
             lib_exc.NotFound, self.security_groups_client.show_security_group,
@@ -43,6 +45,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4c094c09-000b-4e41-8100-9617600c02a6')
     def test_show_non_existent_security_group_rule(self):
+        """Test showing non existent security group rule"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(
             lib_exc.NotFound,
@@ -52,6 +55,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('1f1bb89d-5664-4956-9fcd-83ee0fa603df')
     def test_delete_non_existent_security_group(self):
+        """Test deleting non existent security group"""
         non_exist_id = data_utils.rand_uuid()
         self.assertRaises(lib_exc.NotFound,
                           self.security_groups_client.delete_security_group,
@@ -61,6 +65,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('981bdc22-ce48-41ed-900a-73148b583958')
     def test_create_security_group_rule_with_bad_protocol(self):
+        """Test creating security group rule with bad protocol"""
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad protocol name
@@ -74,6 +79,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5f8daf69-3c5f-4aaa-88c9-db1d66f68679')
     def test_create_security_group_rule_with_bad_remote_ip_prefix(self):
+        """Test creating security group rule with bad remote ip prefix"""
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad remote_ip_prefix
@@ -89,6 +95,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('4bf786fd-2f02-443c-9716-5b98e159a49a')
     def test_create_security_group_rule_with_non_existent_remote_groupid(self):
+        """Creating security group rule with non existent remote group id"""
         group_create_body, _ = self._create_security_group()
         non_exist_id = data_utils.rand_uuid()
 
@@ -105,6 +112,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('b5c4b247-6b02-435b-b088-d10d45650881')
     def test_create_security_group_rule_with_remote_ip_and_group(self):
+        """Test creating security group rule with remote ip and group"""
         sg1_body, _ = self._create_security_group()
         sg2_body, _ = self._create_security_group()
 
@@ -121,6 +129,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('5666968c-fff3-40d6-9efc-df1c8bd01abb')
     def test_create_security_group_rule_with_bad_ethertype(self):
+        """Test creating security group rule with bad bad ethertype"""
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad ethertype
@@ -134,6 +143,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d')
     def test_create_security_group_rule_with_invalid_ports(self):
+        """Test creating security group rule with invalid ports"""
         group_create_body, _ = self._create_security_group()
 
         # Create rule for tcp protocol with invalid ports
@@ -168,7 +178,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('2323061e-9fbf-4eb0-b547-7e8fafc90849')
     def test_create_additional_default_security_group_fails(self):
-        # Create security group named 'default', it should be failed.
+        """Test creating additional default security group
+
+        Create security group named 'default', it should be failed.
+        """
         name = 'default'
         self.assertRaises(lib_exc.Conflict,
                           self.security_groups_client.create_security_group,
@@ -177,7 +190,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('966e2b96-023a-11e7-a9e4-fa163e4fa634')
     def test_create_security_group_update_name_default(self):
-        # Update security group name to 'default', it should be failed.
+        """Test updating security group's name to default
+
+        Update security group name to 'default', it should be failed.
+        """
         group_create_body, _ = self._create_security_group()
         self.assertRaises(lib_exc.Conflict,
                           self.security_groups_client.update_security_group,
@@ -187,7 +203,10 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('8fde898f-ce88-493b-adc9-4e4692879fc5')
     def test_create_duplicate_security_group_rule_fails(self):
-        # Create duplicate security group rule, it should fail.
+        """Test creating duplicate security group rule
+
+        Create duplicate security group rule, it should fail.
+        """
         body, _ = self._create_security_group()
 
         min_port = 66
@@ -213,7 +232,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('be308db6-a7cf-4d5c-9baf-71bafd73f35e')
     def test_create_security_group_rule_with_non_existent_security_group(self):
-        # Create security group rules with not existing security group.
+        """Creating security group rules with not existing security group"""
         non_existent_sg = data_utils.rand_uuid()
         self.assertRaises(
             lib_exc.NotFound,
@@ -228,6 +247,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7607439c-af73-499e-bf64-f687fd12a842')
     def test_create_security_group_rule_wrong_ip_prefix_version(self):
+        """Test creating security group rule with wrong ip prefix version"""
         group_create_body, _ = self._create_security_group()
 
         # Create rule with bad remote_ip_prefix
diff --git a/tempest/api/network/test_service_providers.py b/tempest/api/network/test_service_providers.py
index 9ebcd89..5af5244 100644
--- a/tempest/api/network/test_service_providers.py
+++ b/tempest/api/network/test_service_providers.py
@@ -18,12 +18,14 @@
 
 
 class ServiceProvidersTest(base.BaseNetworkTest):
+    """Test network service providers"""
 
     @decorators.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
     @testtools.skipUnless(
         utils.is_extension_enabled('service-type', 'network'),
         'service-type extension not enabled.')
     def test_service_providers_list(self):
+        """Test listing network service providers"""
         body = self.service_providers_client.list_service_providers()
         self.assertIn('service_providers', body)
         self.assertIsInstance(body['service_providers'], list)
diff --git a/tempest/api/network/test_subnetpools_extensions.py b/tempest/api/network/test_subnetpools_extensions.py
index bfc2609..48603ed 100644
--- a/tempest/api/network/test_subnetpools_extensions.py
+++ b/tempest/api/network/test_subnetpools_extensions.py
@@ -49,6 +49,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e9811')
     def test_create_list_show_update_delete_subnetpools(self):
+        """Test create/list/show/update/delete of subnet pools"""
         subnetpool_name = data_utils.rand_name('subnetpools')
         # create subnet pool
         prefix = CONF.network.default_network
diff --git a/tempest/api/network/test_tags.py b/tempest/api/network/test_tags.py
index 2b9719a..5219c34 100644
--- a/tempest/api/network/test_tags.py
+++ b/tempest/api/network/test_tags.py
@@ -51,7 +51,7 @@
 
     @decorators.idempotent_id('ee76bfaf-ac94-4d74-9ecc-4bbd4c583cb1')
     def test_create_list_show_update_delete_tags(self):
-        # Validate that creating a tag on a network resource works.
+        """Validate that creating a tag on a network resource works"""
         tag_name = data_utils.rand_name(self.__class__.__name__ + '-Tag')
         self.tags_client.create_tag('networks', self.network['id'], tag_name)
         self.addCleanup(self.tags_client.delete_all_tags, 'networks',
@@ -158,6 +158,7 @@
 
     @decorators.idempotent_id('c6231efa-9a89-4adf-b050-2a3156b8a1d9')
     def test_create_check_list_and_delete_tags(self):
+        """Test tag operations on subnets/ports/routers/subnetpools"""
         tag_names = self._create_tags_for_each_resource()
 
         for i, resource in enumerate(self.SUPPORTED_RESOURCES):
@@ -181,6 +182,7 @@
 
     @decorators.idempotent_id('663a90f5-f334-4b44-afe0-c5fc1d408791')
     def test_update_and_delete_all_tags(self):
+        """Test update/delete all tags on subnets/ports/routers/subnetpools"""
         self._create_tags_for_each_resource()
 
         for resource in self.SUPPORTED_RESOURCES:
diff --git a/tempest/api/volume/admin/test_groups.py b/tempest/api/volume/admin/test_groups.py
index 2f6eb6b..e67b985 100644
--- a/tempest/api/volume/admin/test_groups.py
+++ b/tempest/api/volume/admin/test_groups.py
@@ -23,12 +23,15 @@
 
 
 class GroupsTest(base.BaseVolumeAdminTest):
+    """Tests of volume groups with microversion greater than 3.12"""
+
     _api_version = 3
     min_microversion = '3.13'
     max_microversion = 'latest'
 
     @decorators.idempotent_id('4b111d28-b73d-4908-9bd2-03dc2992e4d4')
     def test_group_create_show_list_delete(self):
+        """Test creating, showing, listing and deleting of volume group"""
         # Create volume type
         volume_type = self.create_volume_type()
 
@@ -95,6 +98,7 @@
 
     @decorators.idempotent_id('4a8a6fd2-8b3b-4641-8f54-6a6f99320006')
     def test_group_update(self):
+        """Test updating volume group"""
         # Create volume type
         volume_type = self.create_volume_type()
 
@@ -150,12 +154,15 @@
 
 
 class GroupsV314Test(base.BaseVolumeAdminTest):
+    """Tests of volume groups with microversion greater than 3.13"""
+
     _api_version = 3
     min_microversion = '3.14'
     max_microversion = 'latest'
 
     @decorators.idempotent_id('2424af8c-7851-4888-986a-794b10c3210e')
     def test_create_group_from_group(self):
+        """Test creating volume group from volume group"""
         # Create volume type
         volume_type = self.create_volume_type()
 
@@ -185,12 +192,15 @@
 
 
 class GroupsV320Test(base.BaseVolumeAdminTest):
+    """Tests of volume groups with microversion greater than 3.19"""
+
     _api_version = 3
     min_microversion = '3.20'
     max_microversion = 'latest'
 
     @decorators.idempotent_id('b20c696b-0cbc-49a5-8b3a-b1fb9338f45c')
     def test_reset_group_status(self):
+        """Test resetting volume group status to creating/available/error"""
         # Create volume type
         volume_type = self.create_volume_type()
 
diff --git a/tempest/api/volume/admin/test_snapshot_manage.py b/tempest/api/volume/admin/test_snapshot_manage.py
index 37a47ec..ab0aa38 100644
--- a/tempest/api/volume/admin/test_snapshot_manage.py
+++ b/tempest/api/volume/admin/test_snapshot_manage.py
@@ -48,6 +48,7 @@
 
     @decorators.idempotent_id('0132f42d-0147-4b45-8501-cc504bbf7810')
     def test_unmanage_manage_snapshot(self):
+        """Test unmanaging and managing volume snapshot"""
         # Create a volume
         volume = self.create_volume()
 
diff --git a/tempest/api/volume/admin/test_user_messages.py b/tempest/api/volume/admin/test_user_messages.py
index 8048017..096709c 100644
--- a/tempest/api/volume/admin/test_user_messages.py
+++ b/tempest/api/volume/admin/test_user_messages.py
@@ -22,6 +22,8 @@
 
 
 class UserMessagesTest(base.BaseVolumeAdminTest):
+    """Test volume messages with microversion greater than 3.2"""
+
     _api_version = 3
     min_microversion = '3.3'
     max_microversion = 'latest'
@@ -51,6 +53,7 @@
 
     @decorators.idempotent_id('50f29e6e-f363-42e1-8ad1-f67ae7fd4d5a')
     def test_list_show_messages(self):
+        """Test listing and showing volume messages"""
         message_id = self._create_user_message()
         self.addCleanup(self.messages_client.delete_message, message_id)
 
@@ -62,6 +65,7 @@
 
     @decorators.idempotent_id('c6eb6901-cdcc-490f-b735-4fe251842aed')
     def test_delete_message(self):
+        """Test deleting volume messages"""
         message_id = self._create_user_message()
         self.messages_client.delete_message(message_id)
         self.messages_client.wait_for_resource_deletion(message_id)
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 83c27e1..e4e15c5 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -18,9 +18,11 @@
 
 
 class VolumeHostsAdminTestsJSON(base.BaseVolumeAdminTest):
+    """Test fetching volume hosts info by admin users"""
 
     @decorators.idempotent_id('d5f3efa2-6684-4190-9ced-1c2f526352ad')
     def test_list_hosts(self):
+        """Test listing volume hosts"""
         hosts = self.admin_hosts_client.list_hosts()['hosts']
         self.assertGreaterEqual(len(hosts), 2,
                                 "The count of volume hosts is < 2, "
@@ -28,6 +30,7 @@
 
     @decorators.idempotent_id('21168d57-b373-4b71-a3ac-f2c88f0c5d31')
     def test_show_host(self):
+        """Test getting volume host details"""
         hosts = self.admin_hosts_client.list_hosts()['hosts']
         self.assertGreaterEqual(len(hosts), 2,
                                 "The count of volume hosts is < 2, "
diff --git a/tempest/api/volume/admin/test_volume_manage.py b/tempest/api/volume/admin/test_volume_manage.py
index 4b352e0..1e4e7cb 100644
--- a/tempest/api/volume/admin/test_volume_manage.py
+++ b/tempest/api/volume/admin/test_volume_manage.py
@@ -24,6 +24,7 @@
 
 
 class VolumeManageAdminTest(base.BaseVolumeAdminTest):
+    """Test volume manage by admin users"""
 
     @classmethod
     def skip_checks(cls):
@@ -39,6 +40,7 @@
 
     @decorators.idempotent_id('70076c71-0ce1-4208-a8ff-36a66e65cc1e')
     def test_unmanage_manage_volume(self):
+        """Test unmanaging and managing volume"""
         # Create original volume
         org_vol_id = self.create_volume()['id']
         org_vol_info = self.admin_volume_client.show_volume(
diff --git a/tempest/api/volume/admin/test_volume_pools.py b/tempest/api/volume/admin/test_volume_pools.py
index 744bc01..9424994 100644
--- a/tempest/api/volume/admin/test_volume_pools.py
+++ b/tempest/api/volume/admin/test_volume_pools.py
@@ -21,6 +21,8 @@
 
 
 class VolumePoolsAdminTestsJSON(base.BaseVolumeAdminTest):
+    """Test getting volume pools by admin users"""
+
     def _assert_pools(self, with_detail=False):
         cinder_pools = self.admin_scheduler_stats_client.list_pools(
             detail=with_detail)['pools']
@@ -33,8 +35,10 @@
 
     @decorators.idempotent_id('0248a46c-e226-4933-be10-ad6fca8227e7')
     def test_get_pools_without_details(self):
+        """Test getting volume pools without detail"""
         self._assert_pools()
 
     @decorators.idempotent_id('d4bb61f7-762d-4437-b8a4-5785759a0ced')
     def test_get_pools_with_details(self):
+        """Test getting volume pools with detail"""
         self._assert_pools(with_detail=True)
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 5c7ab15..937d28b 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -24,6 +24,7 @@
 
 
 class VolumeQuotasNegativeTestJSON(base.BaseVolumeAdminTest):
+    """Negative tests of volume quotas"""
 
     @classmethod
     def setup_credentials(cls):
@@ -52,6 +53,7 @@
     @decorators.attr(type='negative')
     @decorators.idempotent_id('bf544854-d62a-47f2-a681-90f7a47d86b6')
     def test_quota_volumes(self):
+        """Creating more volume than allowed quota will fail"""
         self.admin_quotas_client.update_quota_set(self.demo_tenant_id,
                                                   volumes=1, gigabytes=-1)
         self.assertRaises(lib_exc.OverLimit,
@@ -61,6 +63,7 @@
     @decorators.attr(type='negative')
     @decorators.idempotent_id('2dc27eee-8659-4298-b900-169d71a91374')
     def test_quota_volume_gigabytes(self):
+        """Creating volume with size larger than allowed quota will fail"""
         self.admin_quotas_client.update_quota_set(
             self.demo_tenant_id, gigabytes=CONF.volume.volume_size, volumes=-1)
         self.assertRaises(lib_exc.OverLimit,
@@ -70,6 +73,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('d321dc21-d8c6-401f-95fe-49f4845f1a6d')
     def test_volume_extend_gigabytes_quota_deviation(self):
+        """Extending volume with size larger than allowed quota will fail"""
         self.admin_quotas_client.update_quota_set(
             self.demo_tenant_id, gigabytes=CONF.volume.volume_size)
         self.assertRaises(lib_exc.OverLimit,
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index ae29049..174cf9e 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -20,11 +20,12 @@
 
 
 class VolumeTypesNegativeTest(base.BaseVolumeAdminTest):
+    """Negative tests of volume type"""
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('878b4e57-faa2-4659-b0d1-ce740a06ae81')
     def test_create_with_empty_name(self):
-        # Should not be able to create volume type with an empty name.
+        """Test creating volume type with an empty name will fail"""
         self.assertRaises(
             lib_exc.BadRequest,
             self.admin_volume_types_client.create_volume_type, name='')
@@ -32,7 +33,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('994610d6-0476-4018-a644-a2602ef5d4aa')
     def test_get_nonexistent_type_id(self):
-        # Should not be able to get volume type with nonexistent type id.
+        """Test getting volume type with nonexistent type id will fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.admin_volume_types_client.show_volume_type,
                           data_utils.rand_uuid())
@@ -40,7 +41,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('6b3926d2-7d73-4896-bc3d-e42dfd11a9f6')
     def test_delete_nonexistent_type_id(self):
-        # Should not be able to delete volume type with nonexistent type id.
+        """Test deleting volume type with nonexistent type id will fail"""
         self.assertRaises(lib_exc.NotFound,
                           self.admin_volume_types_client.delete_volume_type,
                           data_utils.rand_uuid())
@@ -48,7 +49,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('8c09f849-f225-4d78-ba87-bffd9a5e0c6f')
     def test_create_volume_with_private_volume_type(self):
-        # Should not be able to create volume with private volume type.
+        """Test creating volume with private volume type will fail"""
         params = {'os-volume-type-access:is_public': False}
         volume_type = self.create_volume_type(**params)
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 5bac3d8..33e503f 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -23,6 +23,8 @@
 
 
 class VolumesActionsTest(base.BaseVolumeAdminTest):
+    """Test volume actions"""
+
     create_default_network = True
 
     def _create_reset_and_force_delete_temp_volume(self, status=None):
@@ -38,7 +40,10 @@
 
     @decorators.idempotent_id('d063f96e-a2e0-4f34-8b8a-395c42de1845')
     def test_volume_reset_status(self):
-        # test volume reset status : available->error->available->maintenance
+        """Test resetting volume status
+
+        Reset volume status to available->error->available->maintenance
+        """
         volume = self.create_volume()
         self.addCleanup(waiters.wait_for_volume_resource_status,
                         self.volumes_client, volume['id'], 'available')
@@ -52,27 +57,28 @@
 
     @decorators.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
     def test_volume_force_delete_when_volume_is_creating(self):
-        # test force delete when status of volume is creating
+        """Test force deleting volume when its status is creating"""
         self._create_reset_and_force_delete_temp_volume('creating')
 
     @decorators.idempotent_id('db8d607a-aa2e-4beb-b51d-d4005c232011')
     def test_volume_force_delete_when_volume_is_attaching(self):
-        # test force delete when status of volume is attaching
+        """Test force deleting volume when its status is attaching"""
         self._create_reset_and_force_delete_temp_volume('attaching')
 
     @decorators.idempotent_id('3e33a8a8-afd4-4d64-a86b-c27a185c5a4a')
     def test_volume_force_delete_when_volume_is_error(self):
-        # test force delete when status of volume is error
+        """Test force deleting volume when its status is error"""
         self._create_reset_and_force_delete_temp_volume('error')
 
     @decorators.idempotent_id('b957cabd-1486-4e21-90cf-a9ed3c39dfb2')
     def test_volume_force_delete_when_volume_is_maintenance(self):
-        # test force delete when status of volume is maintenance
+        """Test force deleting volume when its status is maintenance"""
         self._create_reset_and_force_delete_temp_volume('maintenance')
 
     @decorators.idempotent_id('d38285d9-929d-478f-96a5-00e66a115b81')
     @utils.services('compute')
     def test_force_detach_volume(self):
+        """Test force detaching volume when its status is error"""
         # Create a server and a volume
         server_id = self.create_server()['id']
         volume_id = self.create_volume()['id']
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 2345698..60f85a4 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -26,11 +26,14 @@
 
 
 class VolumesListTestJSON(base.BaseVolumeTest):
-    # NOTE: This test creates a number of 1G volumes. To run it successfully,
-    # ensure that the backing file for the volume group that Cinder uses
-    # has space for at least 3 1G volumes!
-    # If you are running a Devstack environment, ensure that the
-    # VOLUME_BACKING_FILE_SIZE is at least 4G in your localrc
+    """Test listing volumes
+
+    NOTE: This test creates a number of 1G volumes. To run it successfully,
+    ensure that the backing file for the volume group that Cinder uses
+    has space for at least 3 1G volumes!
+    If you are running a Devstack environment, ensure that the
+    VOLUME_BACKING_FILE_SIZE is at least 4G in your localrc
+    """
 
     VOLUME_FIELDS = ('id', 'name')
 
@@ -116,7 +119,7 @@
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('0b6ddd39-b948-471f-8038-4787978747c4')
     def test_volume_list(self):
-        # Get a list of Volumes
+        """Test getting a list of volumes"""
         # Fetch all volumes
         fetched_list = self.volumes_client.list_volumes()['volumes']
         self._assert_volumes_in(fetched_list, self.volume_list,
@@ -124,13 +127,14 @@
 
     @decorators.idempotent_id('adcbb5a7-5ad8-4b61-bd10-5380e111a877')
     def test_volume_list_with_details(self):
-        # Get a list of Volumes with details
+        """Test getting a list of detailed volumes"""
         # Fetch all Volumes
         fetched_list = self.volumes_client.list_volumes(detail=True)['volumes']
         self._assert_volumes_in(fetched_list, self.volume_list)
 
     @decorators.idempotent_id('a28e8da4-0b56-472f-87a8-0f4d3f819c02')
     def test_volume_list_by_name(self):
+        """Test getting a list of volumes filtered by volume name"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
         fetched_vol = self.volumes_client.list_volumes(
@@ -140,6 +144,7 @@
 
     @decorators.idempotent_id('2de3a6d4-12aa-403b-a8f2-fdeb42a89623')
     def test_volume_list_details_by_name(self):
+        """Test getting a list of detailed volumes filtered by volume name"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name']}
         fetched_vol = self.volumes_client.list_volumes(
@@ -149,6 +154,7 @@
 
     @decorators.idempotent_id('39654e13-734c-4dab-95ce-7613bf8407ce')
     def test_volumes_list_by_status(self):
+        """Test getting a list of volumes filtered by volume status"""
         params = {'status': 'available'}
         fetched_list = self.volumes_client.list_volumes(
             params=params)['volumes']
@@ -158,6 +164,7 @@
 
     @decorators.idempotent_id('2943f712-71ec-482a-bf49-d5ca06216b9f')
     def test_volumes_list_details_by_status(self):
+        """Test getting a list of detailed volumes filtered by status"""
         params = {'status': 'available'}
         fetched_list = self.volumes_client.list_volumes(
             detail=True, params=params)['volumes']
@@ -181,6 +188,7 @@
 
     @decorators.idempotent_id('2016a939-72ec-482a-bf49-d5ca06216b9f')
     def test_volumes_list_details_by_bootable(self):
+        """Test getting a list of detailed volumes filtered by bootable"""
         params = {'bootable': 'false'}
         fetched_list = self.volumes_client.list_volumes(
             detail=True, params=params)['volumes']
@@ -190,6 +198,7 @@
 
     @decorators.idempotent_id('c0cfa863-3020-40d7-b587-e35f597d5d87')
     def test_volumes_list_by_availability_zone(self):
+        """Test getting a list of volumes filtered by availability zone"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
@@ -201,6 +210,7 @@
 
     @decorators.idempotent_id('e1b80d13-94f0-4ba2-a40e-386af29f8db1')
     def test_volumes_list_details_by_availability_zone(self):
+        """Test getting a list of detailed volumes by availability zone"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
@@ -212,19 +222,19 @@
 
     @decorators.idempotent_id('b5ebea1b-0603-40a0-bb41-15fcd0a53214')
     def test_volume_list_with_param_metadata(self):
-        # Test to list volumes when metadata param is given
+        """Test listing volumes when metadata param is given"""
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params)
 
     @decorators.idempotent_id('1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d')
     def test_volume_list_with_detail_param_metadata(self):
-        # Test to list volumes details when metadata param is given
+        """Test listing volumes details when metadata param is given"""
         params = {'metadata': self.metadata}
         self._list_by_param_value_and_assert(params, with_detail=True)
 
     @decorators.idempotent_id('777c87c1-2fc4-4883-8b8e-5c0b951d1ec8')
     def test_volume_list_param_display_name_and_status(self):
-        # Test to list volume when display name and status param is given
+        """Test listing volume when display name and status param is given"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name'],
                   'status': 'available'}
@@ -232,7 +242,7 @@
 
     @decorators.idempotent_id('856ab8ca-6009-4c37-b691-be1065528ad4')
     def test_volume_list_with_detail_param_display_name_and_status(self):
-        # Test to list volume when name and status param is given
+        """Test listing volume when name and status param is given"""
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {'name': volume['name'],
                   'status': 'available'}
@@ -240,7 +250,7 @@
 
     @decorators.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
     def test_volume_list_details_with_multiple_params(self):
-        # List volumes detail using combined condition
+        """Test listing volumes detail using combined filtering condition"""
         def _list_details_with_multiple_params(limit=2,
                                                status='available',
                                                sort_dir='asc',
@@ -375,14 +385,29 @@
 
     @decorators.idempotent_id('e9138a2c-f67b-4796-8efa-635c196d01de')
     def test_volume_list_details_pagination(self):
+        """Test listing volumes with details by pagination
+
+        All volumes will be returned by multiple requests, and the number of
+        'limit' volumes will be returned at a time.
+        """
         self._test_pagination('volumes', ids=self.volume_id_list, detail=True)
 
     @decorators.idempotent_id('af55e775-8e4b-4feb-8719-215c43b0238c')
     def test_volume_list_pagination(self):
+        """Test listing volumes by pagination
+
+        All volumes will be returned by multiple requests, and the number of
+        'limit' volumes will be returned at a time.
+        """
         self._test_pagination('volumes', ids=self.volume_id_list, detail=False)
 
     @decorators.idempotent_id('46eff077-100b-427f-914e-3db2abcdb7e2')
     def test_volume_list_with_detail_param_marker(self):
+        """Test listing volumes with details from the specified marker
+
+        Choose a volume id from all volumes as a marker, list volumes with
+        that marker, only volumes with id greater than marker will be returned.
+        """
         # Choosing a random volume from a list of volumes for 'marker'
         # parameter
         marker = random.choice(self.volume_id_list)
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index f1adeab..b0bf5b2 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -76,8 +76,6 @@
         if self.method == 'GET' or self.method == 'HEAD':
             if 'x-timestamp' not in actual:
                 return NonExistentHeader('x-timestamp')
-            if 'accept-ranges' not in actual:
-                return NonExistentHeader('accept-ranges')
             if self.target == 'Account':
                 if 'x-account-bytes-used' not in actual:
                     return NonExistentHeader('x-account-bytes-used')
diff --git a/tempest/config.py b/tempest/config.py
index 11f9426..eca2023 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from __future__ import print_function
-
 import os
 import tempfile
 
@@ -658,6 +656,12 @@
                                   'are current one. In future, Tempest will '
                                   'test v2 APIs only so this config option '
                                   'will be removed.'),
+    # Image import feature is setup in devstack victoria onwards.
+    # Once all stable branches setup the same via glance standalone
+    # mode or with uwsgi, we can remove this config option.
+    cfg.BoolOpt('import_image',
+                default=False,
+                help="Is image import feature enabled"),
 ]
 
 network_group = cfg.OptGroup(name='network',
diff --git a/tempest/lib/api_schema/response/volume/group_snapshots.py b/tempest/lib/api_schema/response/volume/group_snapshots.py
new file mode 100644
index 0000000..c75c3ba
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/group_snapshots.py
@@ -0,0 +1,106 @@
+# Copyright 2015 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
+create_group_snapshot = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_snapshot': {
+                'type': 'object',
+                'properties': {
+                    'id': {'type': 'string', 'format': 'uuid'},
+                    'name': {'type': 'string'},
+                    'group_type_id': {'type': 'string', 'format': 'uuid'},
+                },
+                'additionalProperties': False,
+                'required': ['id', 'name', 'group_type_id']
+            }
+        },
+        'additionalProperties': False,
+        'required': ['group_snapshot']
+    }
+}
+
+delete_group_snapshot = {'status_code': [202]}
+
+common_show_group_snapshot = {
+    'type': 'object',
+    'properties': {
+        'created_at': parameter_types.date_time,
+        'group_id': {'type': 'string', 'format': 'uuid'},
+        'id': {'type': 'string', 'format': 'uuid'},
+        'name': {'type': 'string'},
+        'status': {'type': 'string'},
+        'description': {'type': ['string', 'null']},
+        'group_type_id': {'type': 'string', 'format': 'uuid'},
+    },
+    'additionalProperties': False,
+    'required': ['created_at', 'group_id', 'id', 'name',
+                 'status', 'description', 'group_type_id']
+}
+
+show_group_snapshot = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_snapshot': common_show_group_snapshot
+        },
+        'additionalProperties': False,
+        'required': ['group_snapshot']
+    }
+}
+
+list_group_snapshots_no_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_snapshots': {
+                'type': 'array',
+                'items': {
+                    'type': 'object',
+                    'properties': {
+                        'id': {'type': 'string', 'format': 'uuid'},
+                        'name': {'type': 'string'}
+                    },
+                    'additionalProperties': False,
+                    'required': ['id', 'name'],
+                }
+            }
+        },
+        'additionalProperties': False,
+        'required': ['group_snapshots'],
+    }
+}
+
+list_group_snapshots_with_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_snapshots': {
+                'type': 'array',
+                'items': common_show_group_snapshot
+            }
+        },
+        'additionalProperties': False,
+        'required': ['group_snapshots'],
+    }
+}
+
+reset_group_snapshot_status = {'status_code': [202]}
diff --git a/tempest/lib/api_schema/response/volume/group_types.py b/tempest/lib/api_schema/response/volume/group_types.py
index bcfa32e..4fc9ae8 100644
--- a/tempest/lib/api_schema/response/volume/group_types.py
+++ b/tempest/lib/api_schema/response/volume/group_types.py
@@ -73,6 +73,18 @@
     }
 }
 
+show_default_group_type = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'group_type': common_show_group_type
+        },
+        'additionalProperties': False,
+        'required': ['group_type']
+    }
+}
+
 update_group_type = {
     'status_code': [200],
     'response_body': {
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index 431a0a0..0513e90 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -21,6 +21,7 @@
 
 import jsonschema
 from oslo_log import log as logging
+from oslo_log import versionutils
 from oslo_serialization import jsonutils as json
 import six
 from six.moves import urllib
@@ -177,13 +178,27 @@
         return self.auth_provider.credentials.tenant_name
 
     @property
+    def project_id(self):
+        """The project id being used for requests
+
+        :rtype: string
+        :return: The project id being used for requests
+        """
+        return self.auth_provider.credentials.tenant_id
+
+    @property
     def tenant_id(self):
         """The tenant/project id being used for requests
 
         :rtype: string
         :return: The tenant/project id being used for requests
         """
-        return self.auth_provider.credentials.tenant_id
+        # NOTE(ralonsoh): this property should be deprecated, reference
+        # blueprint adopt-oslo-versioned-objects-for-db.
+        versionutils.report_deprecated_feature(
+            self.LOG, '"tenant_id" property is deprecated for removal, use '
+                      '"project_id" instead')
+        return self.project_id
 
     @property
     def password(self):
@@ -899,12 +914,44 @@
                 raise exceptions.TimeoutException(message)
             time.sleep(self.build_interval)
 
+    def wait_for_resource_activation(self, id):
+        """Waits for a resource to become active
+
+        This method will loop over is_resource_active until either
+        is_resource_active returns True or the build timeout is reached. This
+        depends on is_resource_active being implemented
+
+        :param str id: The id of the resource to check
+        :raises TimeoutException: If the build_timeout has elapsed and the
+                                  resource still hasn't been active
+        """
+        start_time = int(time.time())
+        while True:
+            if self.is_resource_active(id):
+                return
+            if int(time.time()) - start_time >= self.build_timeout:
+                message = ('Failed to reach active state %(resource_type)s '
+                           '%(id)s within the required time (%(timeout)s s).' %
+                           {'resource_type': self.resource_type, 'id': id,
+                            'timeout': self.build_timeout})
+                caller = test_utils.find_test_caller()
+                if caller:
+                    message = '(%s) %s' % (caller, message)
+                raise exceptions.TimeoutException(message)
+            time.sleep(self.build_interval)
+
     def is_resource_deleted(self, id):
         """Subclasses override with specific deletion detection."""
         message = ('"%s" does not implement is_resource_deleted'
                    % self.__class__.__name__)
         raise NotImplementedError(message)
 
+    def is_resource_active(self, id):
+        """Subclasses override with specific active detection."""
+        message = ('"%s" does not implement is_resource_active'
+                   % self.__class__.__name__)
+        raise NotImplementedError(message)
+
     @property
     def resource_type(self):
         """Returns the primary type of resource this client works with."""
diff --git a/tempest/lib/common/thread.py b/tempest/lib/common/thread.py
index 510fc36..b47d40d 100644
--- a/tempest/lib/common/thread.py
+++ b/tempest/lib/common/thread.py
@@ -13,10 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-# This make disable relative module import
-from __future__ import absolute_import
-
-
 import six
 
 if six.PY2:
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index 90778da..4713cce 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -128,6 +128,15 @@
             return True
         return False
 
+    def is_resource_active(self, id):
+        try:
+            image = self.show_image(id)
+            if image['status'] != 'active':
+                return False
+        except lib_exc.NotFound:
+            return False
+        return True
+
     @property
     def resource_type(self):
         """Returns the primary type of resource this client works with."""
@@ -152,6 +161,83 @@
         self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
+    def stage_image_file(self, image_id, data):
+        """Upload binary image data to staging area.
+
+        For a full list of available parameters, please refer to the official
+        API reference (stage API:
+        https://docs.openstack.org/api-ref/image/v2/#interoperable-image-import
+        """
+        url = 'images/%s/stage' % image_id
+
+        # We are going to do chunked transfer, so split the input data
+        # info fixed-sized chunks.
+        headers = {'Content-Type': 'application/octet-stream'}
+        data = iter(functools.partial(data.read, CHUNKSIZE), b'')
+
+        resp, body = self.request('PUT', url, headers=headers,
+                                  body=data, chunked=True)
+        self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def info_import(self):
+        """Return information about server-supported import methods."""
+        url = 'info/import'
+        resp, body = self.get(url)
+
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def info_stores(self):
+        """Return information about server-supported stores."""
+        url = 'info/stores'
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
+    def image_import(self, image_id, method='glance-direct',
+                     all_stores_must_succeed=None, all_stores=True,
+                     stores=None, image_uri=None):
+        """Import data from staging area to glance store.
+
+        For a full list of available parameters, please refer to the official
+        API reference (stage API:
+        https://docs.openstack.org/api-ref/image/v2/#interoperable-image-import
+
+        :param method: The import method (i.e. glance-direct) to use
+        :param all_stores_must_succeed: Boolean indicating if all store imports
+                                        must succeed for the import to be
+                                        considered successful. Must be None if
+                                        server does not support multistore.
+        :param all_stores: Boolean indicating if image should be imported to
+                           all available stores (incompatible with stores)
+        :param stores: A list of destination store names for the import. Must
+                       be None if server does not support multistore.
+        :param image_uri: A URL to be used with the web-download method
+        """
+        url = 'images/%s/import' % image_id
+        data = {
+            "method": {
+                "name": method
+            },
+        }
+        if stores is not None:
+            data["stores"] = stores
+        else:
+            data["all_stores"] = all_stores
+
+        if all_stores_must_succeed is not None:
+            data['all_stores_must_succeed'] = all_stores_must_succeed
+        if image_uri:
+            data['method']['uri'] = image_uri
+        data = json.dumps(data)
+        headers = {'Content-Type': 'application/json'}
+        resp, _ = self.post(url, data, headers=headers)
+
+        self.expected_success(202, resp.status)
+        return rest_client.ResponseBody(resp)
+
     def show_image_file(self, image_id):
         """Download binary image data.
 
diff --git a/tempest/lib/services/network/quotas_client.py b/tempest/lib/services/network/quotas_client.py
index 997d201..96cc65d 100644
--- a/tempest/lib/services/network/quotas_client.py
+++ b/tempest/lib/services/network/quotas_client.py
@@ -12,11 +12,33 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import functools
+
 from tempest.lib.services.network import base
 
 
+def _warning_deprecate_tenant_id(func):
+    @functools.wraps(func)
+    def inner(*args, **kwargs):
+        _self = args[0]
+        # check length of arg to know whether 'tenant_id' is passed as
+        # positional arg or kwargs.
+        if len(args) < 2:
+            if 'tenant_id' in kwargs:
+                _self.LOG.warning(
+                    'positional arg name "tenant_id" is deprecated, for '
+                    'removal, please start using "project_id" instead')
+            elif 'project_id' in kwargs:
+                # fallback to deprecated name till deprecation phase.
+                kwargs['tenant_id'] = kwargs.pop('project_id')
+
+        return func(*args, **kwargs)
+    return inner
+
+
 class QuotasClient(base.BaseNetworkClient):
 
+    @_warning_deprecate_tenant_id
     def update_quotas(self, tenant_id, **kwargs):
         """Update quota for a project.
 
@@ -28,12 +50,14 @@
         uri = '/quotas/%s' % tenant_id
         return self.update_resource(uri, put_body)
 
+    @_warning_deprecate_tenant_id
     def reset_quotas(self, tenant_id):  # noqa
         # NOTE: This noqa is for passing T111 check and we cannot rename
         #       to keep backwards compatibility.
         uri = '/quotas/%s' % tenant_id
         return self.delete_resource(uri)
 
+    @_warning_deprecate_tenant_id
     def show_quotas(self, tenant_id, **fields):
         """Show quota for a project.
 
@@ -54,11 +78,13 @@
         uri = '/quotas'
         return self.list_resources(uri, **filters)
 
+    @_warning_deprecate_tenant_id
     def show_default_quotas(self, tenant_id):
         """List default quotas for a project."""
         uri = '/quotas/%s/default' % tenant_id
         return self.show_resource(uri)
 
+    @_warning_deprecate_tenant_id
     def show_quota_details(self, tenant_id):
         """Show quota details for a project."""
         uri = '/quotas/%s/details.json' % tenant_id
diff --git a/tempest/lib/services/volume/v3/group_snapshots_client.py b/tempest/lib/services/volume/v3/group_snapshots_client.py
index e425a3f..4051c06 100644
--- a/tempest/lib/services/volume/v3/group_snapshots_client.py
+++ b/tempest/lib/services/volume/v3/group_snapshots_client.py
@@ -16,6 +16,7 @@
 from oslo_serialization import jsonutils as json
 from six.moves.urllib import parse as urllib
 
+from tempest.lib.api_schema.response.volume import group_snapshots as schema
 from tempest.lib.common import rest_client
 from tempest.lib import exceptions as lib_exc
 from tempest.lib.services.volume import base_client
@@ -34,7 +35,7 @@
         post_body = json.dumps({'group_snapshot': kwargs})
         resp, body = self.post('group_snapshots', post_body)
         body = json.loads(body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.create_group_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def delete_group_snapshot(self, group_snapshot_id):
@@ -44,7 +45,7 @@
         https://docs.openstack.org/api-ref/block-storage/v3/#delete-group-snapshot
         """
         resp, body = self.delete('group_snapshots/%s' % group_snapshot_id)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.delete_group_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_group_snapshot(self, group_snapshot_id):
@@ -56,7 +57,7 @@
         url = "group_snapshots/%s" % str(group_snapshot_id)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_group_snapshot, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def list_group_snapshots(self, detail=False, **params):
@@ -67,13 +68,15 @@
         https://docs.openstack.org/api-ref/block-storage/v3/#list-group-snapshots-with-details
         """
         url = "group_snapshots"
+        list_group_snapshots = schema.list_group_snapshots_no_detail
         if detail:
             url += "/detail"
+            list_group_snapshots = schema.list_group_snapshots_with_detail
         if params:
             url += '?%s' % urllib.urlencode(params)
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(list_group_snapshots, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def reset_group_snapshot_status(self, group_snapshot_id, status_to_set):
@@ -85,7 +88,7 @@
         post_body = json.dumps({'reset_status': {'status': status_to_set}})
         resp, body = self.post('group_snapshots/%s/action' % group_snapshot_id,
                                post_body)
-        self.expected_success(202, resp.status)
+        self.validate_response(schema.reset_group_snapshot_status, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def is_resource_deleted(self, id):
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index e0bf5e2..1dcd508 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -73,7 +73,7 @@
         url = 'group_types/default'
         resp, body = self.get(url)
         body = json.loads(body)
-        self.expected_success(200, resp.status)
+        self.validate_response(schema.show_default_group_type, resp, body)
         return rest_client.ResponseBody(resp, body)
 
     def show_group_type(self, group_type_id):
diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py
index aa6c867..4ac4112 100644
--- a/tempest/lib/services/volume/v3/versions_client.py
+++ b/tempest/lib/services/volume/v3/versions_client.py
@@ -54,8 +54,9 @@
         """
 
         version_url = urljoin(self._get_base_version_url(), version + '/')
-        resp, body = self.raw_request(version_url, 'GET',
-                                      {'X-Auth-Token': self.token})
+        headers = self.get_headers()
+        headers['X-Auth-Token'] = self.token
+        resp, body = self.raw_request(version_url, 'GET', headers=headers)
         self._error_checker(resp, body)
         body = json.loads(body)
         self.validate_response(schema.volume_api_version_details, resp, body)
diff --git a/tempest/lib/services/volume/v3/volumes_client.py b/tempest/lib/services/volume/v3/volumes_client.py
index 4fb6d2e..9c6729b 100644
--- a/tempest/lib/services/volume/v3/volumes_client.py
+++ b/tempest/lib/services/volume/v3/volumes_client.py
@@ -219,7 +219,7 @@
         if volume["volume"]["status"] == "error_deleting":
             raise lib_exc.DeleteErrorException(
                 "Volume %s failed to delete and is in error_deleting status" %
-                volume['id'])
+                volume['volume']['id'])
         return False
 
     @property
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 004bf9e..a80b77d 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -868,15 +868,15 @@
             raise cls.skipException('Neutron not available')
 
     def _create_network(self, networks_client=None,
-                        tenant_id=None,
+                        project_id=None,
                         namestart='network-smoke-',
                         port_security_enabled=True, **net_dict):
         if not networks_client:
             networks_client = self.networks_client
-        if not tenant_id:
-            tenant_id = networks_client.tenant_id
+        if not project_id:
+            project_id = networks_client.project_id
         name = data_utils.rand_name(namestart)
-        network_kwargs = dict(name=name, tenant_id=tenant_id)
+        network_kwargs = dict(name=name, project_id=project_id)
         if net_dict:
             network_kwargs.update(net_dict)
         # Neutron disables port security by default so we have to check the
@@ -901,14 +901,14 @@
         if not subnets_client:
             subnets_client = self.subnets_client
 
-        def cidr_in_use(cidr, tenant_id):
+        def cidr_in_use(cidr, project_id):
             """Check cidr existence
 
             :returns: True if subnet with cidr already exist in tenant
                   False else
             """
             cidr_in_use = self.os_admin.subnets_client.list_subnets(
-                tenant_id=tenant_id, cidr=cidr)['subnets']
+                project_id=project_id, cidr=cidr)['subnets']
             return len(cidr_in_use) != 0
 
         ip_version = kwargs.pop('ip_version', 4)
@@ -927,13 +927,13 @@
         # blocks until an unallocated block is found.
         for subnet_cidr in tenant_cidr.subnet(num_bits):
             str_cidr = str(subnet_cidr)
-            if cidr_in_use(str_cidr, tenant_id=network['tenant_id']):
+            if cidr_in_use(str_cidr, project_id=network['project_id']):
                 continue
 
             subnet = dict(
                 name=data_utils.rand_name(namestart),
                 network_id=network['id'],
-                tenant_id=network['tenant_id'],
+                project_id=network['project_id'],
                 cidr=str_cidr,
                 ip_version=ip_version,
                 **kwargs
@@ -1015,7 +1015,7 @@
         kwargs = {
             'floating_network_id': external_network_id,
             'port_id': port_id,
-            'tenant_id': thing['tenant_id'],
+            'tenant_id': thing.get('project_id') or thing['tenant_id'],
             'fixed_ip_address': ip4,
         }
         if CONF.network.subnet_id:
@@ -1122,18 +1122,18 @@
         self.fail(msg)
 
     def _create_security_group(self, security_group_rules_client=None,
-                               tenant_id=None,
+                               project_id=None,
                                namestart='secgroup-smoke',
                                security_groups_client=None):
         if security_group_rules_client is None:
             security_group_rules_client = self.security_group_rules_client
         if security_groups_client is None:
             security_groups_client = self.security_groups_client
-        if tenant_id is None:
-            tenant_id = security_groups_client.tenant_id
+        if project_id is None:
+            project_id = security_groups_client.project_id
         secgroup = self._create_empty_security_group(
             namestart=namestart, client=security_groups_client,
-            tenant_id=tenant_id)
+            project_id=project_id)
 
         # Add rules to the security group
         rules = self._create_loginable_secgroup_rule(
@@ -1141,11 +1141,11 @@
             secgroup=secgroup,
             security_groups_client=security_groups_client)
         for rule in rules:
-            self.assertEqual(tenant_id, rule['tenant_id'])
+            self.assertEqual(project_id, rule['project_id'])
             self.assertEqual(secgroup['id'], rule['security_group_id'])
         return secgroup
 
-    def _create_empty_security_group(self, client=None, tenant_id=None,
+    def _create_empty_security_group(self, client=None, project_id=None,
                                      namestart='secgroup-smoke'):
         """Create a security group without rules.
 
@@ -1153,23 +1153,23 @@
          - IPv4 egress to any
          - IPv6 egress to any
 
-        :param tenant_id: secgroup will be created in this tenant
+        :param project_id: secgroup will be created in this project
         :returns: the created security group
         """
         if client is None:
             client = self.security_groups_client
-        if not tenant_id:
-            tenant_id = client.tenant_id
+        if not project_id:
+            project_id = client.project_id
         sg_name = data_utils.rand_name(namestart)
         sg_desc = sg_name + " description"
         sg_dict = dict(name=sg_name,
                        description=sg_desc)
-        sg_dict['tenant_id'] = tenant_id
+        sg_dict['project_id'] = project_id
         result = client.create_security_group(**sg_dict)
 
         secgroup = result['security_group']
         self.assertEqual(secgroup['name'], sg_name)
-        self.assertEqual(tenant_id, secgroup['tenant_id'])
+        self.assertEqual(project_id, secgroup['project_id'])
         self.assertEqual(secgroup['description'], sg_desc)
 
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
@@ -1178,15 +1178,15 @@
 
     def _create_security_group_rule(self, secgroup=None,
                                     sec_group_rules_client=None,
-                                    tenant_id=None,
+                                    project_id=None,
                                     security_groups_client=None, **kwargs):
         """Create a rule from a dictionary of rule parameters.
 
         Create a rule in a secgroup. if secgroup not defined will search for
-        default secgroup in tenant_id.
+        default secgroup in project_id.
 
         :param secgroup: the security group.
-        :param tenant_id: if secgroup not passed -- the tenant in which to
+        :param project_id: if secgroup not passed -- the tenant in which to
             search for default secgroup
         :param kwargs: a dictionary containing rule parameters:
             for example, to allow incoming ssh:
@@ -1201,18 +1201,18 @@
             sec_group_rules_client = self.security_group_rules_client
         if security_groups_client is None:
             security_groups_client = self.security_groups_client
-        if not tenant_id:
-            tenant_id = security_groups_client.tenant_id
+        if not project_id:
+            project_id = security_groups_client.project_id
         if secgroup is None:
-            # Get default secgroup for tenant_id
+            # Get default secgroup for project_id
             default_secgroups = security_groups_client.list_security_groups(
-                name='default', tenant_id=tenant_id)['security_groups']
-            msg = "No default security group for tenant %s." % (tenant_id)
+                name='default', project_id=project_id)['security_groups']
+            msg = "No default security group for project %s." % (project_id)
             self.assertNotEmpty(default_secgroups, msg)
             secgroup = default_secgroups[0]
 
         ruleset = dict(security_group_id=secgroup['id'],
-                       tenant_id=secgroup['tenant_id'])
+                       project_id=secgroup['project_id'])
         ruleset.update(kwargs)
 
         sg_rule = sec_group_rules_client.create_security_group_rule(**ruleset)
@@ -1278,7 +1278,7 @@
 
         return rules
 
-    def _get_router(self, client=None, tenant_id=None):
+    def _get_router(self, client=None, project_id=None):
         """Retrieve a router for the given tenant id.
 
         If a public router has been configured, it will be returned.
@@ -1289,8 +1289,8 @@
         """
         if not client:
             client = self.routers_client
-        if not tenant_id:
-            tenant_id = client.tenant_id
+        if not project_id:
+            project_id = client.project_id
         router_id = CONF.network.public_router_id
         network_id = CONF.network.public_network_id
         if router_id:
@@ -1300,7 +1300,7 @@
             router = client.create_router(
                 name=data_utils.rand_name(self.__class__.__name__ + '-router'),
                 admin_state_up=True,
-                tenant_id=tenant_id,
+                project_id=project_id,
                 external_gateway_info=dict(network_id=network_id))['router']
             self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                             client.delete_router, router['id'])
@@ -1311,14 +1311,14 @@
 
     def create_networks(self, networks_client=None,
                         routers_client=None, subnets_client=None,
-                        tenant_id=None, dns_nameservers=None,
+                        project_id=None, dns_nameservers=None,
                         port_security_enabled=True, **net_dict):
         """Create a network with a subnet connected to a router.
 
         The baremetal driver is a special case since all nodes are
         on the same shared network.
 
-        :param tenant_id: id of tenant to create resources in.
+        :param project_id: id of project to create resources in.
         :param dns_nameservers: list of dns servers to send to subnet.
         :param port_security_enabled: whether or not port_security is enabled
         :param net_dict: a dict containing experimental network information in
@@ -1343,11 +1343,11 @@
         else:
             network = self._create_network(
                 networks_client=networks_client,
-                tenant_id=tenant_id,
+                project_id=project_id,
                 port_security_enabled=port_security_enabled,
                 **net_dict)
             router = self._get_router(client=routers_client,
-                                      tenant_id=tenant_id)
+                                      project_id=project_id)
             subnet_kwargs = dict(network=network,
                                  subnets_client=subnets_client)
             # use explicit check because empty list is a valid option
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index b1919d4..e26dc9d 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -262,7 +262,7 @@
         self._wait_server_status_and_check_network_connectivity(
             server, keypair, floating_ip)
 
-    @decorators.skip_because(bug='1836595')
+    @decorators.unstable_test(bug='1836595')
     @decorators.idempotent_id('25b188d7-0183-4b1e-a11d-15840c8e2fd6')
     @testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
                           'Cold migration is not available.')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index f466729..6c1b3fa 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -331,7 +331,7 @@
         internal_ips = (
             p['fixed_ips'][0]['ip_address'] for p in
             self.os_admin.ports_client.list_ports(
-                tenant_id=server['tenant_id'],
+                project_id=server['tenant_id'],
                 network_id=network['id'])['ports']
             if p['device_owner'].startswith('network') or
             p['device_owner'].startswith('compute')
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 9cbd831..3fc93e4 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -176,7 +176,7 @@
         cls.primary_tenant = cls.TenantProperties(cls.os_primary)
         cls.alt_tenant = cls.TenantProperties(cls.os_alt)
         for tenant in [cls.primary_tenant, cls.alt_tenant]:
-            cls.tenants[tenant.creds.tenant_id] = tenant
+            cls.tenants[tenant.creds.project_id] = tenant
 
         cls.floating_ip_access = not CONF.network.public_router_id
 
@@ -199,14 +199,14 @@
     def _create_tenant_security_groups(self, tenant):
         access_sg = self._create_empty_security_group(
             namestart='secgroup_access-',
-            tenant_id=tenant.creds.tenant_id,
+            project_id=tenant.creds.project_id,
             client=tenant.manager.security_groups_client
         )
 
         # don't use default secgroup since it allows in-project traffic
         def_sg = self._create_empty_security_group(
             namestart='secgroup_general-',
-            tenant_id=tenant.creds.tenant_id,
+            project_id=tenant.creds.project_id,
             client=tenant.manager.security_groups_client
         )
         tenant.security_groups.update(access=access_sg, default=def_sg)
@@ -536,7 +536,7 @@
         # Create empty security group and add icmp rule in it
         new_sg = self._create_empty_security_group(
             namestart='secgroup_new-',
-            tenant_id=new_tenant.creds.tenant_id,
+            project_id=new_tenant.creds.project_id,
             client=new_tenant.manager.security_groups_client)
         icmp_rule = dict(
             protocol='icmp',
diff --git a/tempest/tests/lib/services/network/test_quotas_client.py b/tempest/tests/lib/services/network/test_quotas_client.py
index aa6c1a1..7dce4e1 100644
--- a/tempest/tests/lib/services/network/test_quotas_client.py
+++ b/tempest/tests/lib/services/network/test_quotas_client.py
@@ -52,7 +52,7 @@
         }
     }
 
-    FAKE_QUOTA_TENANT_ID = "bab7d5c60cd041a0a36f7c4b6e1dd978"
+    FAKE_QUOTA_PROJECT_ID = "bab7d5c60cd041a0a36f7c4b6e1dd978"
 
     FAKE_QUOTA_DETAILS = {
         "quota": {
@@ -115,7 +115,7 @@
             self.FAKE_PROJECT_QUOTAS,
             bytes_body,
             200,
-            tenant_id=self.FAKE_QUOTA_TENANT_ID)
+            project_id=self.FAKE_QUOTA_PROJECT_ID)
 
     def _test_show_default_quotas(self, bytes_body=False):
         self.check_service_client_function(
@@ -124,7 +124,7 @@
             self.FAKE_PROJECT_QUOTAS,
             bytes_body,
             200,
-            tenant_id=self.FAKE_QUOTA_TENANT_ID)
+            project_id=self.FAKE_QUOTA_PROJECT_ID)
 
     def _test_update_quotas(self, bytes_body=False):
         self.check_service_client_function(
@@ -133,7 +133,7 @@
             self.FAKE_PROJECT_QUOTAS,
             bytes_body,
             200,
-            tenant_id=self.FAKE_QUOTA_TENANT_ID)
+            project_id=self.FAKE_QUOTA_PROJECT_ID)
 
     def _test_show_quota_details(self, bytes_body=False):
         self.check_service_client_function(
@@ -142,7 +142,7 @@
             self.FAKE_QUOTA_DETAILS,
             bytes_body,
             200,
-            tenant_id=self.FAKE_QUOTA_TENANT_ID)
+            project_id=self.FAKE_QUOTA_PROJECT_ID)
 
     def test_reset_quotas(self):
         self.check_service_client_function(
@@ -150,7 +150,7 @@
             "tempest.lib.common.rest_client.RestClient.delete",
             {},
             status=204,
-            tenant_id=self.FAKE_QUOTA_TENANT_ID)
+            project_id=self.FAKE_QUOTA_PROJECT_ID)
 
     def test_list_quotas_with_str_body(self):
         self._test_list_quotas()