This is an automated email from the ASF dual-hosted git repository.

bkyryliuk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 4e340c8  feat: Switch from nosetest to pytest (#10177)
4e340c8 is described below

commit 4e340c83687f9fffec00c939c29397ee85abd231
Author: Bogdan <b.kyryl...@gmail.com>
AuthorDate: Mon Jun 29 15:36:06 2020 -0700

    feat: Switch from nosetest to pytest (#10177)
    
    * Switch from nosetest to pytest
    
    Fix schedule tests
    
    Collect pytest coverage
    
    Move pytest config into pytest.ini
    
    Move cov to the pytest.ini
    
    * Append coverage for the 2nd run
    
    * Add coverage to all commands
    
    * Coverage only for tests
    
    * Get coverage from 1 place
    
    * Rename classes to be  pytest compatible
    
    * Test coverage for examples and tests
    
    * Max diff to -1
    
    * Explain how to run pytest for the whole project
    
    * Do not append code coverage for the main run
    
    * Do not run coverage on examples
    
    Co-authored-by: bogdan kyryliuk <bogdankyryl...@dropbox.com>
---
 scripts/python_tests.sh => pytest.ini           | 16 +++++-----------
 requirements-dev.txt                            |  3 ++-
 scripts/python_tests.sh                         |  4 ++--
 scripts/tests/run.sh                            |  4 ++--
 setup.cfg                                       |  7 -------
 tests/access_tests.py                           |  4 +++-
 tests/base_api_tests.py                         |  2 +-
 tests/base_tests.py                             |  4 +---
 tests/cache_tests.py                            |  5 +----
 tests/celery_tests.py                           |  6 +++---
 tests/charts/api_tests.py                       |  5 +----
 tests/charts/schema_tests.py                    |  2 +-
 tests/config_tests.py                           |  5 +----
 tests/core_tests.py                             |  5 +----
 tests/dashboard_tests.py                        |  2 +-
 tests/dashboards/api_tests.py                   |  5 +----
 tests/dashboards/dao_tests.py                   |  2 +-
 tests/database_api_tests.py                     |  2 +-
 tests/dataframe_test.py                         |  2 +-
 tests/datasets/api_tests.py                     |  2 +-
 tests/datasource_tests.py                       |  5 +----
 tests/db_engine_specs/athena_tests.py           |  4 ++--
 tests/db_engine_specs/base_engine_spec_tests.py |  4 ++--
 tests/db_engine_specs/base_tests.py             |  2 +-
 tests/db_engine_specs/bigquery_tests.py         |  4 ++--
 tests/db_engine_specs/clickhouse_tests.py       |  4 ++--
 tests/db_engine_specs/drill_tests.py            |  4 ++--
 tests/db_engine_specs/druid_tests.py            |  4 ++--
 tests/db_engine_specs/elasticsearch_tests.py    |  4 ++--
 tests/db_engine_specs/hive_tests.py             |  4 ++--
 tests/db_engine_specs/impala_tests.py           |  4 ++--
 tests/db_engine_specs/kylin_tests.py            |  4 ++--
 tests/db_engine_specs/mssql_tests.py            |  4 ++--
 tests/db_engine_specs/mysql_tests.py            |  6 +++---
 tests/db_engine_specs/oracle_tests.py           |  4 ++--
 tests/db_engine_specs/pinot_tests.py            |  4 ++--
 tests/db_engine_specs/postgres_tests.py         |  4 ++--
 tests/db_engine_specs/presto_tests.py           |  8 +++-----
 tests/db_engine_specs/snowflake_tests.py        |  4 ++--
 tests/db_engine_specs/sqlite_tests.py           |  4 ++--
 tests/dict_import_export_tests.py               |  5 +----
 tests/druid_func_tests.py                       |  2 +-
 tests/druid_func_tests_sip38.py                 |  2 +-
 tests/druid_tests.py                            |  2 +-
 tests/email_tests.py                            |  2 +-
 tests/feature_flag_tests.py                     |  2 +-
 tests/form_tests.py                             |  2 +-
 tests/import_export_tests.py                    |  2 +-
 tests/jinja_context_tests.py                    |  2 +-
 tests/load_examples_test.py                     |  6 +-----
 tests/log_api_tests.py                          |  2 +-
 tests/migration_tests.py                        |  2 +-
 tests/model_tests.py                            |  4 ++--
 tests/pandas_postprocessing_tests.py            |  2 +-
 tests/queries/api_tests.py                      |  2 +-
 tests/query_context_tests.py                    |  2 +-
 tests/result_set_tests.py                       |  2 +-
 tests/schedules_test.py                         | 10 +++++-----
 tests/security/analytics_db_safety_tests.py     |  2 +-
 tests/security_tests.py                         |  6 +++---
 tests/sql_parse_tests.py                        |  2 +-
 tests/sql_validator_tests.py                    |  6 +++---
 tests/sqla_models_tests.py                      |  2 +-
 tests/sqllab_tests.py                           |  5 +----
 tests/stats_logger_tests.py                     |  2 +-
 tests/strategy_tests.py                         |  5 +----
 tests/tagging_tests.py                          |  2 +-
 tests/thumbnails_tests.py                       |  4 ++--
 tests/utils_tests.py                            |  2 +-
 tests/viz_tests.py                              | 20 ++++++++++----------
 tox.ini                                         |  6 ++++--
 71 files changed, 123 insertions(+), 166 deletions(-)

diff --git a/scripts/python_tests.sh b/pytest.ini
old mode 100755
new mode 100644
similarity index 73%
copy from scripts/python_tests.sh
copy to pytest.ini
index 33768af..418efb2
--- a/scripts/python_tests.sh
+++ b/pytest.ini
@@ -1,5 +1,3 @@
-#!/usr/bin/env bash
-
 #
 # Licensed to the Apache Software Foundation (ASF) under one or more
 # contributor license agreements.  See the NOTICE file distributed with
@@ -16,12 +14,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
-set -e
-
-export SUPERSET_CONFIG=${SUPERSET_CONFIG:-tests.superset_test_config}
-echo "Superset config module: $SUPERSET_CONFIG"
-
-superset db upgrade
-superset init
-nosetests --stop tests/load_examples_test.py
-nosetests --stop --exclude=load_examples_test tests
+[pytest]
+addopts = -ra -q
+testpaths =
+    tests
+python_files = *_test.py test_*.py *_tests.py
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 3687aff..399f9b7 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -21,7 +21,8 @@ flask-testing==0.8.0
 ipdb==0.12
 isort==4.3.21
 mypy==0.770
-nose==1.3.7
+pytest==5.4.3
+pytest-cov==2.10.0
 parameterized==0.7.4
 pip-tools==5.1.2
 pre-commit==1.17.0
diff --git a/scripts/python_tests.sh b/scripts/python_tests.sh
index 33768af..f0309f2 100755
--- a/scripts/python_tests.sh
+++ b/scripts/python_tests.sh
@@ -23,5 +23,5 @@ echo "Superset config module: $SUPERSET_CONFIG"
 
 superset db upgrade
 superset init
-nosetests --stop tests/load_examples_test.py
-nosetests --stop --exclude=load_examples_test tests
+pytest --maxfail=1 tests/load_examples_test.py
+pytest --maxfail=1 --cov=superset --ignore=load_examples_test tests/*
diff --git a/scripts/tests/run.sh b/scripts/tests/run.sh
index 5e95663..aeffeb0 100755
--- a/scripts/tests/run.sh
+++ b/scripts/tests/run.sh
@@ -56,7 +56,7 @@ function test_init() {
   echo --------------------
   echo Load examples
   echo --------------------
-  nosetests tests/load_examples_test.py
+  pytest -s tests/load_examples_test.py
 }
 
 
@@ -145,5 +145,5 @@ fi
 
 if [ $RUN_TESTS -eq 1 ]
 then
-  nosetests --exclude=load_examples_test "${TEST_MODULE}"
+  pytest -s --ignore=load_examples_test "${TEST_MODULE}"
 fi
diff --git a/setup.cfg b/setup.cfg
index e7eedf7..8c969fa 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -33,13 +33,6 @@ all_files = 1
 [upload_sphinx]
 upload-dir = docs/_build/html
 
-[nosetests]
-verbosity = 3
-detailed-errors = 1
-with-coverage = 1
-nocapture = 1
-cover-package = superset
-
 [isort]
 combine_as_imports = true
 include_trailing_comma = true
diff --git a/tests/access_tests.py b/tests/access_tests.py
index 0af7415..d452d13 100644
--- a/tests/access_tests.py
+++ b/tests/access_tests.py
@@ -94,10 +94,12 @@ def create_access_request(session, ds_type, ds_name, 
role_name, user_name):
     return access_request
 
 
-class RequestAccessTests(SupersetTestCase):
+class TestRequestAccess(SupersetTestCase):
     @classmethod
     def setUpClass(cls):
         with app.app_context():
+            cls.create_druid_test_objects()
+
             security_manager.add_role("override_me")
             security_manager.add_role(TEST_ROLE_1)
             security_manager.add_role(TEST_ROLE_2)
diff --git a/tests/base_api_tests.py b/tests/base_api_tests.py
index 112211a..e1f6e48 100644
--- a/tests/base_api_tests.py
+++ b/tests/base_api_tests.py
@@ -48,7 +48,7 @@ class Model1Api(BaseSupersetModelRestApi):
 appbuilder.add_api(Model1Api)
 
 
-class BaseModelRestApiTests(SupersetTestCase):
+class TestBaseModelRestApi(SupersetTestCase):
     def test_default_missing_declaration_get(self):
         """
             API: Test default missing declaration on get
diff --git a/tests/base_tests.py b/tests/base_tests.py
index 28895fe..871480b 100644
--- a/tests/base_tests.py
+++ b/tests/base_tests.py
@@ -52,9 +52,7 @@ class SupersetTestCase(TestCase):
         "postgresql": "public",
     }
 
-    def __init__(self, *args, **kwargs):
-        super(SupersetTestCase, self).__init__(*args, **kwargs)
-        self.maxDiff = None
+    maxDiff = -1
 
     def create_app(self):
         return app
diff --git a/tests/cache_tests.py b/tests/cache_tests.py
index 3a889fa..4f6581c 100644
--- a/tests/cache_tests.py
+++ b/tests/cache_tests.py
@@ -23,10 +23,7 @@ from superset.utils.core import QueryStatus
 from .base_tests import SupersetTestCase
 
 
-class CacheTests(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super(CacheTests, self).__init__(*args, **kwargs)
-
+class TestCache(SupersetTestCase):
     def setUp(self):
         cache.clear()
 
diff --git a/tests/celery_tests.py b/tests/celery_tests.py
index e30d780..af20de6 100644
--- a/tests/celery_tests.py
+++ b/tests/celery_tests.py
@@ -44,7 +44,7 @@ CELERY_SLEEP_TIME = 10
 DROP_TABLE_SLEEP_TIME = 10
 
 
-class UtilityFunctionTests(SupersetTestCase):
+class TestUtilityFunction(SupersetTestCase):
     # TODO(bkyryliuk): support more cases in CTA function.
     def test_create_table_as(self):
         q = ParsedQuery("SELECT * FROM outer_space;")
@@ -75,7 +75,7 @@ class UtilityFunctionTests(SupersetTestCase):
         )
 
 
-class AppContextTests(SupersetTestCase):
+class TestAppContext(SupersetTestCase):
     def test_in_app_context(self):
         @celery_app.task()
         def my_task():
@@ -95,7 +95,7 @@ class AppContextTests(SupersetTestCase):
 CTAS_SCHEMA_NAME = "sqllab_test_db"
 
 
-class CeleryTestCase(SupersetTestCase):
+class TestCelery(SupersetTestCase):
     def get_query_by_name(self, sql):
         session = db.session
         query = session.query(Query).filter_by(sql=sql).first()
diff --git a/tests/charts/api_tests.py b/tests/charts/api_tests.py
index 2723bcd..24aa1e8 100644
--- a/tests/charts/api_tests.py
+++ b/tests/charts/api_tests.py
@@ -36,12 +36,9 @@ from tests.fixtures.query_context import get_query_context
 CHART_DATA_URI = "api/v1/chart/data"
 
 
-class ChartApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
+class TestChartApi(SupersetTestCase, ApiOwnersTestCaseMixin):
     resource_name = "chart"
 
-    def __init__(self, *args, **kwargs):
-        super(ChartApiTests, self).__init__(*args, **kwargs)
-
     def insert_chart(
         self,
         slice_name: str,
diff --git a/tests/charts/schema_tests.py b/tests/charts/schema_tests.py
index fc51d02..4c998fc 100644
--- a/tests/charts/schema_tests.py
+++ b/tests/charts/schema_tests.py
@@ -29,7 +29,7 @@ def load_query_context(payload: Dict[str, Any]) -> 
Tuple[QueryContext, Dict[str,
     return ChartDataQueryContextSchema().load(payload)
 
 
-class SchemaTestCase(SupersetTestCase):
+class TestSchema(SupersetTestCase):
     def test_query_context_limit_and_offset(self):
         self.login(username="admin")
         table_name = "birth_names"
diff --git a/tests/config_tests.py b/tests/config_tests.py
index 851bb6b..1c661b5 100644
--- a/tests/config_tests.py
+++ b/tests/config_tests.py
@@ -71,10 +71,7 @@ def apply_dttm_defaults(table: SqlaTable, dttm_defaults: 
Dict[str, Any]):
             dbcol.expression = dttm_column_defaults["expression"]
 
 
-class ConfigTests(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super(ConfigTests, self).__init__(*args, **kwargs)
-
+class TestConfig(SupersetTestCase):
     def setUp(self) -> None:
         self.login(username="admin")
         self._test_db_id = get_or_create_db(
diff --git a/tests/core_tests.py b/tests/core_tests.py
index fde253e..e67a846 100644
--- a/tests/core_tests.py
+++ b/tests/core_tests.py
@@ -67,10 +67,7 @@ from .base_tests import SupersetTestCase
 logger = logging.getLogger(__name__)
 
 
-class CoreTests(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super(CoreTests, self).__init__(*args, **kwargs)
-
+class TestCore(SupersetTestCase):
     def setUp(self):
         db.session.query(Query).delete()
         db.session.query(DatasourceAccessRequest).delete()
diff --git a/tests/dashboard_tests.py b/tests/dashboard_tests.py
index 3afbbe4..50db6d0 100644
--- a/tests/dashboard_tests.py
+++ b/tests/dashboard_tests.py
@@ -35,7 +35,7 @@ from superset.views import core as views
 from .base_tests import SupersetTestCase
 
 
-class DashboardTests(SupersetTestCase):
+class TestDashboard(SupersetTestCase):
     def get_mock_positions(self, dash):
         positions = {"DASHBOARD_VERSION_KEY": "v2"}
         for i, slc in enumerate(dash.slices):
diff --git a/tests/dashboards/api_tests.py b/tests/dashboards/api_tests.py
index 23cdd88..145706c 100644
--- a/tests/dashboards/api_tests.py
+++ b/tests/dashboards/api_tests.py
@@ -32,7 +32,7 @@ from tests.base_api_tests import ApiOwnersTestCaseMixin
 from tests.base_tests import SupersetTestCase
 
 
-class DashboardApiTests(SupersetTestCase, ApiOwnersTestCaseMixin):
+class TestDashboardApi(SupersetTestCase, ApiOwnersTestCaseMixin):
     resource_name = "dashboard"
 
     dashboard_data = {
@@ -44,9 +44,6 @@ class DashboardApiTests(SupersetTestCase, 
ApiOwnersTestCaseMixin):
         "published": False,
     }
 
-    def __init__(self, *args, **kwargs):
-        super(DashboardApiTests, self).__init__(*args, **kwargs)
-
     def insert_dashboard(
         self,
         dashboard_title: str,
diff --git a/tests/dashboards/dao_tests.py b/tests/dashboards/dao_tests.py
index 8d3c51c..6bb22b8 100644
--- a/tests/dashboards/dao_tests.py
+++ b/tests/dashboards/dao_tests.py
@@ -25,7 +25,7 @@ from superset.models.dashboard import Dashboard
 from tests.base_tests import SupersetTestCase
 
 
-class DashboardDAOTests(SupersetTestCase):
+class TestDashboardDAO(SupersetTestCase):
     def test_set_dash_metadata(self):
         dash = 
db.session.query(Dashboard).filter_by(slug="world_health").first()
         data = dash.data
diff --git a/tests/database_api_tests.py b/tests/database_api_tests.py
index d0e9ecf..2cb2d43 100644
--- a/tests/database_api_tests.py
+++ b/tests/database_api_tests.py
@@ -30,7 +30,7 @@ from superset.utils.core import get_example_database
 from .base_tests import SupersetTestCase
 
 
-class DatabaseApiTests(SupersetTestCase):
+class TestDatabaseApi(SupersetTestCase):
     def test_get_items(self):
         """
             Database API: Test get items
diff --git a/tests/dataframe_test.py b/tests/dataframe_test.py
index fdb0207..a6dbbac 100644
--- a/tests/dataframe_test.py
+++ b/tests/dataframe_test.py
@@ -26,7 +26,7 @@ from superset.result_set import SupersetResultSet
 from .base_tests import SupersetTestCase
 
 
-class SupersetDataFrameTestCase(SupersetTestCase):
+class TestSupersetDataFrame(SupersetTestCase):
     def test_df_to_records(self):
         data = [("a1", "b1", "c1"), ("a2", "b2", "c2")]
         cursor_descr = (("a", "string"), ("b", "string"), ("c", "string"))
diff --git a/tests/datasets/api_tests.py b/tests/datasets/api_tests.py
index 184b784..e1d642f 100644
--- a/tests/datasets/api_tests.py
+++ b/tests/datasets/api_tests.py
@@ -38,7 +38,7 @@ from superset.views.base import generate_download_headers
 from tests.base_tests import SupersetTestCase
 
 
-class DatasetApiTests(SupersetTestCase):
+class TestDatasetApi(SupersetTestCase):
     @staticmethod
     def insert_dataset(
         table_name: str, schema: str, owners: List[int], database: Database
diff --git a/tests/datasource_tests.py b/tests/datasource_tests.py
index 9015e6d..8733059 100644
--- a/tests/datasource_tests.py
+++ b/tests/datasource_tests.py
@@ -24,10 +24,7 @@ from .base_tests import SupersetTestCase
 from .fixtures.datasource import datasource_post
 
 
-class DatasourceTests(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super(DatasourceTests, self).__init__(*args, **kwargs)
-
+class TestDatasource(SupersetTestCase):
     def test_external_metadata(self):
         self.login(username="admin")
         tbl = self.get_table_by_name("birth_names")
diff --git a/tests/db_engine_specs/athena_tests.py 
b/tests/db_engine_specs/athena_tests.py
index b59f500..92160db 100644
--- a/tests/db_engine_specs/athena_tests.py
+++ b/tests/db_engine_specs/athena_tests.py
@@ -17,10 +17,10 @@
 from tests.test_app import app  # isort:skip
 
 from superset.db_engine_specs.athena import AthenaEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class AthenaTestCase(DbEngineSpecTestCase):
+class TestAthenaDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/base_engine_spec_tests.py 
b/tests/db_engine_specs/base_engine_spec_tests.py
index 1d68e98..f4fc64b 100644
--- a/tests/db_engine_specs/base_engine_spec_tests.py
+++ b/tests/db_engine_specs/base_engine_spec_tests.py
@@ -23,12 +23,12 @@ from superset.db_engine_specs import engines
 from superset.db_engine_specs.base import BaseEngineSpec, builtin_time_grains
 from superset.db_engine_specs.sqlite import SqliteEngineSpec
 from superset.utils.core import get_example_database
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 from ..fixtures.pyodbcRow import Row
 
 
-class DbEngineSpecsTests(DbEngineSpecTestCase):
+class TestDbEngineSpecs(TestDbEngineSpec):
     def test_extract_limit_from_query(self, engine_spec_class=BaseEngineSpec):
         q0 = "select * from table"
         q1 = "select * from mytable limit 10"
diff --git a/tests/db_engine_specs/base_tests.py 
b/tests/db_engine_specs/base_tests.py
index 5b08dbf..9df91f4 100644
--- a/tests/db_engine_specs/base_tests.py
+++ b/tests/db_engine_specs/base_tests.py
@@ -23,7 +23,7 @@ from tests.base_tests import SupersetTestCase
 from tests.test_app import app  # isort:skip
 
 
-class DbEngineSpecTestCase(SupersetTestCase):
+class TestDbEngineSpec(SupersetTestCase):
     def sql_limit_regex(
         self, sql, expected_sql, engine_spec_class=MySQLEngineSpec, limit=1000
     ):
diff --git a/tests/db_engine_specs/bigquery_tests.py 
b/tests/db_engine_specs/bigquery_tests.py
index 67f7747..988575d 100644
--- a/tests/db_engine_specs/bigquery_tests.py
+++ b/tests/db_engine_specs/bigquery_tests.py
@@ -22,10 +22,10 @@ from sqlalchemy import column
 
 from superset.db_engine_specs.base import BaseEngineSpec
 from superset.db_engine_specs.bigquery import BigQueryEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class BigQueryTestCase(DbEngineSpecTestCase):
+class TestBigQueryDbEngineSpec(TestDbEngineSpec):
     def test_bigquery_sqla_column_label(self):
         """
         DB Eng Specs (bigquery): Test column label
diff --git a/tests/db_engine_specs/clickhouse_tests.py 
b/tests/db_engine_specs/clickhouse_tests.py
index 5c06a39..b6416c8 100644
--- a/tests/db_engine_specs/clickhouse_tests.py
+++ b/tests/db_engine_specs/clickhouse_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.clickhouse import ClickHouseEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class ClickHouseTestCase(DbEngineSpecTestCase):
+class TestClickHouseDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/drill_tests.py 
b/tests/db_engine_specs/drill_tests.py
index 0e64f02..9897a5d 100644
--- a/tests/db_engine_specs/drill_tests.py
+++ b/tests/db_engine_specs/drill_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.drill import DrillEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class DrillTestCase(DbEngineSpecTestCase):
+class TestDrillDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/druid_tests.py 
b/tests/db_engine_specs/druid_tests.py
index 76f49e9..fb9f3f4 100644
--- a/tests/db_engine_specs/druid_tests.py
+++ b/tests/db_engine_specs/druid_tests.py
@@ -17,10 +17,10 @@
 from sqlalchemy import column
 
 from superset.db_engine_specs.druid import DruidEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class DruidTestCase(DbEngineSpecTestCase):
+class TestDruidDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/elasticsearch_tests.py 
b/tests/db_engine_specs/elasticsearch_tests.py
index 8b222a6..30fa14c 100644
--- a/tests/db_engine_specs/elasticsearch_tests.py
+++ b/tests/db_engine_specs/elasticsearch_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.elasticsearch import ElasticSearchEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class ElasticSearchTestCase(DbEngineSpecTestCase):
+class TestElasticSearchDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/hive_tests.py 
b/tests/db_engine_specs/hive_tests.py
index 1ac6ddc..83b23e9 100644
--- a/tests/db_engine_specs/hive_tests.py
+++ b/tests/db_engine_specs/hive_tests.py
@@ -19,10 +19,10 @@ from unittest import mock
 from superset.db_engine_specs.hive import HiveEngineSpec
 from superset.exceptions import SupersetException
 from superset.sql_parse import Table
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class HiveTests(DbEngineSpecTestCase):
+class TestHiveDbEngineSpec(TestDbEngineSpec):
     def test_0_progress(self):
         log = """
             17/02/07 18:26:27 INFO log.PerfLogger: <PERFLOG method=compile 
from=org.apache.hadoop.hive.ql.Driver>
diff --git a/tests/db_engine_specs/impala_tests.py 
b/tests/db_engine_specs/impala_tests.py
index c0de4f2..8d2e403 100644
--- a/tests/db_engine_specs/impala_tests.py
+++ b/tests/db_engine_specs/impala_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.impala import ImpalaEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class ImpalaTestCase(DbEngineSpecTestCase):
+class TestImpalaDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/kylin_tests.py 
b/tests/db_engine_specs/kylin_tests.py
index 2301e30..8e6c020 100644
--- a/tests/db_engine_specs/kylin_tests.py
+++ b/tests/db_engine_specs/kylin_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.kylin import KylinEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class KylinTestCase(DbEngineSpecTestCase):
+class TestKylinDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/mssql_tests.py 
b/tests/db_engine_specs/mssql_tests.py
index 0a254de..149ed69 100644
--- a/tests/db_engine_specs/mssql_tests.py
+++ b/tests/db_engine_specs/mssql_tests.py
@@ -24,10 +24,10 @@ from sqlalchemy.types import String, UnicodeText
 
 from superset.db_engine_specs.base import BaseEngineSpec
 from superset.db_engine_specs.mssql import MssqlEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class MssqlEngineSpecTest(DbEngineSpecTestCase):
+class TestMssqlEngineSpec(TestDbEngineSpec):
     def test_mssql_column_types(self):
         def assert_type(type_string, type_expected):
             type_assigned = MssqlEngineSpec.get_sqla_column_type(type_string)
diff --git a/tests/db_engine_specs/mysql_tests.py 
b/tests/db_engine_specs/mysql_tests.py
index 897507d..f284f88 100644
--- a/tests/db_engine_specs/mysql_tests.py
+++ b/tests/db_engine_specs/mysql_tests.py
@@ -20,12 +20,12 @@ from sqlalchemy.dialects import mysql
 from sqlalchemy.dialects.mysql import DATE, NVARCHAR, TEXT, VARCHAR
 
 from superset.db_engine_specs.mysql import MySQLEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class MySQLEngineSpecsTestCase(DbEngineSpecTestCase):
+class TestMySQLEngineSpecsDbEngineSpec(TestDbEngineSpec):
     @unittest.skipUnless(
-        DbEngineSpecTestCase.is_module_installed("MySQLdb"), "mysqlclient not 
installed"
+        TestDbEngineSpec.is_module_installed("MySQLdb"), "mysqlclient not 
installed"
     )
     def test_get_datatype_mysql(self):
         """Tests related to datatype mapping for MySQL"""
diff --git a/tests/db_engine_specs/oracle_tests.py 
b/tests/db_engine_specs/oracle_tests.py
index 8b821c7..1aa375d 100644
--- a/tests/db_engine_specs/oracle_tests.py
+++ b/tests/db_engine_specs/oracle_tests.py
@@ -19,10 +19,10 @@ from sqlalchemy.dialects import oracle
 from sqlalchemy.dialects.oracle import DATE, NVARCHAR, VARCHAR
 
 from superset.db_engine_specs.oracle import OracleEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class OracleTestCase(DbEngineSpecTestCase):
+class TestOracleDbEngineSpec(TestDbEngineSpec):
     def test_oracle_sqla_column_name_length_exceeded(self):
         col = column("This_Is_32_Character_Column_Name")
         label = OracleEngineSpec.make_label_compatible(col.name)
diff --git a/tests/db_engine_specs/pinot_tests.py 
b/tests/db_engine_specs/pinot_tests.py
index 405ac9b..9732827 100644
--- a/tests/db_engine_specs/pinot_tests.py
+++ b/tests/db_engine_specs/pinot_tests.py
@@ -17,10 +17,10 @@
 from sqlalchemy import column
 
 from superset.db_engine_specs.pinot import PinotEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class PinotTestCase(DbEngineSpecTestCase):
+class TestPinotDbEngineSpec(TestDbEngineSpec):
     """ Tests pertaining to our Pinot database support """
 
     def test_pinot_time_expression_sec_one_1m_grain(self):
diff --git a/tests/db_engine_specs/postgres_tests.py 
b/tests/db_engine_specs/postgres_tests.py
index 098e918..139b339 100644
--- a/tests/db_engine_specs/postgres_tests.py
+++ b/tests/db_engine_specs/postgres_tests.py
@@ -20,10 +20,10 @@ from sqlalchemy import column, literal_column
 from sqlalchemy.dialects import postgresql
 
 from superset.db_engine_specs.postgres import PostgresEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class PostgresTests(DbEngineSpecTestCase):
+class TestPostgresDbEngineSpec(TestDbEngineSpec):
     def test_get_table_names(self):
         """
         DB Eng Specs (postgres): Test get table names
diff --git a/tests/db_engine_specs/presto_tests.py 
b/tests/db_engine_specs/presto_tests.py
index 0ca0635..b57ab01 100644
--- a/tests/db_engine_specs/presto_tests.py
+++ b/tests/db_engine_specs/presto_tests.py
@@ -21,13 +21,11 @@ from sqlalchemy.engine.result import RowProxy
 from sqlalchemy.sql import select
 
 from superset.db_engine_specs.presto import PrestoEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class PrestoTests(DbEngineSpecTestCase):
-    @skipUnless(
-        DbEngineSpecTestCase.is_module_installed("pyhive"), "pyhive not 
installed"
-    )
+class TestPrestoDbEngineSpec(TestDbEngineSpec):
+    @skipUnless(TestDbEngineSpec.is_module_installed("pyhive"), "pyhive not 
installed")
     def test_get_datatype_presto(self):
         self.assertEqual("STRING", PrestoEngineSpec.get_datatype("string"))
 
diff --git a/tests/db_engine_specs/snowflake_tests.py 
b/tests/db_engine_specs/snowflake_tests.py
index 027e373..e8f76fe 100644
--- a/tests/db_engine_specs/snowflake_tests.py
+++ b/tests/db_engine_specs/snowflake_tests.py
@@ -18,10 +18,10 @@ import json
 
 from superset.db_engine_specs.snowflake import SnowflakeEngineSpec
 from superset.models.core import Database
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class SnowflakeTestCase(DbEngineSpecTestCase):
+class TestSnowflakeDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/db_engine_specs/sqlite_tests.py 
b/tests/db_engine_specs/sqlite_tests.py
index 71104c4..fd3001c 100644
--- a/tests/db_engine_specs/sqlite_tests.py
+++ b/tests/db_engine_specs/sqlite_tests.py
@@ -15,10 +15,10 @@
 # specific language governing permissions and limitations
 # under the License.
 from superset.db_engine_specs.sqlite import SqliteEngineSpec
-from tests.db_engine_specs.base_tests import DbEngineSpecTestCase
+from tests.db_engine_specs.base_tests import TestDbEngineSpec
 
 
-class SQliteTestCase(DbEngineSpecTestCase):
+class TestSQliteDbEngineSpec(TestDbEngineSpec):
     def test_convert_dttm(self):
         dttm = self.get_dttm()
 
diff --git a/tests/dict_import_export_tests.py 
b/tests/dict_import_export_tests.py
index 3597eac..dc0b8d8 100644
--- a/tests/dict_import_export_tests.py
+++ b/tests/dict_import_export_tests.py
@@ -40,12 +40,9 @@ NAME_PREFIX = "dict_"
 ID_PREFIX = 20000
 
 
-class DictImportExportTests(SupersetTestCase):
+class TestDictImportExport(SupersetTestCase):
     """Testing export import functionality for dashboards"""
 
-    def __init__(self, *args, **kwargs):
-        super(DictImportExportTests, self).__init__(*args, **kwargs)
-
     @classmethod
     def delete_imports(cls):
         with app.app_context():
diff --git a/tests/druid_func_tests.py b/tests/druid_func_tests.py
index 699afea..a8b1692 100644
--- a/tests/druid_func_tests.py
+++ b/tests/druid_func_tests.py
@@ -50,7 +50,7 @@ def emplace(metrics_dict, metric_name, is_postagg=False):
 
 
 # Unit tests that can be run without initializing base tests
-class DruidFuncTestCase(SupersetTestCase):
+class TestDruidFunc(SupersetTestCase):
     @unittest.skipUnless(
         SupersetTestCase.is_module_installed("pydruid"), "pydruid not 
installed"
     )
diff --git a/tests/druid_func_tests_sip38.py b/tests/druid_func_tests_sip38.py
index 058d8c1..fb2837e 100644
--- a/tests/druid_func_tests_sip38.py
+++ b/tests/druid_func_tests_sip38.py
@@ -55,7 +55,7 @@ def emplace(metrics_dict, metric_name, is_postagg=False):
     {"SIP_38_VIZ_REARCHITECTURE": True},
     clear=True,
 )
-class DruidFuncTestCase(SupersetTestCase):
+class TestDruidFunc(SupersetTestCase):
     @unittest.skipUnless(
         SupersetTestCase.is_module_installed("pydruid"), "pydruid not 
installed"
     )
diff --git a/tests/druid_tests.py b/tests/druid_tests.py
index c0d1834..648eb32 100644
--- a/tests/druid_tests.py
+++ b/tests/druid_tests.py
@@ -102,7 +102,7 @@ GB_RESULT_SET = [
 DruidCluster.get_druid_version = lambda _: "0.9.1"  # type: ignore
 
 
-class DruidTests(SupersetTestCase):
+class TestDruid(SupersetTestCase):
 
     """Testing interactions with Druid"""
 
diff --git a/tests/email_tests.py b/tests/email_tests.py
index 59af211..94337f6 100644
--- a/tests/email_tests.py
+++ b/tests/email_tests.py
@@ -34,7 +34,7 @@ send_email_test = mock.Mock()
 logger = logging.getLogger(__name__)
 
 
-class EmailSmtpTest(SupersetTestCase):
+class TestEmailSmtp(SupersetTestCase):
     def setUp(self):
         app.config["smtp_ssl"] = False
 
diff --git a/tests/feature_flag_tests.py b/tests/feature_flag_tests.py
index 8712c63..2ce9649 100644
--- a/tests/feature_flag_tests.py
+++ b/tests/feature_flag_tests.py
@@ -20,7 +20,7 @@ from superset import is_feature_enabled
 from tests.base_tests import SupersetTestCase
 
 
-class FeatureFlagTests(SupersetTestCase):
+class TestFeatureFlag(SupersetTestCase):
     @patch.dict(
         "superset.extensions.feature_flag_manager._feature_flags",
         {"FOO": True},
diff --git a/tests/form_tests.py b/tests/form_tests.py
index 2ac143d..92aea64 100644
--- a/tests/form_tests.py
+++ b/tests/form_tests.py
@@ -20,7 +20,7 @@ from superset.forms import CommaSeparatedListField, 
filter_not_empty_values
 from tests.base_tests import SupersetTestCase
 
 
-class FormTestCase(SupersetTestCase):
+class TestForm(SupersetTestCase):
     def test_comma_separated_list_field(self):
         field = CommaSeparatedListField().bind(Form(), "foo")
         field.process_formdata([u""])
diff --git a/tests/import_export_tests.py b/tests/import_export_tests.py
index b47b43b..16443af 100644
--- a/tests/import_export_tests.py
+++ b/tests/import_export_tests.py
@@ -38,7 +38,7 @@ from superset.models.slice import Slice
 from .base_tests import SupersetTestCase
 
 
-class ImportExportTests(SupersetTestCase):
+class TestImportExport(SupersetTestCase):
     """Testing export import functionality for dashboards"""
 
     @classmethod
diff --git a/tests/jinja_context_tests.py b/tests/jinja_context_tests.py
index 431d3b6..0f15b11 100644
--- a/tests/jinja_context_tests.py
+++ b/tests/jinja_context_tests.py
@@ -22,7 +22,7 @@ from superset.jinja_context import ExtraCache, filter_values
 from tests.base_tests import SupersetTestCase
 
 
-class Jinja2ContextTests(SupersetTestCase):
+class TestJinja2Context(SupersetTestCase):
     def test_filter_values_default(self) -> None:
         with app.test_request_context():
             self.assertEquals(filter_values("name", "foo"), ["foo"])
diff --git a/tests/load_examples_test.py b/tests/load_examples_test.py
index 5b61730..7fe94e9 100644
--- a/tests/load_examples_test.py
+++ b/tests/load_examples_test.py
@@ -17,11 +17,7 @@
 from .base_tests import SupersetTestCase
 
 
-class SupersetDataFrameTestCase(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-        self.examples = None
-
+class TestSupersetDataFrame(SupersetTestCase):
     def setUp(self) -> None:
         # Late importing here as we need an app context to be pushed...
         from superset import examples
diff --git a/tests/log_api_tests.py b/tests/log_api_tests.py
index dbf1084..f13d5c9 100644
--- a/tests/log_api_tests.py
+++ b/tests/log_api_tests.py
@@ -29,7 +29,7 @@ from superset.models.core import Log
 from .base_tests import SupersetTestCase
 
 
-class LogApiTests(SupersetTestCase):
+class TestLogApi(SupersetTestCase):
     def insert_log(
         self,
         action: str,
diff --git a/tests/migration_tests.py b/tests/migration_tests.py
index d809da5..444aefb 100644
--- a/tests/migration_tests.py
+++ b/tests/migration_tests.py
@@ -24,7 +24,7 @@ from superset.migrations.versions.fb13d49b72f9_better_filters 
import (
 from .base_tests import SupersetTestCase
 
 
-class MigrationTestCase(SupersetTestCase):
+class TestMigration(SupersetTestCase):
     def test_upgrade_slice(self):
         slc = Slice(
             slice_name="FOO",
diff --git a/tests/model_tests.py b/tests/model_tests.py
index 4a203a9..c8a1131 100644
--- a/tests/model_tests.py
+++ b/tests/model_tests.py
@@ -30,7 +30,7 @@ from superset.utils.core import get_example_database, 
QueryStatus
 from .base_tests import SupersetTestCase
 
 
-class DatabaseModelTestCase(SupersetTestCase):
+class TestDatabaseModel(SupersetTestCase):
     @unittest.skipUnless(
         SupersetTestCase.is_module_installed("requests"), "requests not 
installed"
     )
@@ -173,7 +173,7 @@ class DatabaseModelTestCase(SupersetTestCase):
             self.assertEqual(df.iat[0, 0], ";")
 
 
-class SqlaTableModelTestCase(SupersetTestCase):
+class TestSqlaTableModel(SupersetTestCase):
     def test_get_timestamp_expression(self):
         tbl = self.get_table_by_name("birth_names")
         ds_col = tbl.get_column("ds")
diff --git a/tests/pandas_postprocessing_tests.py 
b/tests/pandas_postprocessing_tests.py
index 14342cc..839b227 100644
--- a/tests/pandas_postprocessing_tests.py
+++ b/tests/pandas_postprocessing_tests.py
@@ -56,7 +56,7 @@ def round_floats(
     return [round(val, precision) if val else None for val in floats]
 
 
-class PostProcessingTestCase(SupersetTestCase):
+class TestPostProcessing(SupersetTestCase):
     def test_pivot(self):
         aggregates = {"idx_nulls": {"operator": "sum"}}
 
diff --git a/tests/queries/api_tests.py b/tests/queries/api_tests.py
index 5016812..bcd55c9 100644
--- a/tests/queries/api_tests.py
+++ b/tests/queries/api_tests.py
@@ -33,7 +33,7 @@ from superset.models.sql_lab import Query
 from tests.base_tests import SupersetTestCase
 
 
-class QueryApiTests(SupersetTestCase):
+class TestQueryApi(SupersetTestCase):
     def insert_query(
         self,
         database_id: int,
diff --git a/tests/query_context_tests.py b/tests/query_context_tests.py
index 310df01..eb75820 100644
--- a/tests/query_context_tests.py
+++ b/tests/query_context_tests.py
@@ -28,7 +28,7 @@ from tests.base_tests import SupersetTestCase
 from tests.fixtures.query_context import get_query_context
 
 
-class QueryContextTests(SupersetTestCase):
+class TestQueryContext(SupersetTestCase):
     def test_schema_deserialization(self):
         """
         Ensure that the deserialized QueryContext contains all required fields.
diff --git a/tests/result_set_tests.py b/tests/result_set_tests.py
index 963cd95..888b695 100644
--- a/tests/result_set_tests.py
+++ b/tests/result_set_tests.py
@@ -25,7 +25,7 @@ from superset.result_set import dedup, SupersetResultSet
 from .base_tests import SupersetTestCase
 
 
-class SupersetResultSetTestCase(SupersetTestCase):
+class TestSupersetResultSet(SupersetTestCase):
     def test_dedup(self):
         self.assertEqual(dedup(["foo", "bar"]), ["foo", "bar"])
         self.assertEqual(
diff --git a/tests/schedules_test.py b/tests/schedules_test.py
index 348ee86..a8bd592 100644
--- a/tests/schedules_test.py
+++ b/tests/schedules_test.py
@@ -42,7 +42,7 @@ from tests.base_tests import SupersetTestCase
 from .utils import read_fixture
 
 
-class SchedulesTestCase(SupersetTestCase):
+class TestSchedules(SupersetTestCase):
 
     RECIPIENTS = "recipie...@superset.com, recipie...@superset.com"
     BCC = "b...@superset.com"
@@ -379,7 +379,7 @@ class SchedulesTestCase(SupersetTestCase):
             {
                 "channels": "#test_channel",
                 "file": element.screenshot_as_png,
-                "initial_comment": "\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/1/|Explore in Superset>\n        ",
+                "initial_comment": f"\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/{schedule.slice_id}/|Explore in Superset>\n 
       ",
                 "title": "[Report]  Participants",
             },
         )
@@ -434,7 +434,7 @@ class SchedulesTestCase(SupersetTestCase):
             {
                 "channels": "#test_channel",
                 "file": element.screenshot_as_png,
-                "initial_comment": "\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/1/|Explore in Superset>\n        ",
+                "initial_comment": f"\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/{schedule.slice_id}/|Explore in Superset>\n 
       ",
                 "title": "[Report]  Participants",
             },
         )
@@ -481,7 +481,7 @@ class SchedulesTestCase(SupersetTestCase):
             {
                 "channels": "#test_channel",
                 "file": self.CSV,
-                "initial_comment": "\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/1/|Explore in Superset>\n        ",
+                "initial_comment": f"\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/{schedule.slice_id}/|Explore in Superset>\n 
       ",
                 "title": "[Report]  Participants",
             },
         )
@@ -526,7 +526,7 @@ class SchedulesTestCase(SupersetTestCase):
             {
                 "channels": "#test_channel",
                 "file": self.CSV,
-                "initial_comment": "\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/1/|Explore in Superset>\n        ",
+                "initial_comment": f"\n        *Participants*\n\n        
<http://0.0.0.0:8080/superset/slice/{schedule.slice_id}/|Explore in Superset>\n 
       ",
                 "title": "[Report]  Participants",
             },
         )
diff --git a/tests/security/analytics_db_safety_tests.py 
b/tests/security/analytics_db_safety_tests.py
index 5d32646..9423208 100644
--- a/tests/security/analytics_db_safety_tests.py
+++ b/tests/security/analytics_db_safety_tests.py
@@ -22,7 +22,7 @@ from superset.security.analytics_db_safety import (
 from tests.base_tests import SupersetTestCase
 
 
-class DBConnectionsTest(SupersetTestCase):
+class TestDBConnections(SupersetTestCase):
     def test_check_sqlalchemy_uri_ok(self):
         check_sqlalchemy_uri("postgres://user:passw...@test.com")
 
diff --git a/tests/security_tests.py b/tests/security_tests.py
index b427982..7568cd6 100644
--- a/tests/security_tests.py
+++ b/tests/security_tests.py
@@ -65,7 +65,7 @@ def delete_schema_perm(view_menu_name: str) -> None:
     return None
 
 
-class RolePermissionTests(SupersetTestCase):
+class TestRolePermission(SupersetTestCase):
     """Testing export role permissions."""
 
     def setUp(self):
@@ -818,7 +818,7 @@ class RolePermissionTests(SupersetTestCase):
             raise Exception(f"Some views are not secured:\n{view_str}")
 
 
-class SecurityManagerTests(SupersetTestCase):
+class TestSecurityManager(SupersetTestCase):
     """
     Testing the Security Manager.
     """
@@ -930,7 +930,7 @@ class SecurityManagerTests(SupersetTestCase):
             security_manager.raise_for_access(viz=test_viz)
 
 
-class RowLevelSecurityTests(SupersetTestCase):
+class TestRowLevelSecurity(SupersetTestCase):
     """
     Testing Row Level Security
     """
diff --git a/tests/sql_parse_tests.py b/tests/sql_parse_tests.py
index e09f4f1..5d2fc4d 100644
--- a/tests/sql_parse_tests.py
+++ b/tests/sql_parse_tests.py
@@ -19,7 +19,7 @@ import unittest
 from superset.sql_parse import ParsedQuery, Table
 
 
-class SupersetTestCase(unittest.TestCase):
+class TestSupersetSqlParse(unittest.TestCase):
     def extract_tables(self, query):
         return ParsedQuery(query).tables
 
diff --git a/tests/sql_validator_tests.py b/tests/sql_validator_tests.py
index 4cf2956..4f47233 100644
--- a/tests/sql_validator_tests.py
+++ b/tests/sql_validator_tests.py
@@ -42,7 +42,7 @@ PRESTO_TEST_FEATURE_FLAGS = {
 }
 
 
-class SqlValidatorEndpointTests(SupersetTestCase):
+class TestSqlValidatorEndpoint(SupersetTestCase):
     """Testing for Sql Lab querytext validation endpoint"""
 
     def tearDown(self):
@@ -114,7 +114,7 @@ class SqlValidatorEndpointTests(SupersetTestCase):
         self.assertIn("Kaboom!", resp["error"])
 
 
-class BaseValidatorTests(SupersetTestCase):
+class TestBaseValidator(SupersetTestCase):
     """Testing for the base sql validator"""
 
     def setUp(self):
@@ -125,7 +125,7 @@ class BaseValidatorTests(SupersetTestCase):
             self.validator.validate(None, None, None)
 
 
-class PrestoValidatorTests(SupersetTestCase):
+class TestPrestoValidator(SupersetTestCase):
     """Testing for the prestodb sql validator"""
 
     def setUp(self):
diff --git a/tests/sqla_models_tests.py b/tests/sqla_models_tests.py
index aa2daf9..4222cdb 100644
--- a/tests/sqla_models_tests.py
+++ b/tests/sqla_models_tests.py
@@ -27,7 +27,7 @@ from superset.utils.core import DbColumnType, 
get_example_database, FilterOperat
 from .base_tests import SupersetTestCase
 
 
-class DatabaseModelTestCase(SupersetTestCase):
+class TestDatabaseModel(SupersetTestCase):
     def test_is_time_druid_time_col(self):
         """Druid has a special __time column"""
 
diff --git a/tests/sqllab_tests.py b/tests/sqllab_tests.py
index 426649a..a43a4b1 100644
--- a/tests/sqllab_tests.py
+++ b/tests/sqllab_tests.py
@@ -40,12 +40,9 @@ QUERY_2 = "SELECT * FROM NO_TABLE"
 QUERY_3 = "SELECT * FROM birth_names LIMIT 10"
 
 
-class SqlLabTests(SupersetTestCase):
+class TestSqlLab(SupersetTestCase):
     """Testings for Sql Lab"""
 
-    def __init__(self, *args, **kwargs):
-        super(SqlLabTests, self).__init__(*args, **kwargs)
-
     def run_some_queries(self):
         db.session.query(Query).delete()
         db.session.commit()
diff --git a/tests/stats_logger_tests.py b/tests/stats_logger_tests.py
index f76befb..e18f60d 100644
--- a/tests/stats_logger_tests.py
+++ b/tests/stats_logger_tests.py
@@ -21,7 +21,7 @@ from unittest.mock import Mock, patch
 from superset.stats_logger import StatsdStatsLogger
 
 
-class StatsdStatsLoggerTest(TestCase):
+class TestStatsdStatsLogger(TestCase):
     def verify_client_calls(self, logger, client):
         logger.incr("foo1")
         client.incr.assert_called_once()
diff --git a/tests/strategy_tests.py b/tests/strategy_tests.py
index 08d25b2..c4f0019 100644
--- a/tests/strategy_tests.py
+++ b/tests/strategy_tests.py
@@ -50,10 +50,7 @@ mock_positions = {
 }
 
 
-class CacheWarmUpTests(SupersetTestCase):
-    def __init__(self, *args, **kwargs):
-        super(CacheWarmUpTests, self).__init__(*args, **kwargs)
-
+class TestCacheWarmUp(SupersetTestCase):
     def test_get_form_data_chart_only(self):
         chart_id = 1
         result = get_form_data(chart_id, None)
diff --git a/tests/tagging_tests.py b/tests/tagging_tests.py
index 70785c6..77c80d7 100644
--- a/tests/tagging_tests.py
+++ b/tests/tagging_tests.py
@@ -21,7 +21,7 @@ from superset import is_feature_enabled
 from tests.base_tests import SupersetTestCase
 
 
-class TaggingTests(SupersetTestCase):
+class TestTagging(SupersetTestCase):
     @skipUnless(
         (is_feature_enabled("TAGGING_SYSTEM") == False),
         "skipping as tagging endpoints are not enabled",
diff --git a/tests/thumbnails_tests.py b/tests/thumbnails_tests.py
index a780386..39f98af 100644
--- a/tests/thumbnails_tests.py
+++ b/tests/thumbnails_tests.py
@@ -38,7 +38,7 @@ from tests.test_app import app
 from .base_tests import SupersetTestCase
 
 
-class ThumbnailsSeleniumLive(LiveServerTestCase):
+class TestThumbnailsSeleniumLive(LiveServerTestCase):
     def create_app(self):
         return app
 
@@ -66,7 +66,7 @@ class ThumbnailsSeleniumLive(LiveServerTestCase):
             self.assertEqual(response.getcode(), 202)
 
 
-class ThumbnailsTests(SupersetTestCase):
+class TestThumbnails(SupersetTestCase):
 
     mock_image = b"bytes mock image"
 
diff --git a/tests/utils_tests.py b/tests/utils_tests.py
index 709d111..28f73c8 100644
--- a/tests/utils_tests.py
+++ b/tests/utils_tests.py
@@ -108,7 +108,7 @@ def mock_to_adhoc(filt, expressionType="SIMPLE", 
clause="where"):
     return result
 
 
-class UtilsTestCase(SupersetTestCase):
+class TestUtils(SupersetTestCase):
     def test_json_int_dttm_ser(self):
         dttm = datetime(2020, 1, 1)
         ts = 1577836800000.0
diff --git a/tests/viz_tests.py b/tests/viz_tests.py
index 0a8a41b..8290fbf 100644
--- a/tests/viz_tests.py
+++ b/tests/viz_tests.py
@@ -37,7 +37,7 @@ from .utils import load_fixture
 logger = logging.getLogger(__name__)
 
 
-class BaseVizTestCase(SupersetTestCase):
+class TestBaseViz(SupersetTestCase):
     def test_constructor_exception_no_datasource(self):
         form_data = {}
         datasource = None
@@ -166,7 +166,7 @@ class BaseVizTestCase(SupersetTestCase):
         self.assertEqual(app.config["CACHE_DEFAULT_TIMEOUT"], 
test_viz.cache_timeout)
 
 
-class TableVizTestCase(SupersetTestCase):
+class TestTableViz(SupersetTestCase):
     def test_get_data_applies_percentage(self):
         form_data = {
             "groupby": ["groupA", "groupB"],
@@ -443,7 +443,7 @@ class TableVizTestCase(SupersetTestCase):
         self.assertEqual(["sum_value"], data["columns"])
 
 
-class DistBarVizTestCase(SupersetTestCase):
+class TestDistBarViz(SupersetTestCase):
     def test_groupby_nulls(self):
         form_data = {
             "metrics": ["votes"],
@@ -519,7 +519,7 @@ class DistBarVizTestCase(SupersetTestCase):
         self.assertEqual(expected, data)
 
 
-class PairedTTestTestCase(SupersetTestCase):
+class TestPairedTTest(SupersetTestCase):
     def test_get_data_transforms_dataframe(self):
         form_data = {
             "groupby": ["groupA", "groupB", "groupC"],
@@ -659,7 +659,7 @@ class PairedTTestTestCase(SupersetTestCase):
         self.assertEqual(data, expected)
 
 
-class PartitionVizTestCase(SupersetTestCase):
+class TestPartitionViz(SupersetTestCase):
     @patch("superset.viz.BaseViz.query_obj")
     def test_query_obj_time_series_option(self, super_query_obj):
         datasource = self.get_datasource_mock()
@@ -863,7 +863,7 @@ class PartitionVizTestCase(SupersetTestCase):
         self.assertEqual(7, len(test_viz.nest_values.mock_calls))
 
 
-class RoseVisTestCase(SupersetTestCase):
+class TestRoseVis(SupersetTestCase):
     def test_rose_vis_get_data(self):
         raw = {}
         t1 = pd.Timestamp("2000")
@@ -899,7 +899,7 @@ class RoseVisTestCase(SupersetTestCase):
         self.assertEqual(expected, res)
 
 
-class TimeSeriesTableVizTestCase(SupersetTestCase):
+class TestTimeSeriesTableViz(SupersetTestCase):
     def test_get_data_metrics(self):
         form_data = {"metrics": ["sum__A", "count"], "groupby": []}
         datasource = self.get_datasource_mock()
@@ -956,7 +956,7 @@ class TimeSeriesTableVizTestCase(SupersetTestCase):
             test_viz.query_obj()
 
 
-class BaseDeckGLVizTestCase(SupersetTestCase):
+class TestBaseDeckGLViz(SupersetTestCase):
     def test_get_metrics(self):
         form_data = load_fixture("deck_path_form_data.json")
         datasource = self.get_datasource_mock()
@@ -1133,7 +1133,7 @@ class BaseDeckGLVizTestCase(SupersetTestCase):
             assert expected_results.get(mock_key) == adhoc_filters
 
 
-class TimeSeriesVizTestCase(SupersetTestCase):
+class TestTimeSeriesViz(SupersetTestCase):
     def test_timeseries_unicode_data(self):
         datasource = self.get_datasource_mock()
         form_data = {"groupby": ["name"], "metrics": ["sum__payout"]}
@@ -1258,7 +1258,7 @@ class TimeSeriesVizTestCase(SupersetTestCase):
         )
 
 
-class BigNumberVizTestCase(SupersetTestCase):
+class TestBigNumberViz(SupersetTestCase):
     def test_get_data(self):
         datasource = self.get_datasource_mock()
         df = pd.DataFrame(
diff --git a/tox.ini b/tox.ini
index 94c86e2..9ff47a2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -18,8 +18,10 @@
 commands =
     {toxinidir}/superset/bin/superset db upgrade
     {toxinidir}/superset/bin/superset init
-    nosetests tests/load_examples_test.py
-    nosetests --exclude=load_examples_test {posargs:tests}
+    pytest -ra -q tests/load_examples_test.py
+    # use -s to be able to use break pointers.
+    # no args or tests/* can be passed as an argument to run all tests
+    pytest --ignore=load_examples_test {posargs}
 deps =
     -rrequirements.txt
     -rrequirements-dev.txt

Reply via email to