diff --git a/tests/fns.rs b/tests/fns.rs
new file mode 100644
index 0000000000000000000000000000000000000000..15c252194abf247fe3026056d2a8337ea5e2f81d
--- /dev/null
+++ b/tests/fns.rs
@@ -0,0 +1,111 @@
+mod utils;
+use mquery::query::{
+    fns::{aggregate, label, rollup, transform},
+    Duration, Metric, Unit,
+};
+
+macro_rules! rollup_tests {
+    ($($fn_name:ident),+) => {
+        $(#[tokio::test]
+        async fn $fn_name() {
+            let query = rollup::$fn_name(Metric::new("test_metric").lookback(Duration(1, Unit::Day)));
+            utils::send_query(query).await.unwrap();
+        })+
+    };
+}
+
+macro_rules! aggr_tests {
+    ($($fn_name: tt),+) => {
+        $(#[tokio::test]
+        async fn $fn_name() {
+            let query = aggregate::$fn_name(Metric::new("test_metric"));
+            utils::send_query(query).await.unwrap();
+        })+
+    };
+}
+
+macro_rules! label_tests {
+    ($($fn_name: tt),+) => {
+        $(#[tokio::test]
+        async fn $fn_name() {
+            let query = label::$fn_name(Metric::new("metric"), &["label", "label2"]);
+            utils::send_query(query).await.unwrap();
+        })+
+    };
+}
+
+aggr_tests!(sum, min, max, avg, group, stddev, stdvar, count);
+
+#[tokio::test]
+async fn aggr_count_values() {
+    let query = aggregate::count_values("label", Metric::new("test_metric"));
+    utils::send_query(query).await.unwrap();
+}
+
+#[tokio::test]
+async fn aggr_topk() {
+    let query = aggregate::topk(10, Metric::new("test_metric"));
+    utils::send_query(query).await.unwrap();
+}
+
+#[tokio::test]
+async fn aggr_bottomk() {
+    let query = aggregate::bottomk(10, Metric::new("test_metric"));
+    utils::send_query(query).await.unwrap();
+}
+
+#[tokio::test]
+async fn aggr_quantile() {
+    let query = aggregate::quantile(0.5, Metric::new("test_metric"));
+    utils::send_query(query).await.unwrap();
+}
+
+rollup_tests!(
+    avg_over_time,
+    min_over_time,
+    max_over_time,
+    sum_over_time,
+    count_over_time,
+    stddev_over_time,
+    stdvar_over_time,
+    present_over_time,
+    last_over_time
+);
+
+#[tokio::test]
+async fn quantile_over_time() {
+    let query = rollup::quantile_over_time(
+        0.1,
+        Metric::new("test_metric").lookback(Duration(1, Unit::Day)),
+    );
+    utils::send_query(query).await.unwrap();
+}
+
+#[tokio::test]
+async fn mql_label_map() {
+    let query = label::mql_label_map(
+        Metric::new("metric"),
+        "label",
+        &["source", "destination", "source2", "destination2"],
+    );
+    utils::send_query(query).await.unwrap();
+}
+
+label_tests!(
+    mql_sort_by_label,
+    mql_sort_by_label_desc,
+    mql_sort_by_label_numeric,
+    mql_sort_by_label_numeric_desc
+);
+
+#[tokio::test]
+async fn trans_limit_offset() {
+    let query = transform::mql_limit_offset(1, 2, Metric::new("metric")).to_string();
+    utils::send_query(query).await.unwrap();
+}
+
+#[tokio::test]
+async fn trans_union() {
+    let query = transform::mql_union(&[Metric::new("metric"), Metric::new("metric2")]).to_string();
+    utils::send_query(query).await.unwrap();
+}