The C++ unit testing library Catch currently does not support parameterized tests (though it might in Catch 2.0). However, I've found that I need parameterized tests for some purpose, so I wrote a small C++17 parameterized test library.This library isn't actually specific to Catch, but it does work with it.parameterized_tests.hpp#pragma once#include <functional>#include <tuple>#include <type_traits>#include <utility>namespace test {    namespace detail {        template <typename... Ts>        struct args : std::tuple<Ts...>        {            using base_type = std::tuple<Ts...>;            using base_type::base_type;            base_type const& as_tuple() const&            {                return *this;            }            base_type& as_tuple() &            {                return *this;            }            base_type as_tuple() &&            {                return std::move(*this);            }        };        template <typename PossiblyArgs>        struct is_args : std::false_type        {        };        template <typename... Args>        struct is_args<args<Args...>> : std::true_type        {        };        template <typename... Parameters>        struct parameters : args<Parameters...>        {            using base_type = args<Parameters...>;            using base_type::base_type;            base_type const& as_args() const&            {                return *this;            }            base_type& as_args() &            {                return *this;            }            base_type as_args() &&            {                return std::move(*this);            }        };        template <typename PossiblyParams>        struct is_parameters : std::false_type        {        };        template <typename... Parameters>        struct is_parameters<parameters<Parameters...>> : std::true_type        {        };        template <typename F, typename Tuple>        void for_each_impl(F const& fn, Tuple&& tuple)        {            std::apply(                [&fn](auto&&... args) {                    int unused[] = {(std::invoke(fn, std::forward<decltype(args)>(args)), 0)...};                    (void) unused;                },                std::forward<Tuple>(tuple));        }        template <typename F, typename... Ts>        void for_each(F const& fn, parameters<Ts...> params)        {            test::detail::for_each_impl(                [&](auto&& arg) {                    using Arg = decltype(arg);                    if constexpr (is_parameters<std::decay_t<Arg>>::value) {                        test::detail::for_each(fn, std::forward<Arg>(arg));                    } else if (is_args<std::decay_t<Arg>>::value) {                        std::apply(fn, std::forward<Arg>(arg).as_tuple());                    } else {                        static_assert(is_args<std::decay_t<Arg>>::value, Internal error);                    }                },                params.as_tuple());        }        template <typename T>        auto make_parameter_list_arg(T&& arg)        {            if constexpr (is_parameters<std::decay_t<T>>::value                          || is_args<std::decay_t<T>>::value) {                return arg;            } else {                return test::args(std::forward<T>(arg));            }        }        template <typename... Ts>        auto make_parameter_list(Ts&&... args)        {            return parameters<decltype(test::detail::make_parameter_list_arg(                std::forward<Ts>(args)))...>{std::forward<Ts>(args)...};        }    }    template <typename F, typename... Args>    void parameterized_test(F const& fn, Args&&... args)    {        detail::for_each(fn, detail::make_parameter_list(std::forward<Args>(args)...));    }    template <typename... Ts>    detail::args<std::decay_t<Ts>...> args(Ts&&... args)    {        return {std::forward<Ts>(args)...};    }    template <typename... Ts>    auto parameter_list(Ts&&... args)    {        return detail::make_parameter_list(std::forward<Ts>(args)...);    }}Usage:TEST_CASE(my test case) {    auto mySharedParameters = test::parameter_list(some string parameter, some other param);    auto mySharedMultiParams = test::parameter_list(test::args(1, 2), test::args(3, 4));    auto mySharedParametersWithExtraParams = test::parameter_list(mySharedParameters, more arguments);    test::parameterized_test([](std::string message) {            CAPTURE(message); // if desired            CHECK(message.size() > 0);        }, mySharedParametersWithExtraParams,        my extra parameter, test::args(I can explicitly wrap as args too));    test::parameterized_test([](int a, int b) {            a = a + 1;            CHECK(a == b);        }, mySharedMultiParams);}I haven't tried using a SECTION within a parameterized_test lambda, but it has a good chance of working.
Value parameterized tests for Catch
c++;template meta programming;c++17