Repository: dbt-labs/dbt-core

Issue:
Use test materialization when executing ✨generic✨ tests
### Current Behavior
generic (aka schema) tests are currently executed using the python api directly.
https://github.com/fishtown-analytics/dbt/blob/77c10713a325d2bee91d1822951ce5d91ccc3278/core/dbt/task/test.py#L84-L85

### Desired Behavior
Schema tests should be executed and handled by the same test materialization used for data tests. The goal here is to maintain existing behavior handling results (simply interpreting number of rows returned by `count(*)` for the test)

### Things to consider
Returning results for most schema tests is straight forward, we can simply remove `count(*)` and return the results of the query fulfilling the test, the materialization will take care of the rest. In some cases, this is not straight forward for tests that are simple pass/fail and do not necessarily return results.

Example:
https://github.com/fishtown-analytics/dbt/blob/749f87397ec1e0a270b2e09bd8dbeb71862fdb81/test/integration/005_simple_seed_test/macros/schema_test.sql

We will have to create a way to interpret different types of results as part of this. 


Discussion:

Resolving patch:
diff --git a/core/dbt/compilation.py b/core/dbt/compilation.py
--- a/core/dbt/compilation.py
+++ b/core/dbt/compilation.py
@@ -12,8 +12,8 @@
 from dbt.context.providers import generate_runtime_model
 from dbt.contracts.graph.manifest import Manifest
 from dbt.contracts.graph.compiled import (
-    CompiledSchemaTestNode,
     COMPILED_TYPES,
+    CompiledSchemaTestNode,
     GraphMemberNode,
     InjectedCTE,
     ManifestNode,


Test patch:
diff --git a/core/dbt/include/global_project/macros/schema_tests/accepted_values.sql b/core/dbt/include/global_project/macros/schema_tests/accepted_values.sql
--- a/core/dbt/include/global_project/macros/schema_tests/accepted_values.sql
+++ b/core/dbt/include/global_project/macros/schema_tests/accepted_values.sql
@@ -31,7 +31,7 @@ validation_errors as (
     )
 )
 
-select count(*) as validation_errors
+select *
 from validation_errors
 
 {% endmacro %}
diff --git a/core/dbt/include/global_project/macros/schema_tests/not_null.sql b/core/dbt/include/global_project/macros/schema_tests/not_null.sql
--- a/core/dbt/include/global_project/macros/schema_tests/not_null.sql
+++ b/core/dbt/include/global_project/macros/schema_tests/not_null.sql
@@ -3,7 +3,7 @@
 
 {% set column_name = kwargs.get('column_name', kwargs.get('arg')) %}
 
-select count(*) as validation_errors
+select *
 from {{ model }}
 where {{ column_name }} is null
 
diff --git a/core/dbt/include/global_project/macros/schema_tests/relationships.sql b/core/dbt/include/global_project/macros/schema_tests/relationships.sql
--- a/core/dbt/include/global_project/macros/schema_tests/relationships.sql
+++ b/core/dbt/include/global_project/macros/schema_tests/relationships.sql
@@ -4,7 +4,7 @@
 {% set column_name = kwargs.get('column_name', kwargs.get('from')) %}
 
 
-select count(*) as validation_errors
+select *
 from (
     select {{ column_name }} as id from {{ model }}
 ) as child
diff --git a/core/dbt/include/global_project/macros/schema_tests/unique.sql b/core/dbt/include/global_project/macros/schema_tests/unique.sql
--- a/core/dbt/include/global_project/macros/schema_tests/unique.sql
+++ b/core/dbt/include/global_project/macros/schema_tests/unique.sql
@@ -3,7 +3,7 @@
 
 {% set column_name = kwargs.get('column_name', kwargs.get('arg')) %}
 
-select count(*) as validation_errors
+select *
 from (
 
     select
diff --git a/core/dbt/task/test.py b/core/dbt/task/test.py
--- a/core/dbt/task/test.py
+++ b/core/dbt/task/test.py
@@ -1,5 +1,5 @@
 import threading
-from typing import Dict, Any, Set
+from typing import Dict, Any, Set, Union
 
 from .compile import CompileRunner
 from .run import RunTask
@@ -11,15 +11,10 @@
     CompiledTestNode,
 )
 from dbt.contracts.graph.manifest import Manifest
