From 51996b4b18b168172cdff5c663062c8cb4dd641c Mon Sep 17 00:00:00 2001 From: Will Deng Date: Wed, 6 Dec 2023 13:32:51 -0500 Subject: [PATCH] added tests --- tests/functional/metrics/fixtures.py | 39 ++++++++++++ tests/functional/metrics/test_metrics.py | 60 +++++++++++++++++++ ..._semantic_layer_nodes_satisfy_protocols.py | 18 ++++++ 3 files changed, 117 insertions(+) diff --git a/tests/functional/metrics/fixtures.py b/tests/functional/metrics/fixtures.py index 89eeb930043..71dab05517c 100644 --- a/tests/functional/metrics/fixtures.py +++ b/tests/functional/metrics/fixtures.py @@ -626,3 +626,42 @@ meta: my_meta: 'testing' """ + +conversion_semantic_model_purchasing_yml = """ +version: 2 + +semantic_models: + - name: semantic_purchasing + model: ref('purchasing') + measures: + - name: num_orders + agg: COUNT + expr: purchased_at + - name: num_visits + agg: SUM + expr: 1 + dimensions: + - name: purchased_at + type: TIME + entities: + - name: purchase + type: primary + expr: '1' + defaults: + agg_time_dimension: purchased_at + +""" + +conversion_metric_yml = """ +version: 2 +metrics: + - name: converted_orders_over_visits + label: Number of orders converted from visits + type: conversion + type_params: + conversion_type_params: + base_measure: num_visits + conversion_measure: num_orders + entity: purchase + calculation: conversion_rate +""" diff --git a/tests/functional/metrics/test_metrics.py b/tests/functional/metrics/test_metrics.py index 3cc0ea412b7..70ebcfa35b8 100644 --- a/tests/functional/metrics/test_metrics.py +++ b/tests/functional/metrics/test_metrics.py @@ -7,6 +7,8 @@ from tests.functional.metrics.fixtures import ( + conversion_semantic_model_purchasing_yml, + conversion_metric_yml, mock_purchase_data_csv, models_people_sql, models_people_metrics_yml, @@ -339,3 +341,61 @@ def test_simple_metric( # initial run with pytest.raises(ParsingError): run_dbt(["run"]) + + +class TestConversionMetric: + @pytest.fixture(scope="class") + def models(self): + return { + "purchasing.sql": purchasing_model_sql, + "metricflow_time_spine.sql": metricflow_time_spine_sql, + "semantic_models.yml": conversion_semantic_model_purchasing_yml, + "conversion_metric.yml": conversion_metric_yml, + } + + @pytest.fixture(scope="class") + def seeds(self): + return { + "mock_purchase_data.csv": mock_purchase_data_csv, + } + + def test_conversion_metric( + self, + project, + ): + # initial parse + runner = dbtRunner() + result = runner.invoke(["parse"]) + assert result.success + assert isinstance(result.result, Manifest) + + # make sure the metric is in the manifest + manifest = get_manifest(project.project_root) + metric_ids = list(manifest.metrics.keys()) + expected_metric_ids = [ + "metric.test.converted_orders_over_visits", + ] + assert metric_ids == expected_metric_ids + assert manifest.metrics[ + "metric.test.converted_orders_over_visits" + ].type_params.conversion_type_params + assert ( + len( + manifest.metrics[ + "metric.test.converted_orders_over_visits" + ].type_params.input_measures + ) + == 2 + ) + assert ( + manifest.metrics[ + "metric.test.converted_orders_over_visits" + ].type_params.conversion_type_params.window + is None + ) + assert ( + manifest.metrics[ + "metric.test.converted_orders_over_visits" + ].type_params.conversion_type_params.entity + == "purchase" + ) diff --git a/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py b/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py index b144603409f..8a3f588d69f 100644 --- a/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py +++ b/tests/unit/test_semantic_layer_nodes_satisfy_protocols.py @@ -2,6 +2,8 @@ import copy from dbt.contracts.graph.nodes import ( + ConstantPropertyInput, + ConversionTypeParams, Metric, MetricInput, MetricInputMeasure, @@ -233,6 +235,21 @@ def complex_metric_input_measure(where_filter) -> MetricInputMeasure: ) +@pytest.fixture(scope="session") +def conversion_type_params( + simple_metric_input_measure, metric_time_window +) -> ConversionTypeParams: + return ConversionTypeParams( + base_measure=simple_metric_input_measure, + conversion_measure=simple_metric_input_measure, + entity="entity", + window=metric_time_window, + constant_properties=[ + ConstantPropertyInput(base_property="base", conversion_property="conversion") + ], + ) + + @pytest.fixture(scope="session") def complex_metric_type_params( metric_time_window, simple_metric_input, simple_metric_input_measure @@ -245,6 +262,7 @@ def complex_metric_type_params( window=metric_time_window, grain_to_date=TimeGranularity.DAY, metrics=[simple_metric_input], + conversion_type_params=conversion_type_params, )