-from dbt.contracts.graph.parsed import (
-    ParsedDataTestNode,
-    ParsedSchemaTestNode,
-)
 from dbt.contracts.results import RunResult, TestStatus
 from dbt.context.providers import generate_runtime_model
 from dbt.clients.jinja import MacroGenerator
 from dbt.exceptions import (
-    raise_compiler_error,
     InternalException,
     missing_materialization
 )
@@ -47,29 +42,12 @@ def print_start_line(self):
         description = self.describe_node()
         print_start_line(description, self.node_index, self.num_nodes)
 
-    def execute_schema_test(self, test: CompiledSchemaTestNode):
-        _, table = self.adapter.execute(
-            test.compiled_sql,
-            auto_begin=True,
-            fetch=True,
-        )
-
-        num_rows = len(table.rows)
-        if num_rows != 1:
-            num_cols = len(table.columns)
-            raise_compiler_error(
-                f"Bad test {test.test_metadata.name}: "
-                f"Returned {num_rows} rows and {num_cols} cols, but expected "
-                f"1 row and 1 column"
-            )
-        return table[0][0]
-
     def before_execute(self):
         self.print_start_line()
 
-    def execute_data_test(
+    def execute_test(
         self,
-        test: CompiledDataTestNode,
+        test: Union[CompiledDataTestNode, CompiledSchemaTestNode],
         manifest: Manifest
     ) -> int:
         context = generate_runtime_model(
@@ -79,7 +57,8 @@ def execute_data_test(
         materialization_macro = manifest.find_materialization_macro_by_name(
             self.config.project_name,
             test.get_materialization(),
-            self.adapter.type())
+            self.adapter.type()
+        )
 
         if materialization_macro is None:
             missing_materialization(test, self.adapter.type())
@@ -112,15 +91,7 @@ def execute_data_test(
         return int(table[0][0])
 
     def execute(self, test: CompiledTestNode, manifest: Manifest):
-        if isinstance(test, CompiledDataTestNode):
-            failed_rows = self.execute_data_test(test, manifest)
-        elif isinstance(test, CompiledSchemaTestNode):
-            failed_rows = self.execute_schema_test(test)
-        else:
-            raise InternalException(
-                f'Expected compiled schema test or compiled data test, got '
-                f'{type(test)}'
-            )
+        failed_rows = self.execute_test(test, manifest)
 
         severity = test.config.severity.upper()
         thread_id = threading.current_thread().name
@@ -146,10 +117,6 @@ def after_execute(self, result):
         self.print_result_line(result)
 
 
-DATA_TEST_TYPES = (CompiledDataTestNode, ParsedDataTestNode)
-SCHEMA_TEST_TYPES = (CompiledSchemaTestNode, ParsedSchemaTestNode)
-
-
 class TestSelector(ResourceTypeSelector):
     def __init__(self, graph, manifest, previous_state):
         super().__init__(
diff --git a/test/integration/004_simple_snapshot_test/macros/test_no_overlaps.sql b/test/integration/004_simple_snapshot_test/macros/test_no_overlaps.sql
--- a/test/integration/004_simple_snapshot_test/macros/test_no_overlaps.sql
+++ b/test/integration/004_simple_snapshot_test/macros/test_no_overlaps.sql
@@ -15,7 +15,7 @@
     mostly copy+pasted from dbt_utils, but I removed some parameters and added
     a query that calls get_snapshot_unique_id
 #}
-{% macro test_mutually_exclusive_ranges(model) %}
+{% test mutually_exclusive_ranges(model) %}
 
 with base as (
     select {{ get_snapshot_unique_id() }} as dbt_unique_id,
@@ -81,5 +81,5 @@ validation_errors as (
     )
 )
 
-select count(*) from validation_errors
-{% endmacro %}
+select * from validation_errors
+{% endtest %}
diff --git a/test/integration/005_simple_seed_test/macros/schema_test.sql b/test/integration/005_simple_seed_test/macros/schema_test.sql
--- a/test/integration/005_simple_seed_test/macros/schema_test.sql
+++ b/test/integration/005_simple_seed_test/macros/schema_test.sql
@@ -1,5 +1,5 @@
 
-{% macro test_column_type(model, column_name, type) %}
+{% test column_type(model, column_name, type) %}
 
     {% set cols = adapter.get_columns_in_relation(model) %}
 
@@ -8,12 +8,15 @@
         {% do col_types.update({col.name: col.data_type}) %}
     {% endfor %}
 
+    {% set validation_message = 'Got a column type of ' ~ col_types.get(column_name) ~ ', expected ' ~ type %}
+
     {% set val = 0 if col_types.get(column_name) == type else 1 %}
     {% if val == 1 and execute %}
-        {# I'm so tired of guessing what's wrong, let's just log it #}
-        {{ log('Got a column type of ' ~ col_types.get(column_name) ~ ', expected ' ~ type, info=True) }}
+        {{ log(validation_message, info=True) }}
     {% endif %}
 
-    select {{ val }} as pass_fail
+    select '{{ validation_message }}' as validation_error
+    from (select true) as nothing
+    where {{ val }} = 1
 
-{% endmacro %}
+{% endtest %}
diff --git a/test/integration/008_schema_tests_test/local_dependency/dbt_project.yml b/test/integration/008_schema_tests_test/local_dependency/dbt_project.yml
deleted file mode 100644
--- a/test/integration/008_schema_tests_test/local_dependency/dbt_project.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-name: 'local_dep'
-version: '1.0'
-config-version: 2
-
-profile: 'default'
-
-macro-paths: ["macros"]
diff --git a/test/integration/008_schema_tests_test/local_dependency/macros/equality.sql b/test/integration/008_schema_tests_test/local_dependency/macros/equality.sql
deleted file mode 100644
--- a/test/integration/008_schema_tests_test/local_dependency/macros/equality.sql
+++ /dev/null
@@ -1,82 +0,0 @@
-{# this is copy-pasted from dbt-utils, this test is no longer at its mercy #}
-{% macro except() %}
-  {{ adapter.dispatch('except', packages=['local_dep'])() }}
-{% endmacro %}
-
-{% macro default__except() %}
-
-    except
-
-{% endmacro %}
-
-{% macro bigquery__except() %}
-
-    except distinct
-
-{% endmacro %}%
-
-{% macro test_equality(model) %}
-
-{% set compare_model = kwargs.get('compare_model', kwargs.get('arg')) %}
-
-
-{#-- Prevent querying of db in parsing mode. This works because this macro does not create any new refs. #}
-{%- if not execute -%}
-    {{ return('') }}
-{% endif %}
-
--- setup
-
-{% set dest_columns = adapter.get_columns_in_relation(model) %}
-{% set dest_cols_csv = dest_columns | map(attribute='quoted') | join(', ') %}
-
-with a as (
-
-    select * from {{ model }}
-
-),
-
-b as (
-
-    select * from {{ compare_model }}
-
-),
-
-a_minus_b as (
-
-    select {{dest_cols_csv}} from a
-    {{ local_dep.except() }}
-    select {{dest_cols_csv}} from b
-
-),
-
-b_minus_a as (
-
-    select {{dest_cols_csv}} from b
-    {{ local_dep.except() }}
-    select {{dest_cols_csv}} from a
-
-),
-
-unioned as (
-
-    select * from a_minus_b
-    union all
-    select * from b_minus_a
-
-),
-
-final as (
-
-    select (select count(*) from unioned) +
-        (select abs(
-            (select count(*) from a_minus_b) -
-            (select count(*) from b_minus_a)
-            ))
-        as count
-
-)
-
-select count from final
-
-{% endmacro %}
diff --git a/test/integration/008_schema_tests_test/macros-v2/macros/tests.sql b/test/integration/008_schema_tests_test/macros-v2/macros/tests.sql
--- a/test/integration/008_schema_tests_test/macros-v2/macros/tests.sql
+++ b/test/integration/008_schema_tests_test/macros-v2/macros/tests.sql
@@ -1,21 +1,15 @@
+{% test every_value_is_blue(model, column_name) %}
 
-
-{% macro test_every_value_is_blue(model, column_name) %}
-
-    select
-        count(*)
-
+    select *
     from {{ model }}
     where {{ column_name }} != 'blue'
 
-{% endmacro %}
+{% endtest %}
 
 
-{% macro test_rejected_values(model, column_name, values) %}
-
-    select
-        count(*)
+{% test rejected_values(model, column_name, values) %}
 
+    select *
     from {{ model }}
     where {{ column_name }} in (
         {% for value in values %}
@@ -23,20 +17,19 @@
         {% endfor %}
     )
 
-{% endmacro %}
+{% endtest %}
 
 
-{% macro test_equivalent(model, value) %}
+{% test equivalent(model, value) %}
     {% set expected = 'foo-bar' %}
-    select
-    {% if value == expected %}
-        0
-    {% else %}
-        {% set msg -%}
-        got "{{ value }}", expected "{{ expected }}"
-        {%- endset %}
-        {% do log(msg, info=True) %}
-        1
+    {% set eq = 1 if value == expected else 0 %}
+    {% set validation_message -%}
+      'got "{{ value }}", expected "{{ expected }}"'
+    {%- endset %}
+    {% if eq == 0 and execute %}
+        {{ log(validation_message, info=True) }}
     {% endif %}
-    as id
-{% endmacro %}
+
+    select {{ validation_message }} as validation_error
+    where {{ eq }} = 0
+{% endtest %}
diff --git a/test/integration/008_schema_tests_test/macros-v2/malformed/tests.sql b/test/integration/008_schema_tests_test/macros-v2/malformed/tests.sql
deleted file mode 100644
--- a/test/integration/008_schema_tests_test/macros-v2/malformed/tests.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- tries to build a macro that always returns an empty set
-{% macro test_empty_aggregation(model, column_name) %}
-
-SELECT * from {{ model }} WHERE 1=0
-
-{% endmacro %}
diff --git a/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/schema.yml b/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/schema.yml
deleted file mode 100644
--- a/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/schema.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-version: 2
-
-models:
-  - name: table_copy
-    description: "A copy of the table"
-    columns:
-      - name: email
-        tests:
-          - not_null
-    # should throw a runtime error
-    tests:
-      - empty_aggregation
\ No newline at end of file
diff --git a/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/table_copy.sql b/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/table_copy.sql
deleted file mode 100644
--- a/test/integration/008_schema_tests_test/models-v2/custom-bad-test-macro/table_copy.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-
-{{
-    config(
-        materialized='table'
-    )
-}}
-
-select * from {{ this.schema }}.seed
diff --git a/test/integration/008_schema_tests_test/models-v2/custom/schema.yml b/test/integration/008_schema_tests_test/models-v2/custom/schema.yml
--- a/test/integration/008_schema_tests_test/models-v2/custom/schema.yml
+++ b/test/integration/008_schema_tests_test/models-v2/custom/schema.yml
@@ -15,6 +15,3 @@ models:
         tests:
           - every_value_is_blue
           - rejected_values: { values: ['orange', 'purple'] }
-    # passes
-    tests:
-      - local_dep.equality: { compare_model: ref('table_copy') }
diff --git a/test/integration/008_schema_tests_test/test-context-macros/custom_schema_tests.sql b/test/integration/008_schema_tests_test/test-context-macros/custom_schema_tests.sql
--- a/test/integration/008_schema_tests_test/test-context-macros/custom_schema_tests.sql
+++ b/test/integration/008_schema_tests_test/test-context-macros/custom_schema_tests.sql
@@ -1,19 +1,19 @@
-{% macro test_type_one(model) %}
+{% test type_one(model) %}
 
-    select count(*) from (
+    select * from (
 
         select * from {{ model }}
         union all
         select * from {{ ref('model_b') }}
-        
+
     ) as Foo
 
-{% endmacro %}
+{% endtest %}
 
-{% macro test_type_two(model) %}
+{% test type_two(model) %}
 
     {{ config(severity = "WARN") }}
 
-    select count(*) from {{ model }}
+    select * from {{ model }}
 
-{% endmacro %}
+{% endtest %}
diff --git a/test/integration/008_schema_tests_test/test_schema_v2_tests.py b/test/integration/008_schema_tests_test/test_schema_v2_tests.py
--- a/test/integration/008_schema_tests_test/test_schema_v2_tests.py
+++ b/test/integration/008_schema_tests_test/test_schema_v2_tests.py
@@ -126,52 +126,6 @@ def test_postgres_malformed_schema_strict_will_break_run(self):
             self.run_dbt(strict=False)
 
 
-class TestMalformedMacroTests(DBTIntegrationTest):
-
-    def setUp(self):
-        DBTIntegrationTest.setUp(self)
-        self.run_sql_file("seed.sql")
-
-    @property
-    def schema(self):
-        return "schema_tests_008"
-
-    @property
-    def models(self):
-        return "models-v2/custom-bad-test-macro"
-
-    @property
-    def project_config(self):
-        return {
-            'config-version': 2,
-            "macro-paths": ["macros-v2/malformed"],
-        }
-
-    def run_schema_validations(self):
-        args = FakeArgs()
-        test_task = TestTask(args, self.config)
-        return test_task.run()
-
-    @use_profile('postgres')
-    def test_postgres_malformed_macro_reports_error(self):
-        self.run_dbt(['deps'])
-        self.run_dbt(strict=True)
-        expected_failure = 'not_null'
-
-        test_results = self.run_schema_validations()
-
-        self.assertEqual(len(test_results), 2)
-
-        for result in test_results:
-            self.assertIn(result.status, ('error', 'fail'))
-            # Assert that error is thrown for empty schema test
-            if result.status == "error":
-                self.assertIn("Returned 0 rows", result.message)
-            # Assert that failure occurs for normal schema test
-            elif result.status == "fail":
-                self.assertIn(expected_failure, result.node.name)
-
-
 class TestHooksInTests(DBTIntegrationTest):
 
     @property
@@ -219,9 +173,6 @@ def schema(self):
     def packages_config(self):
         return {
             'packages': [
-                {
-                    "local": "./local_dependency",
-                },
                 {
                     'git': 'https://github.com/fishtown-analytics/dbt-integration-project',
                     'revision': 'dbt/0.17.0',
@@ -256,7 +207,7 @@ def test_postgres_schema_tests(self):
         self.assertEqual(len(results), 4)
 
         test_results = self.run_schema_validations()
-        self.assertEqual(len(test_results), 6)
+        self.assertEqual(len(test_results), 5)
 
         expected_failures = ['unique', 'every_value_is_blue']
 
diff --git a/test/integration/022_bigquery_test/macros/partition_metadata.sql b/test/integration/022_bigquery_test/macros/partition_metadata.sql
--- a/test/integration/022_bigquery_test/macros/partition_metadata.sql
+++ b/test/integration/022_bigquery_test/macros/partition_metadata.sql
@@ -1,22 +1,19 @@
 
-{% macro test_number_partitions(model, expected) %}
+{% test number_partitions(model, expected) %}
 
     {%- set result = get_partitions_metadata(model) %}
-    
+
     {% if result %}
         {% set partitions = result.columns['partition_id'].values() %}
     {% else %}
         {% set partitions = () %}
     {% endif %}
-        
+
     {% set actual = partitions | length %}
-    
-    {% if model and actual == expected %}
-        select 0 as success
-    {% else %}
-        -- actual: {{ actual }}
-        -- expected: {{ expected }}
-        select 1 as error
-    {% endif %}
+    {% set success = 1 if model and actual == expected else 0 %}
+
+    select 'Expected {{ expected }}, but got {{ actual }}' as validation_error
+    from (select true)
+    where {{ success }} = 0
 
-{% endmacro %}
+{% endtest %}
diff --git a/test/integration/022_bigquery_test/macros/test_creation.sql b/test/integration/022_bigquery_test/macros/test_creation.sql
--- a/test/integration/022_bigquery_test/macros/test_creation.sql
+++ b/test/integration/022_bigquery_test/macros/test_creation.sql
@@ -1,5 +1,5 @@
 
-{% macro test_was_materialized(model, name, type) %}
+{% test was_materialized(model, name, type) %}
 
     {#-- don't run this query in the parsing step #}
     {%- if model -%}
@@ -9,10 +9,10 @@
         {%- set table = {} -%}
     {%- endif -%}
 
-    {% if table and table.type == type %}
-        select 0 as success
-    {% else %}
-        select 1 as error
+    {% if table %}
+      select '{{ table.type }} does not match expected value {{ type }}'
+      from (select true)
+      where '{{ table.type }}' != '{{ type }}'
     {% endif %}
 
-{% endmacro %}
+{% endtest %}
diff --git a/test/integration/026_aliases_test/macros/expect_value.sql b/test/integration/026_aliases_test/macros/expect_value.sql
--- a/test/integration/026_aliases_test/macros/expect_value.sql
+++ b/test/integration/026_aliases_test/macros/expect_value.sql
@@ -1,10 +1,10 @@
 
 -- cross-db compatible test, similar to accepted_values
 
-{% macro test_expect_value(model, field, value) %}
+{% test expect_value(model, field, value) %}
 
-select count(*)
+select *
 from {{ model }}
 where {{ field }} != '{{ value }}'
 
-{% endmacro %}
+{% endtest %}
diff --git a/test/integration/029_docs_generate_tests/macros/dummy_test.sql b/test/integration/029_docs_generate_tests/macros/dummy_test.sql
--- a/test/integration/029_docs_generate_tests/macros/dummy_test.sql
+++ b/test/integration/029_docs_generate_tests/macros/dummy_test.sql
@@ -1,9 +1,9 @@
 
-{% macro test_nothing(model) %}
+{% test nothing(model) %}
 
 -- a silly test to make sure that table-level tests show up in the manifest
 -- without a column_name field
 select 0
 
-{% endmacro %}
+{% endtest %}
 
diff --git a/test/integration/029_docs_generate_tests/test_docs_generate.py b/test/integration/029_docs_generate_tests/test_docs_generate.py
--- a/test/integration/029_docs_generate_tests/test_docs_generate.py
+++ b/test/integration/029_docs_generate_tests/test_docs_generate.py
@@ -1364,7 +1364,7 @@ def expected_seeded_manifest(self, model_database=None, quote_model=False):
                     'unique_id': 'test.test.not_null_model_id',
                     'docs': {'show': True},
                     'compiled': True,
-                    'compiled_sql': AnyStringWith('count(*)'),
+                    'compiled_sql': AnyStringWith('where id is null'),
                     'extra_ctes_injected': True,
                     'extra_ctes': [],
                     'test_metadata': {
@@ -2140,7 +2140,7 @@ def expected_postgres_references_manifest(self, model_database=None):
                     'depends_on': {'macros': []},
                     'description': 'My custom test that I wrote that does nothing',
                     'docs': {'show': True},
-                    'macro_sql': AnyStringWith('macro test_nothing'),
+                    'macro_sql': AnyStringWith('test nothing'),
                     'original_file_path': self.dir('macros/dummy_test.sql'),
                     'path': self.dir('macros/dummy_test.sql'),
                     'package_name': 'test',
diff --git a/test/integration/041_presto_test/data/data_seed.csv b/test/integration/041_presto_test/data/data_seed.csv
deleted file mode 100644
--- a/test/integration/041_presto_test/data/data_seed.csv
+++ /dev/null
@@ -1,5 +0,0 @@
-id,dupe
-1,a
-2,a
-3,a
-4,a
diff --git a/test/integration/041_presto_test/macros/test_creation.sql b/test/integration/041_presto_test/macros/test_creation.sql
deleted file mode 100644
--- a/test/integration/041_presto_test/macros/test_creation.sql
+++ /dev/null
@@ -1,18 +0,0 @@
-
-{% macro test_was_materialized(model, name, type) %}
-
-    {#-- don't run this query in the parsing step #}
-    {%- if model -%}
-        {%- set table = adapter.get_relation(database=model.database, schema=model.schema,
-                                             identifier=model.name) -%}
-    {%- else -%}
-        {%- set table = {} -%}
-    {%- endif -%}
-
-    {% if table and table.type == type %}
-        select 0 as success
-    {% else %}
-        select 1 as error
-    {% endif %}
-
-{% endmacro %}
diff --git a/test/integration/041_presto_test/models/ephemeral_model.sql b/test/integration/041_presto_test/models/ephemeral_model.sql
deleted file mode 100644
--- a/test/integration/041_presto_test/models/ephemeral_model.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-
-{{ config(materialized = "ephemeral") }}
-
-select * from {{ ref('view_model') }}
diff --git a/test/integration/041_presto_test/models/schema.yml b/test/integration/041_presto_test/models/schema.yml
deleted file mode 100644
--- a/test/integration/041_presto_test/models/schema.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-view_model:
-    constraints:
-        not_null:
-            - id
-            - updated_at
-
-        unique:
-            - id
-            - dupe    # fails
-
-        was_materialized:
-            - {name: view_model, type: view}
-
-table_model:
-    constraints:
-        not_null:
-            - id
-
-        was_materialized:
-            - {name: table_model, type: table}
diff --git a/test/integration/041_presto_test/models/table_model.sql b/test/integration/041_presto_test/models/table_model.sql
deleted file mode 100644
--- a/test/integration/041_presto_test/models/table_model.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-
-{{ config(materialized = "table") }}
-
-select * from {{ ref('ephemeral_model') }}
diff --git a/test/integration/041_presto_test/models/view_model.sql b/test/integration/041_presto_test/models/view_model.sql
deleted file mode 100644
--- a/test/integration/041_presto_test/models/view_model.sql
+++ /dev/null
@@ -1,13 +0,0 @@
-{{
-  config(
-    materialized = "view"
-  )
-}}
-
-
-select
-    id,
-    current_date as updated_at,
-    dupe
-
-from {{ ref('data_seed') }}
diff --git a/test/integration/041_presto_test/test_simple_presto_view.py b/test/integration/041_presto_test/test_simple_presto_view.py
deleted file mode 100644
--- a/test/integration/041_presto_test/test_simple_presto_view.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from test.integration.base import DBTIntegrationTest, FakeArgs, use_profile
-import random
-import time
-
-
-class TestBasePrestoRun(DBTIntegrationTest):
-
-    @property
-    def schema(self):
-        return "presto_test_41"
-
-    @property
-    def models(self):
-        return "models"
-
-    @property
-    def project_config(self):
-        return {
-            'config-version': 2,
-            'data-paths': ['data'],
-            'macro-paths': ['macros'],
-            'seeds': {
-                'quote_columns': False,
-            },
-        }
-
-    @property
-    def profile_config(self):
-        return self.presto_profile()
-
-    def assert_nondupes_pass(self):
-        # The 'dupe' model should fail, but all others should pass
-        test_results = self.run_dbt(['test'], expect_pass=False)
-
-        for result in test_results:
-            if 'dupe' in result.node.name:
-                self.assertEqual(result.status, 'fail')
-                self.assertFalse(result.skipped)
-                self.assertTrue(int(result.message) > 0)
-
-            # assert that actual tests pass
-            else:
-                self.assertEqual(result.status, 'pass')
-                self.assertFalse(result.skipped)
-                # message = # of failing rows
-                self.assertEqual(int(result.message), 0)
-
-
-class TestSimplePrestoRun(TestBasePrestoRun):
-    def setUp(self):
-        super().setUp()
-        for conn in self.adapter.connections.in_use.values():
-            conn.transaction_open
-
-    @use_profile('presto')
-    def test__presto_simple_run(self):
-        # make sure seed works twice. Full-refresh is a no-op
-        self.run_dbt(['seed'])
-        self.run_dbt(['seed', '--full-refresh'])
-        results = self.run_dbt()
-        self.assertEqual(len(results), 2)
-        self.assert_nondupes_pass()
-
-
-class TestUnderscorePrestoRun(TestBasePrestoRun):
-    prefix = "_test{}{:04}".format(int(time.time()), random.randint(0, 9999))
-
-    @use_profile('presto')
-    def test_presto_run_twice(self):
-        self.run_dbt(['seed'])
-        results = self.run_dbt()
-        self.assertEqual(len(results), 2)
-        self.assert_nondupes_pass()
-        results = self.run_dbt()
-        self.assertEqual(len(results), 2)
-        self.assert_nondupes_pass()
diff --git a/test/integration/056_column_type_tests/macros/test_is_type.sql b/test/integration/056_column_type_tests/macros/test_is_type.sql
--- a/test/integration/056_column_type_tests/macros/test_is_type.sql
+++ b/test/integration/056_column_type_tests/macros/test_is_type.sql
@@ -35,8 +35,7 @@
     {% do return((failures | length) == 0) %}
 {% endmacro %}
 
-
-{% macro test_is_type(model, column_map) %}
+{% test is_type(model, column_map) %}
     {% if not execute %}
         {{ return(None) }}
     {% endif %}
@@ -65,5 +64,9 @@
         {% endif %}
     {% endfor %}
     {% do log('bad columns: ' ~ bad_columns, info=True) %}
-    select {{ bad_columns | length }} as pass_fail
-{% endmacro %}
+    {% for bad_column in bad_columns %}
+      select '{{ bad_column }}' as bad_column
+      {{ 'union all' if not loop.last }}
+    {% endfor %}
+      select * from (select 1 limit 0) as nothing
+{% endtest %}
diff --git a/test/integration/056_column_type_tests/test_column_types.py b/test/integration/056_column_type_tests/test_column_types.py
--- a/test/integration/056_column_type_tests/test_column_types.py
+++ b/test/integration/056_column_type_tests/test_column_types.py
@@ -1,3 +1,4 @@
+import pytest
 from test.integration.base import DBTIntegrationTest, use_profile
 
 
@@ -20,7 +21,6 @@ def models(self):
     def test_postgres_column_types(self):
         self.run_and_test()
 
-
 class TestRedshiftColumnTypes(TestColumnTypes):
     @property
     def models(self):